0

我正在学习客户端/服务器编程,并且正在制作一个异步客户端/服务器聊天应用程序。

我可以将客户端连接到服务器并发送一条消息,但是在将相同的消息(仅用于测试目的)发送回客户端时遇到问题。任何帮助表示赞赏...

客户代码

byte[] dataBuffer = new byte[10];
    public AsyncCallback callBack;
    public Socket clientSocket;
    IAsyncResult ar;
    Random rnd=new Random();

private void btnSend_Click(object sender, RoutedEventArgs e)
    {
        try
        {
            Object objData = txtMessage.Text;
            byte[] byData = Encoding.ASCII.GetBytes(objData.ToString());
            if (clientSocket != null)
            {
                clientSocket.Send(byData);
                lbxMessages.Items.Add(txtMessage.Text);
            }
            txtMessage.Text = "";
            btnSend.IsEnabled = false;
        }
        catch(SocketException se)
        {
            MessageBox.Show(se.Message);
        }
    }

//SocketPacket CLASS
    public class SocketPacket
    {
        public Socket thisSocket;
        public byte[] dataBuffer = new byte[10];//test no, prevous [1]
    }

//METHODS
    private void WaitForData()
    {
        try
        {
            if (callBack == null)
            {
                callBack = new AsyncCallback(OnDataReceived);
            }
            SocketPacket sckPack = new SocketPacket();
            sckPack.thisSocket = clientSocket;
            ar = clientSocket.BeginReceive(sckPack.dataBuffer, 0, sckPack.dataBuffer.Length, SocketFlags.None, callBack, sckPack);

        }
        catch(SocketException se)
        {
            MessageBox.Show(se.Message);
        }
    }

    public void OnDataReceived(IAsyncResult ar)
    {
        try
        {
            SocketPacket sckID = (SocketPacket)ar.AsyncState;
            int iRx = sckID.thisSocket.EndReceive(ar);
            char[] chars = new char[iRx + 1];
            Decoder d = Encoding.UTF8.GetDecoder();
            int charLen = d.GetChars(sckID.dataBuffer, 0, iRx, chars, 0);
            String szData = new String(chars);
            this.Dispatcher.Invoke((Action)(() =>
            {
                lbxMessages.Items.Add(txtMessage.Text + szData);
            }));
            WaitForData();
        }
        catch (ObjectDisposedException)
        {
            Debugger.Log(0, "1", "\n OnDataRecieved: Socket has been closed\n");
        }
        catch(SocketException se)
        {
            MessageBox.Show(se.Message);
        }
    }

服务器代码

private void OnClientConnect(IAsyncResult asyncResult)
    {
        try
        {
            workerSocket[clientCount] = listenSocket.EndAccept(asyncResult);
            WaitForData(workerSocket[clientCount]);
            ++clientCount;

            if (clientCount<4)//allow max 3 clients
            {

                String str = String.Format("Client # {0} connected", clientCount);                   

                this.Dispatcher.Invoke((Action)(() =>
                {
                    lbxMessages.Items.Add(str);
                    lblConnectionStatus.Content =clientCount + " Connected";
                }));

                listenSocket.BeginAccept(OnClientConnect, null);
            }
        }
        catch (ObjectDisposedException)
        {
            System.Diagnostics.Debugger.Log(0, "1", "\n OnClientConnection: Socket has been closed\n");
        }
        catch (SocketException se)
        {
            MessageBox.Show(se.Message);
        }
    }

public class SocketPacket
    {
        public Socket currentSocket;
        public byte[] dataBuffer = new byte[50];//allowing the 50 digist to be sent at once
    }

    private void WaitForData(Socket socket)
    {
        try
        {
            if (workerCallBack == null)
            {
                workerCallBack = OnDataReceived;
            }
            SocketPacket sckPack = new SocketPacket();
            sckPack.currentSocket = socket;
            socket.BeginReceive(sckPack.dataBuffer, 0, sckPack.dataBuffer.Length, SocketFlags.None, workerCallBack, sckPack);
        }
        catch(SocketException se)
        {
            MessageBox.Show(se.Message);
        }
    }

    public void OnDataReceived(IAsyncResult asyncResult)
    {
        try
        {
            SocketPacket socketData = (SocketPacket)asyncResult.AsyncState;
            int iRx = 0;
            iRx = socketData.currentSocket.EndReceive(asyncResult);
            char[] chars = new char[iRx];
            Decoder decoder = Encoding.UTF8.GetDecoder();
            int charLen = decoder.GetChars(socketData.dataBuffer, 0, iRx, chars, 0);
            String receivedData = new String(chars);

            this.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => lbxMessages.Items.Add(receivedData)));

            //Does not work - does not send same message back to client
            //byte[] byData = Encoding.ASCII.GetBytes(receivedData);
            //if (listenSocket != null)
            //{
            //    listenSocket.Send(byData);
            //}

            WaitForData(socketData.currentSocket);


        }
        catch (ObjectDisposedException)
        {
            System.Diagnostics.Debugger.Log(0, "1", "\n OnDataRecieved: Socket has been closed\n");
        }
        catch (SocketException se)
        {
            MessageBox.Show(se.Message);
        }
    }
4

1 回答 1

0

您应该使用相同的套接字来发送和接收数据。您在 socketData.currentSocket 上调用 EndReceive,因此您还应该调用 socketData.currentSocket.Send。

在服务器端有两个套接字。一个用于“收听”,您在其上调用accept。客户端连接后,accept 调用为该客户端连接创建一个套接字,然后您可以使用该套接字为该特定客户端发送和接收数据。

您不使用“侦听”套接字来发送/接收数据。它没有连接到特定的连接。它仅用作接受新客户端连接的一种方式。

请参阅http://msdn.microsoft.com/en-us/library/fx6588te.aspx

于 2013-04-13T07:49:45.330 回答