TcpClient 개체를 사용하여 파일을 전송하고 있습니다. 개체는 하나뿐입니다. 그래서 파일을 전송하는 동안이 객체를 잠그고 파일을 전송하여 다른 스레드가 TCPClient가 해제 될 때까지 기다렸습니다.C에서 병렬로 스레드 만들기 #
스레드가 단일 개체와 병렬로 작동하게하는 방법이 있습니까?
TcpClient 개체를 사용하여 파일을 전송하고 있습니다. 개체는 하나뿐입니다. 그래서 파일을 전송하는 동안이 객체를 잠그고 파일을 전송하여 다른 스레드가 TCPClient가 해제 될 때까지 기다렸습니다.C에서 병렬로 스레드 만들기 #
스레드가 단일 개체와 병렬로 작동하게하는 방법이 있습니까?
아니요, 각 스레드가 자체 연결을 사용하도록 설정하십시오. 좀
....
당신이 paeallel에서 사용하는 것처럼 느낄 것이다 NetworkStream.BeginWrite을 사용할 수 있습니다 ....
그러면 BeginWrite/BeginRead와 현재의 스레드를 해제에 물건을 할 것입니다 배경. BeginWrite로 여러 개의 쓰기를 대기열에 넣을 수 있습니다 (그리고 병렬 작업을 이해할 수 있습니다). 내부 소켓 버퍼가 파일을 보낼 때 가득 채울 수 있기 때문에 나는 그것을 권하고 싶지 않다.
언제든지 Socket으로 전환하고 SendFile 메서드를 사용할 수 있습니다.
여러 개의 TcpClient 또는 소켓이있는 경우 BeginWrite/BeginRead 메서드를 사용하여 각각에 대해 새 스레드를 만들 필요없이 모두 처리 할 수 있습니다.
다음은 서버에 연결하고 파일을 보내고 연결을 끊는 작은 예입니다. 그것은 열려있는 tcpclients의 양을 처리 할 수 있습니다. 그리고 당신이 보는대로, 내가 그 제조에 사용되는 다른 포트를 보낼 경우
/// <summary>
/// Thread safe queue of client ids
/// </summary>
internal class FileSender
{
/// <summary>
/// A write operation have completed
/// </summary>
/// <param name="ar"></param>
private void OnWriteCompleted(IAsyncResult ar)
{
// We passed the context to this method, cast it back
var context = (ClientContext) ar.AsyncState;
// end the write
context.TcpClient.GetStream().EndWrite(ar);
// we've completed.
if (context.BytesSent >= context.FileStream.Length)
{
// notify any listener
Completed(this, new CompletedEventArgs(context.RemoteEndPoint, context.FileStream.Name));
context.TcpClient.Close();
return;
}
// Send more data from the file to the server.
int bytesRead = context.FileStream.Read(context.Buffer, 0, context.Buffer.Length);
context.BytesSent += bytesRead;
context.TcpClient.GetStream().BeginWrite(context.Buffer, 0, bytesRead, OnWriteCompleted, context);
}
/// <summary>
/// Send a file
/// </summary>
/// <param name="endPoint"></param>
/// <param name="fullPath"></param>
public void SendFile(IPEndPoint endPoint, string fullPath)
{
// Open a stream to the file
var stream = new FileStream(fullPath, FileMode.Open, FileAccess.Read);
// Create a client and connect to remote end
var client = new TcpClient();
client.Connect(endPoint);
// Context is used to keep track of this client
var context = new ClientContext
{
Buffer = new byte[65535],
FileStream = stream,
TcpClient = client,
RemoteEndPoint = endPoint
};
// read from file stream
int bytesRead = stream.Read(context.Buffer, 0, context.Buffer.Length);
// and send the data to the server
context.BytesSent += bytesRead;
client.GetStream().BeginWrite(context.Buffer, 0, bytesRead, OnWriteCompleted, context);
}
/// <summary>
/// File transfer have been completed
/// </summary>
public event EventHandler<CompletedEventArgs> Completed = delegate { };
#region Nested type: ClientContext
/// <summary>
/// Used to keep track of all open connections
/// </summary>
private class ClientContext
{
/// <summary>
/// Gets or sets buffer used to send file
/// </summary>
public byte[] Buffer { get; set; }
/// <summary>
/// Gets or sets number of bytes sent.
/// </summary>
public int BytesSent { get; set; }
/// <summary>
/// Gets or sets file to send
/// </summary>
public FileStream FileStream { get; set; }
public IPEndPoint RemoteEndPoint { get; set; }
/// <summary>
/// Gets or sets client sending the file
/// </summary>
public TcpClient TcpClient { get; set; }
}
#endregion
}
internal class CompletedEventArgs : EventArgs
{
public CompletedEventArgs(IPEndPoint endPoint, string fullPath)
{
EndPoint = endPoint;
FullPath = fullPath;
}
public IPEndPoint EndPoint { get; private set; }
public string FullPath { get; private set; }
}
tcpclient.connect (REMOTEHOST, 포트) (이 닷넷 프레임 워크에서 백그라운드에서 이루어집니다) 어떤 스레드를 사용하지 않습니다 연결하면 같은 포트로 만들면서 오류 (연결을 거부 함)가 발생하고 동일한 객체가됩니다. – marshalprince
그러나 하나의 연결을 사용하는 경우 서버는 함께 속한 데이터를 어떻게 알 수 있습니까? –
내가하고있는 일은 연결을 만들기 위해 하나의 TCPClient를 사용하고 있으며 다른 TCPClient를 생성하고있는 파일을받는 중입니다.하지만 이제는 연결에 사용 된 첫 번째 노드를 잠글 필요가 있습니다. 하지만 중간에 다른 스레드 (데이터 용으로 새로운 TCPClient를 작성)로 데이터를 보내야하지만 연결 용으로 TCPClient가 이미 잠겨 있습니다. 그럼 어떻게 다른 파일을 보낼 수 있습니까 – marshalprince