异步套接字 - c#中与永久套接字的双工通信

时间:2014-09-23 20:08:22

标签: c# .net sockets asynchronous duplex

我试图进行异步套接字通信,并希望服务器保留所有连接套接字的列表,这样他就可以向它们广播消息。

首先,我从msdn Asynchronous Socket Server中取了一些例子并对它们进行了一些修改,以免它们关闭套接字。 (刚删除.shutdown和.Close命令)

但这样做似乎会导致客户端挂在"接收部分"。

以下是我对msdn示例所做的更改:

客户端:

只更改了ReceiveCallback(),因此它保持在无限的接收循环中:

private static void ReceiveCallback(IAsyncResult ar)
{
    try
    {
        // Retrieve the state object and the client socket 
        // from the asynchronous state object.
        StateObject state = (StateObject)ar.AsyncState;
        Socket client = state.workSocket;

        // Read data from the remote device.
        int bytesRead = client.EndReceive(ar);

        if (bytesRead > 0)
        {
            // There might be more data, so store the data received so far.
            state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));

            // Get the rest of the data.
            client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReceiveCallback), state);
        }
        else
        {
            // All the data has arrived; put it in response.
            if (state.sb.Length > 1)
            {
                response = state.sb.ToString();
                Console.WriteLine(state.sb.ToString());
            }
            // Signal that all bytes have been received.
            receiveDone.Set();

            // Get the rest of the data.
            client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReceiveCallback), state);
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.ToString());
    }
}

服务器: 刚刚注释掉关闭套接字的行:

//handler.Shutdown(SocketShutdown.Both);
//handler.Close();

后来我计划保留一个套接字列表,这样我就可以向他们发送消息了,但是这里已经失败了。

我非常了解任何提示,我也希望听到您对使用此天赋的服务器的意见,该服务器必须服务于最多100个客户端,这可能会在2秒内发送请求。 (通信应该是两种方式,以便客户端和服务器可以随时发送消息,而无需等待消息响应)。

谢谢你,晚上好 马丁

1 个答案:

答案 0 :(得分:1)

当套接字关闭时,EndReceive仅返回0。您的客户端永远不会设置receiveDone句柄,因为服务器永远不会关闭套接字。收到数据或终止连接时调用回调。

您需要检测消息的结束(例如您链接的示例)。 例如。 (您链接的代码的修改版本)

content = state.sb.ToString();
if (content.IndexOf("<EOF>") > -1) {
     // All the data has been read from the 
     // client. Display it on the console.
     Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
                 content.Length, content );
     // Echo the data back to the client.
     Send(handler, content);

     { // NEW 
         // Reset your state (persist any data that was from the next message?)      

         // Wait for the next message.
         handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, 
         new AsyncCallback(ReadCallback), state);
     }

 } else {
      // Not all data received. Get more.
      handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, 
      new AsyncCallback(ReadCallback), state);
}