0
我試圖在多線程環境中創建異步套接字客戶端,但它無法正常工作。 下面的示例代碼, 如果我創建新的AsyncSocketClient並從多線程環境調用StartClent,它將只處理一個或兩個休息,它不處理。(我創建新的AsyncSocketClient與每個新的請求) 是因爲的靜態變量,在多線程環境中創建c#異步套接字客戶端
class AsyncSocketClient
{
private static AutoResetEvent sendDone =
new AutoResetEvent(false);
private static AutoResetEvent receiveDone =
new AutoResetEvent(false);
private static ManualResetEvent connectDone =
new ManualResetEvent(false);
static private String response = "";
public void StartClent()
{
Socket workSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// clientSock.ReceiveTimeout = 1;
try
{
workSocket.BeginConnect(new IPEndPoint(IPAddress.Loopback, 8080), new AsyncCallback(ConnectCallBack), workSocket);
connectDone.WaitOne();
Send(s.workSocket, "<EOF>");
sendDone.WaitOne();
Receive(workSocket);
receiveDone.WaitOne();
}
catch(Exception ex)
{
}
}
private void ConnectCallBack(IAsyncResult ar)
{
Socket workSocket = (Socket)ar.AsyncState;
workSocket.EndConnect(ar);
connectDone.Set();
}
private void Receive(Socket client)
{
StateObject state = new StateObject();
state.workSocket = client;
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallBack), state);
}
private void ReceiveCallBack(IAsyncResult ar)
{
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
int byteReceived= client.EndReceive(ar);
if (byteReceived > 0)
{
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, state.buffer.Length));
Array.Clear(state.buffer, 0, state.buffer.Length);
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallBack), state);
}
else
{
if (state.sb.Length > 1)
{
response = state.sb.ToString();
}
receiveDone.Set();
}
}
private void Send(Socket client,string data)
{
byte[] sendBufer = Encoding.ASCII.GetBytes(data);
client.BeginSend(sendBufer, 0, sendBufer.Length, 0, new AsyncCallback(BeginSendCallBack), client);
}
private void BeginSendCallBack(IAsyncResult ar)
{
Socket client = (Socket)ar.AsyncState;
int byteSent= client.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.", byteSent);
sendDone.Set();
}
}
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 30;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
}
您的服務器實際上並不是異步的,因爲您正在執行阻止在這些靜態事件的所有地方等待。是的,他們很可能是你的問題的一部分。除了在看起來不應該分享的情況之外,你不應該被阻擋在第一位。 – Servy 2014-10-28 17:10:55
@Servy這是根據MSDN。我們是否需要爲多線程環境中的每個請求創建一個新的套接字。 http://msdn.microsoft.com/en-us/library/bew39x2a(v=vs.110).aspx – user3597233 2014-10-28 17:20:27
@ user3597233該示例對每個請求都需要新的套接字是正確的。雖然示例使用異步調用,因爲它立即阻止它實質上是同步的。您應該將發送和接收移動到回調中,以便StartClient不會阻止。您可能想要在紙上畫出正在發生的事情以及您的期望。 UML序列圖可能會有所幫助。 – 2014-10-28 17:45:24