首页 文章

C#TCP客户端错误处理异步消息

提问于
浏览
0

我在TCP客户端遇到一些问题,该服务连接到服务器并侦听消息,这些消息在90%的时间内被接收和处理 . 经过一些调试后,我发现在某些情况下我得到“无法读取整个数据包!”错误 . (代码中)

我无法控制服务器发送的内容 . 我的想法是它没有收到完整的消息(我认为它在较长的消息上失败但由于卷不确定) .

我可以解释这个问题的最佳方式是什么?或者其他任何提示 . 我有接收方法,下面是所有操作和问题 .

对不起,这是我第一次使用TCP,所以不要害怕

public void Receive(IAsyncResult ar)
        {
            if (ar != null)
            {
                try
                {

                    byte[] mLenBytes = (byte[])ar.AsyncState;
                    byte[] mDataBytes = null;
                    int bytes_read = mTcpClient.Client.EndReceive(ar);
                    if (bytes_read != 4)
                        throw new Exception("Unable to read whole header!");
                    int len = mLenBytes[3] + ((mLenBytes[2] + (mLenBytes[1] + (mLenBytes[0] << 8)) << 8) << 8);
                    mDataBytes = new byte[len];
                    bytes_read = mTcpClient.Client.Receive(mDataBytes, len, SocketFlags.None);
                    if (bytes_read != len)
                        throw new Exception("Unable to read whole packet of data!" + "Expected " + len + " Got "  + Convert.ToString(bytes_read) + "\r\n" + (System.Text.Encoding.ASCII.GetString(mDataBytes)));
                        //This is the error that is raised!. 

                    // raise an event
                    PhoneBoxEventArgs e1 = new PhoneBoxEventArgs(System.Text.Encoding.UTF8.GetString(mDataBytes));
                    Console.WriteLine("Data received is = " + e1.Data);
                    OnPassEvent(e1);

                }
                catch (Exception ex)
                {

                }

            }
            byte[] mLenBytes_new = new byte[4];
            mTcpClient.Client.BeginReceive(mLenBytes_new, 0, 4, SocketFlags.None, new AsyncCallback(Receive), mLenBytes_new);
        }

1 回答

  • 3

    您不能假设从TCP服务器读取一个完整的“消息” . 这通常是你做整个 Headers 的原因 .

    Headers 应该是4个字节长并告诉你,要遵循多少字节 . 所以你需要做的是:

    • 异步读取,直到有4个字节

    • 保持异步读取,直到你有多少字节被告知要在 Headers 中接收

    你在做的是:

    • 假设你一次得到4个字节,如果你没有得到失败(问题:你不能假设你在一个接收中得到4个字节)

    • 尽可能多地接收字节,如果没有得到足够的字节就会失败(再次出现问题:你不能确保一次接收所有字节)

    我也可以从你的代码中看出你已经开始异步接收了 . 为什么在获得 Headers 后切换到同步接收?

相关问题