4

着信接続を非同期でリッスンする TCP サーバーがあります。クライアントが 1 つだけ接続されていれば、すべて正常に動作します。ただし、2 つ以上の接続がある場合、サーバーは最初のメッセージを取得しません。ReceiveCallback 関数をデバッグすると、サーバーがデータではなくメッセージの長さを取得することがわかります。つまり、2 つのクライアントを接続して最初のメッセージ「hello」を送信しようとすると、サーバーは次のようになります。buffer= /0/0/0/0/0 なので何も表示されません。同じクライアントの 2 番目のメッセージで、サーバーはデータを取得します。

それは私のサーバーがどのように見えるかです:

        private void StartServer()
    {
        try
        {
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            serverSocket.Bind(new IPEndPoint(IPAddress.Any, 3333));
            serverSocket.Listen(100);
            serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);   

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }


     private void AcceptCallback(IAsyncResult ar)
    {
        try
        {
            Socket clientSocket = serverSocket.EndAccept(ar); 
            clientSocketList.Add(clientSocket);
            AppendToTextBox("ClientConnected");
            clientSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), clientSocket);
            serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }


        private void ReceiveCallback(IAsyncResult ar)
    {
        try
        {
            int received = 0;
            Socket current = (Socket)ar.AsyncState;
            received = current.EndReceive(ar);
            byte[] data = new byte[received];

            if (received == 0)
            {
                return;
            }

            Array.Copy(buffer, data, received);
            string text = Encoding.ASCII.GetString(data);

            AppendToTextBox(text);
            buffer = null;
            Array.Resize(ref buffer, current.ReceiveBufferSize);

            current.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), current);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
4

1 に答える 1

2

http://msdn.microsoft.com/en-us/library/dxkwh6zw.aspxの例を参照してください。

を呼び出すたびに新しいバッファが割り当てられるように、コードを変更しますBeginReceive

        Socket clientSocket = serverSocket.EndAccept(ar); 
        clientSocketList.Add(clientSocket);
        AppendToTextBox("ClientConnected");
        var buffer = new byte[BUFFER_LENGTH];  // <---
        clientSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), clientSocket);
        serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);

クライアントごとに 1 つのバッファーが必要です。そうしないと、一方のクライアントが他方のクライアントが使用するバッファを上書きする可能性があります。

于 2013-04-03T22:36:21.053 に答える