Socket粘包处理

2019-01-22  本文已影响55人  passiony
/// <summary>
    /// 接收到消息
    /// </summary>
    void OnReceive(byte[] bytes, int length)
    {
        // 获得请求的字符串,写入到memStream的末端
        memStream.Seek(0, SeekOrigin.End);
        memStream.Write(bytes, 0, length);
        //重置为从menStreamd开头读取
        memStream.Seek(0, SeekOrigin.Begin);

        //int32占用4个字节,ushort占用2个字节
        int lengthCount = 4;
        while (RemainingBytes() > lengthCount)
        {
            //消息的前4个字节表示:字符流的真实长度
            int messageLen = reader.ReadInt32();
            if (RemainingBytes() >= messageLen)
            {
                MemoryStream ms = new MemoryStream();
                BinaryWriter writer = new BinaryWriter(ms);
                //从当前流中读取指定的字节数以写入字节数组中,并将当前位置前移相应的字节数
                writer.Write(reader.ReadBytes(messageLen));
                ms.Seek(0, SeekOrigin.Begin);

                //把消息存到memStream中,交给应用层
                OnReceivedMessage(ms);
            }else{
                //字符流长度不够,往后退两位到int前,跳出循环,等待下次读取
                memStream.Position = memStream.Position - lengthCount;
                break;
            }
        }

        //Create a new stream with any leftover bytes
        byte[] leftover = reader.ReadBytes((int)RemainingBytes());
        memStream.SetLength(0);     //Clear
        memStream.Write(leftover, 0, leftover.Length);
    }

    /// <summary>
    /// 剩余的字节
    /// </summary>
    private long RemainingBytes()
    {
        return memStream.Length - memStream.Position;
    }

上一篇 下一篇

猜你喜欢

热点阅读