【问题标题】:C# stream out of order when using TCP send/receive使用 TCP 发送/接收时 C# 流乱序
【发布时间】:2025-12-07 03:20:06
【问题描述】:

我在创建一个小型客户端/服务器应用程序时遇到了一些似乎在 TCP 流中混淆的东西,因此我编写了一个小型测试应用程序

服务器只是创建一个 TCP 套接字并发送一个递增计数器

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

Socket clientSocket = socket.Accept();

byte test = 0;
while (true)
{
    if (clientSocket.Send(new byte[] { test }, 0, 1, SocketFlags.None) == 1)
    {
        test++;
    }
}

由于这是一个 TCP 流,我希望客户端的流从 0 变为 255 等等。

在客户端使用以下内容:

IPEndPoint ipEndPoint = new IPEndPoint(System.Net.IPAddress.Parse("127.0.0.1"), 7777);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(ipEndPoint);

byte[] buffer = new byte[20000];
byte last = 255;
while (true)
{
    int bytesRead = socket.Receive(buffer);

    for (int i = 0; i < bytesRead; i++)
    {
        if (buffer[i] != (byte)(last+1))
        {
            //problem here
        }
        last = buffer[i];
    }
}

if 条件永远不应该返回 true,但它确实如此。在我分析客户端的流之后,它显示缓冲区通常包含像 000 001 002 003 004 005 006 102 103 104 105 这样的序列。

我在这里缺少什么?我一直认为 TCP 会确保在 TCP 级别按顺序交付。

更新:Thorarin 指出了正确的解决方案。区域警报正在搞乱流(或者可能是数据包)。我要卸载这个软件。

【问题讨论】:

  • 数字是否总是随着间隔而增加,或者它们实际上是乱序的?是否有可能某些数据包在该循环中的某处超时,而您只是从流中提取某些数据包?
  • 数字在增加,但差距很大。没有抛出异常,我希望 .net 处理数据包 (IP) 级别。使用 Wireshark 可以发现,间隙总是在数据包的末尾。但是 TCP 不应该确保数据的传递吗?我还不确定是否有数据丢失或顺序错误。
  • 您如何检查 Wireshark?我的印象是 Wireshark 无法捕获环回接口。
  • @Thorarin 您可以使用内部 IP (192.168.1.112) 并添加路由以通过网关(您的路由器)将所有内容路由到该 IP。是的,这有点愚蠢,但是您的 NIC 上有流量,Wireshark 可以捕获它。

标签: c# .net networking tcp


【解决方案1】:

TCP does guarantee 在订单交付中。我的猜测是你的接收缓冲区出了问题。也许您连接了两次并使用相同的缓冲区?

我已尝试重现您的问题,但无法重现。我不确定clientSocketState 指的是什么,所以我使用了一个常规字节数组作为缓冲区。我懒得用Accept代替BeginAccept,但没有做其他更改。

一定是发生了一些你没有告诉我们的事情:-)

更新:考虑到一切,我开始相信某些防火墙或防病毒软件正在给你带来麻烦。

【讨论】:

  • 抱歉给您带来了困惑。我正在试验它是否与同步/异步有关,并在发布代码时进行了一些混淆。我清理了它并编辑了我的问题。只有一个连接和一个缓冲区。
  • @Peter:我已经修改了我的代码以反映您的更新,但错误仍然没有出现在这里,我也想不出它会在不同系统上发生的合理原因。某种防火墙/防病毒软件搞砸了?
  • 啊,我怎么没想到 :) 你是对的。事实证明,ZoneAlarm 正在搞乱数据包!我不确定为什么会发生这种情况,但可以肯定的是我现在要卸载这个软件。谢谢 :)