使用 TCP 发送/接收时 C# 流乱序

标签 c# .net networking tcp

我在创建一个小型客户端/服务器应用程序时遇到了一些似乎在 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 指出了正确的解决方案。 Zone Alarm 弄乱了流(或者可能是数据包)。我要卸载这个软件。

最佳答案

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

我试图重现您的问题,但我做不到。我不确定 clientSocketState 指的是什么,所以我为缓冲区使用了一个常规字节数组。我懒洋洋地使用 Accept 而不是 BeginAccept,但没有进行其他更改。

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

更新:综合考虑,我开始相信某些防火墙或防病毒软件正在为您搞砸事情。

关于使用 TCP 发送/接收时 C# 流乱序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5705774/

相关文章:

c# - 从 CreatedUser 事件中取消 CreateUserWizard

c# - 在 C# 和 .Net 中强制执行父子关系

c# - 不调用 Thread.Join() 的后果

python - 如何使用IPy确定IP地址是否在白名单中?

c# - ASP.NEt MVC 使用 Web API 返回 Razor View

c# - 使用 linq 将多个求和为一种匿名类型?

c# - 通过局域网将 Android 应用程序连接到 PC 应用程序

networking - 如何使用 Wireshark 从 TCP 数据包中提取原始数据

c# - 将 Java 日期字符串转换为 C# 日期时间

c# - 如何读取在 C# 中打开的文件?