无法使用异步服务器套接字处理多条消息

时间:2018-01-15 12:59:56

标签: c# sockets asynchronous

我有一个异步服务器套接字(基于找到的MSDN示例here),这对1条消息很有用。我目前正在接收39个字节的数据,这是第一个消息,它工作得很好。但是服务器套接字无法接收消息2和3.这是我的代码

private void PrivateStartListening()
    {
        try
        {
            var socket = ManagementSocket.Socket;
            var localEndPoint = ManagementSocket.GetEndPoint();
            socket.Bind(localEndPoint);
            socket.Listen(100);
            Msg.Debug("Listening...");
            while (true)
            {
                // Set the event to nonsignaled state.  
                AllDone.Reset();

                socket.BeginAccept(
                    AcceptCallback,
                    socket);

                // Wait until a connection is made before continuing.  
                AllDone.WaitOne();
            }

        }
        catch (Exception e)
        {
            Msg.Debug(e.ToString());
        }

        Msg.Debug("read completed");

    }

    private void AcceptCallback(IAsyncResult Ar)
    {
        // Signal the main thread to continue.  
        AllDone.Set();

        // Get the socket that handles the client request.  
        var listener = (Socket)Ar.AsyncState;
        var handler = listener.EndAccept(Ar);

        // Create the state object.  
        var state = new StateObject { WorkSocket = handler };
        handler.BeginReceive(state.Buffer, 0, StateObject.BUFFER_SIZE, 0,
            ReadCallback, state);

    }

    private void ReadCallback(IAsyncResult Ar)
    {
        // Retrieve the state object and the handler socket  
        // from the asynchronous state object.  
        var state = (StateObject)Ar.AsyncState;
        var handler = state.WorkSocket;

        // Read data from the client socket.   
        var bytesRead = handler.EndReceive(Ar);

        if (bytesRead > 0)
        {
            handler.BeginReceive(state.Buffer, 0, StateObject.BUFFER_SIZE, 0,
                ReadCallback, state);
        }

        // There  might be more data, so store the data received so far.  
        state.Sb.Append(Encoding.ASCII.GetString(
            state.Buffer, 0, bytesRead));

        // Check for end-of-file tag. If it is not there, read   
        // more data.  
        var content = state.Sb.ToString();

        // All the data has been read from the   
        // client. Display it on the console.  
        Msg.Debug($"Read {content.Length} bytes from socket. \n Data : {content}");
        var fields = content.TrimEnd('\r', '\n').Split(',').ToList();
        if (fields[1] == "0")
        {
            handler.BeginReceive(state.Buffer, 0, StateObject.BUFFER_SIZE, 0,
                ReadCallback, state);
        }
        var paymentDetails = ProcessPaymentResponse(fields);
        if (paymentDetails != null)
        {
            ResponseQueue.Enqueue(paymentDetails);
            ResponseResetSignal.Set();
        }

        // Echo the data back to the client.  
        //Send(handler, content);

    }


    private static void Send(Socket Handler, string Data)
    {
        // Convert the string data to byte data using ASCII encoding.  
        var byteData = Encoding.ASCII.GetBytes(Data);

        // Begin sending the data to the remote device.  
        Handler.BeginSend(byteData, 0, byteData.Length, 0,
            SendCallback, Handler);
    }

    private static void SendCallback(IAsyncResult Ar)
    {
        try
        {
            // Retrieve the socket from the state object.  
            var handler = (Socket)Ar.AsyncState;

            // Complete sending the data to the remote device.  
            var bytesSent = handler.EndSend(Ar);
            Msg.Debug($"Sent {bytesSent} bytes to client.");

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

        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }`

我还附上了wireshark看到的屏幕截图(因此发送了多条消息)Messages being recieved by wireshark but not asny server socket

我的问题是,为什么我能成功收到第一条消息,而不是紧跟在/

之后的消息

我花了整个上午仔细阅读档案,但我仍然没有更聪明。如果它看起来像一个重复的问题,我会道歉。之前的答案都没有对我有用。任何帮助或提示将不胜感激。

1 个答案:

答案 0 :(得分:0)

您的ReadCallback()仅读取可用数据的第一部分,然后退出。因此,跳转到ReadCallback()的唯一方法是建立另一个连接:listener - > AcceptCallback - > ReadCallback

因此,只是尝试将ReadCallback修改为基于循环的版本,该版本等待新数据,直到套接字被交易对手关闭(或者触发另一个事件来停止循环,假设用户决定)。