【问题标题】:C# TCP Client error processing async messageC# TCP 客户端错误处理异步消息
【发布时间】:2012-05-16 20:22:36
【问题描述】:

我在使用 TCP Client 时遇到了一些问题,该服务连接到服务器并侦听消息,这些消息在 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);
        }

【问题讨论】:

    标签: c# asynchronous tcpclient tcplistener


    【解决方案1】:

    您不能假设从 TCP 服务器一次读取即可获得整个“消息”。这通常是你做整个标题的原因。

    标头应该是 4 个字节长,并告诉您后面要跟多少个字节。所以你需要做的是:

    1. 异步读取,直到有 4 个字节
    2. 继续异步读取,直到您在标头中接收到的字节数与您被告知要接收的字节数一样多

    你正在做的是:

    1. 假设您一次获得 4 个字节,如果没有则失败(问题:您不能假设一次接收获得 4 个字节)
    2. 尽可能多地接收字节,如果没有获得足够的字节则失败(再次遇到问题:不能确保一次接收所有字节)

    我还可以从您的代码中看出您已经开始异步接收。为什么拿到header之后又切换到同步接收呢?

    【讨论】:

    • 是的,我更改了它,以便获得标题,虽然我没有收到总数,但我一直在尝试!。感谢您的提示。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-06
    • 2012-03-24
    • 2016-05-24
    • 2015-11-05
    • 2019-09-09
    • 2020-03-29
    • 2012-08-27
    相关资源
    最近更新 更多