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

时间:2010-12-29 08:55:03

标签: c# sockets

我有一个从套接字读取的简单程序。通常它运作良好。但有时接收读取已经读取的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);
            }
        }
    }

1 个答案:

答案 0 :(得分:3)

嗯,你的代码中有一个错误,首先是:

    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,甚至可能记录已读取的数据。