C# TCP段消失

C# TCP段消失,c#,tcp,C#,Tcp,我遇到了一个谷歌似乎无法解决的问题。为了简单起见,我有一个用C#编写的客户端和一个用C编写的运行Linux的服务器。客户端在循环中调用Send(buffer)100次。问题是服务器只接收到十几个。如果我把足够大的睡眠放在一个循环中,一切都会好起来。缓冲区很小-大约30B。我读过关于Nagle算法和ACK延迟的文章,但它没有回答我的问题 for(int i = 0; i < 100; i++) { try

我遇到了一个谷歌似乎无法解决的问题。为了简单起见,我有一个用C#编写的客户端和一个用C编写的运行Linux的服务器。客户端在循环中调用Send(buffer)100次。问题是服务器只接收到十几个。如果我把足够大的睡眠放在一个循环中,一切都会好起来。缓冲区很小-大约30B。我读过关于Nagle算法和ACK延迟的文章,但它没有回答我的问题

          for(int i = 0; i < 100; i++)
          { 
            try
            {                  
                client.Send(oneBuffer, 0, oneBuffer.Length, SocketFlags.None)                    
            }
            catch (SocketException socE)
            {
                if ((socE.SocketErrorCode == SocketError.WouldBlock)
                  || (socE.SocketErrorCode == SocketError.NoBufferSpaceAvailable)
                  || (socE.SocketErrorCode == SocketError.IOPending))
                {
                   Console.WriteLine("Never happens :(");
                }
            }
            Thread.Sleep(100); //problem solver but why??

          }
for(int i=0;i<100;i++)
{ 
尝试
{                  
发送(oneBuffer,0,oneBuffer.Length,SocketFlags.None)
}
捕获(SocketException socE)
{
if((socE.SocketErrorCode==SocketError.WouldBlock)
||(socE.SocketErrorCode==SocketError.NoBufferSpaceAvailable)
||(socE.SocketErrorCode==SocketError.IOPending))
{
Console.WriteLine(“从未发生:(”);
}
}
Thread.Sleep(100);//问题解决者,但为什么??
}

在阻塞模式和非阻塞模式下,发送缓冲区似乎已满并拒绝数据,直到数据再次变为空。更妙的是,我从未收到任何异常!我希望某些异常会引发,但不会引发任何异常。:(有什么想法吗?提前Thnx。

我认为此问题是由于:

Nagle算法的设计目的是通过引起 套接字用于缓冲小数据包,然后合并并发送它们 特定情况下的一个数据包。TCP数据包由40个数据包组成 数据头字节数加上发送的数据。当小数据包 与TCP一起发送时,TCP标头产生的开销可以 成为网络流量的重要组成部分。在重载情况下 在网络中,这种开销导致的拥塞可能会导致 丢失数据报和重新传输,以及过度传播 拥塞导致的时间。Nagle算法禁止发送 当新的传出数据从用户(如果有)处到达时,新的TCP段 连接上先前传输的数据保持未确认状态

调用client.Send函数并不意味着将发送TCP段。 在您的情况下,由于缓冲区很小,naggle算法会将它们重新组合成较大的段。在服务器端检查收到的十几个缓冲区是否包含整个数据

当您添加Thread.Sleep(100)时,您将在服务器端收到100个数据包,因为nagle算法不会等待更多数据

如果应用程序中确实需要较短的延迟,可以显式禁用TcpClient的nagle算法:将属性设置为true。在代码开头添加此行:

client.NoDelay = true;

我认为这个问题是由于:

Nagle算法的设计目的是通过引起 套接字用于缓冲小数据包,然后合并并发送它们 特定情况下的一个数据包。TCP数据包由40个数据包组成 数据头字节数加上发送的数据。当小数据包 与TCP一起发送时,TCP标头产生的开销可以 成为网络流量的重要组成部分。在重载情况下 在网络中,这种开销导致的拥塞可能会导致 丢失数据报和重新传输,以及过度传播 拥塞导致的时间。Nagle算法禁止发送 当新的传出数据从用户(如果有)处到达时,新的TCP段 连接上先前传输的数据保持未确认状态

调用client.Send函数并不意味着将发送TCP段。 在您的情况下,由于缓冲区很小,naggle算法会将它们重新组合成较大的段。在服务器端检查收到的十几个缓冲区是否包含整个数据

当您添加Thread.Sleep(100)时,您将在服务器端收到100个数据包,因为nagle算法不会等待更多数据

如果应用程序中确实需要较短的延迟,可以显式禁用TcpClient的nagle算法:将属性设置为true。在代码开头添加此行:

client.NoDelay = true;

我认为这个问题是由于:

Nagle算法的设计目的是通过引起 套接字用于缓冲小数据包,然后合并并发送它们 特定情况下的一个数据包。TCP数据包由40个数据包组成 数据头字节数加上发送的数据。当小数据包 与TCP一起发送时,TCP标头产生的开销可以 成为网络流量的重要组成部分。在重载情况下 在网络中,这种开销导致的拥塞可能会导致 丢失数据报和重新传输,以及过度传播 拥塞导致的时间。Nagle算法禁止发送 当新的传出数据从用户(如果有)处到达时,新的TCP段 连接上先前传输的数据保持未确认状态

调用client.Send函数并不意味着将发送TCP段。 在您的情况下,由于缓冲区很小,naggle算法会将它们重新组合成较大的段。在服务器端检查收到的十几个缓冲区是否包含整个数据

当您添加Thread.Sleep(100)时,您将在服务器端收到100个数据包,因为nagle算法不会等待更多数据

如果应用程序中确实需要较短的延迟,可以显式禁用TcpClient的nagle算法:将属性设置为true。在代码开头添加此行:

client.NoDelay = true;

我认为这个问题是由于:

Nagle算法的设计目的是通过引起 套接字用于缓冲小数据包,然后合并并发送它们 特定情况下的一个数据包。TCP数据包由40个数据包组成 数据头字节数加上发送的数据。当小数据包