繁体   English   中英

TCP程序包大于MTU时C#Socket.Receive()发生故障

[英]C# Socket.Receive() malfunctions when TCP package is larger than MTU

我正在使用C#套接字类通过短连接向/从我们的服务器发送/接收TCP消息。 伪代码(排除一些错误容忍的逻辑使其清晰可见)如下。

class MyTCPClient {
    private Socket mSocket;

    MyTCPClient() {
        mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    }

    void Connect(ipEndpoint, sendTimeOut, receiveTimeOut) {
        mSocket.Connect(ipEndpoint);
        mSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, sendTimeOut);
        mSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, receiveTimeOut);
    }

    void Send(msg) {
        mSocket.Send(msg);
    }

    void Receive(data) {
        ByteStreamWriter bsw = new ByteStreamWriter();
        int totalLen = 0;
        while (true) {
            byte[] temp = new byte[1024];
            int len = mSocket.Receive(temp, SocketFlags.None);
            System.Threading.Thread.Sleep(50);  // This is the weirdest part
            if (len <= 0) break;
            totalLen += len;
            bsw.WriteBytes(temp);
        }
        byte[] buff = bsw.GetBuffer();
        data = new byte[totalLen];
        Array.Copy(buff, 0, data, 0, totalLen);
    }

    ~MyTCPClient() {
        mSocket.Close();
    }
}

我使用该类通过短连接多次从我们的服务器请求相同的消息,并且发生了以下事情(仅当消息大小大于一个MTU-1500字节时)。

  1. 如果将“ Sleep(50)”注释掉,则大多数情况下(90%)我收到了错误的“数据”,特别是说“ totalLen”是正确的,但“ data”是错误的。
  2. 如果将“ Sleep(50)”替换为“ Sleep(10)”,则大约有一半的时间我收到了错误的“数据”,并且“ totalLen”也总是正确的。
  3. 如果我使用“ Sleep(50)”,有时会收到错误的“数据”。

我可以保证,每次我们的服务器发送正确的数据,并且客户端也在TCP层收到正确的数据(我使用WireShark通过我使用的端口监视所有消息)。 有谁可以帮助回答为什么我的C#代码无法获取正确的数据?

另外,如果我使用mSocket.Available而不是Socket.Receive()的返回值来判断while循环,我将始终获得正确的数据和数据长度...

写入之前,请勿将temp截断为len个字节。 len in temp之后的所有字节尚未用当前数据填充,因此包含无意义的过时日期。

复制到另一个流时,可以使用stream.Write(temp, 0, len)

暂无
暂无

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

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