繁体   English   中英

奇怪/严重的套接字收到C#中的错误

[英]Strange/Severe Socket receive Bug in C#

我有一个从套接字读取的简单程序。 通常情况下,它运作良好。 但有时接收正在读取已读取的2个字节。 消息的结构是1个字节的标头,3个字节的msgLength,msgLength字节,msg和字节尾部。 我用WireShark记录了流量,看起来还不错。

出现此问题如下:

packet X = ........ endOfPreviousMessage, trailer byte, header byte, first byte of msgLength
packet X+1 = 2 bytes the rest of the msgLength

它正确读取了msgLength (值为253)。再次读取了53! 和消息。 当然,这会导致消息解析器出现问题。

编码:

Socket CAMListenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
CAMListenSocket.Bind(new IPEndPoint(IPAddress.Any,CAMListenPort));
CAMListenSocket.Listen(10);

CAMSocket = CAMListenSocket.Accept();


    internal void CAMSocketReceive()
    {
        byte[] hdrBuffer = new byte[4];
        while (Active)
        {
            try
            {
                int read = CAMSocket.Receive(hdrBuffer,4,SocketFlags.None); //Reading the first 4 bytes
                if (read == 0)
                {
                    Logger.Warn(" disconnecting");
                    Active = false;
                    break;
                }
                int msgLength = Utils.BytesToInt(hdrBuffer, 1, 3); //Convert to int, skipping the first byte (which is the SOH)
                if (hdrBuffer[0] != 1)
                {
                    Logger.Warn("CAMSocketReceive::  Out of sync first byte is not SOH !! Handling recovery " );
                    //handleRecovery();
                }
                msgLength = msgLength + 1;//Add the trailer
                byte[] rawMsg = new byte[msgLength]; //Prepare a buffer to hold the CAM msg                                        
                read = 0;
                do
                {
                    read+= CAMSocket.Receive(rawMsg, read, msgLength - read, SocketFlags.None); //Read MSG_LENGTH bytes.                                                                        
                } while (read < msgLength);

                CAMMessage cam = new CAMMessage(rawMsg); //parse the message
                CAMQueue.Add(cam); //Add to the CAM queue
            }
            catch (Exception ex)
            {
                Logger.Error("Error while reading from CAM socket: ", ex);
            }
        }
    }

好吧,这里的代码中有一个错误,首先:

    int read = CAMSocket.Receive(hdrBuffer,4,SocketFlags.None);
    if (read == 0)
    {
        Logger.Warn(" disconnecting");
        Active = false;
        break;
    }
    int msgLength = Utils.BytesToInt(hdrBuffer, 1, 3);

如果read是1、2或3怎么办? 您可能没有读完所有4个字节。 这不太可能,但有可能。 如果消息的长度与上一条消息的长度相同,那么您将确切看到所描述的行为。 (最好对每组标头字节使用一个新的字节数组,这样就不会再使用“旧”数据了,这可能会引起混乱。)

非常怀疑这是.NET套接字实现中的错误。

为了进行诊断,您始终可以记录每次对Read调用的返回值,甚至可能记录已读取的数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM