C# 套接字开始接收异步回调问题

C# 套接字开始接收异步回调问题,c#,sockets,asynchronous,C#,Sockets,Asynchronous,我只是想用一个小小的内部套接字客户机/服务器做一个概念验证。我只是传递一个字符串,并将收到一个特定的字符串返回。e、 g.发送->UCME接收->ICU 在这方面,我一直在遵循MSDN示例,而同步客户端的工作方式与预期的一样。然而,我实际上想要的是异步客户机,而不是。它完成当前的ReceiveCallback,然后无限期挂起。我没有错,什么都没有。唯一的线索是我在F10退出后立即启动时看到以下消息 Step into: Stepping over non-user code 'System.Ne

我只是想用一个小小的内部套接字客户机/服务器做一个概念验证。我只是传递一个字符串,并将收到一个特定的字符串返回。e、 g.发送->UCME接收->ICU

在这方面,我一直在遵循MSDN示例,而同步客户端的工作方式与预期的一样。然而,我实际上想要的是异步客户机,而不是。它完成当前的ReceiveCallback,然后无限期挂起。我没有错,什么都没有。唯一的线索是我在F10退出后立即启动时看到以下消息

Step into: Stepping over non-user code 'System.Net.LazyAsyncResult.Complete'
Step into: Stepping over non-user code 'System.Threading.ExecutionContext.Run'
Step into: Stepping over non-user code 'System.Threading._IOCompletionCallback.PerformIOCompletionCallback'
有什么想法吗

private static void Receive(Socket client)
{
    try
    {
        // Create the state object.
        StateObject state = new StateObject();
        state.workSocket = client;

        // Begin receiving the data from the remote device.
        client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
            new AsyncCallback(ReceiveCallback), state);
    }
    catch (Exception e)
    {
        Console.WriteLine(e.ToString());
    }
}
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();
            }
            // Signal that all bytes have been received.
            receiveDone.Set();
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.ToString());
    }
}

public class StateObject

{
    // Client socket.
    public Socket workSocket = null;
    // Size of receive buffer.
    public const int BufferSize = 256;
    // Receive buffer.
    public byte[] buffer = new byte[BufferSize];
    // Received data string.
    public StringBuilder sb = new StringBuilder();
}

非常标准的错误,TCP是一个流。您将收到UCME的4个字节,再次调用BeginRead,这就是它的结束,因为客户端将不再发送。你必须知道你什么时候收到了全部信息。标准的方法是首先对字符串长度进行编码,这样您就可以准确地知道应该接收多少字节。非常标准的错误是完全可信的。全新的插座。因此,考虑到这一点,我认为实现这一点的另一种方法是拥有一个agreedclient/server EOT?你不能在上面的代码中看到它,但我正在这样做。它是私有静态字符串EOF=string.Format,char4;我这样使用->Sendclient,UCME+EOF;上面的代码从不检查你的EOT,所以看起来Hans的评论仍然有效,对吗?顺便说一句,约定的EOT可以用于小项目,但如果EOT在某一点上实际上是数据的一部分呢?如果您打算对此进行扩展,更好的方法是将消息长度编码为标准化头的一部分。我的项目中的头包含2个短字符,一个同步字,例如0xABCD和一个消息类型,1个int表示头的总长度为8字节。@MattDavis:我明白,我不想让它陷入太多代码的泥潭,特别是因为我从MSDN异步套接字示例中获取了绝大多数代码。所以,总的来说,如果我像你和汉斯·帕桑那样实现长度,我的ReceiveCallback会是什么样子?@HansPassant并不想暗示你的评论是无效的。如果是那样的话,我很抱歉。