.NET运行时中的Tcp缓冲破坏

5 .net c# sockets tcp

这是我前一段时间遗弃的一个老问题,因为我没有解决方案,它只影响了一台服务器(所以我只是将我的服务放在其他地方). 用户遇到与我相同症状的问题:

  • C#.net同步Tcp服务器
  • 通过使用AcceptTcpClient方法阻塞TcpListener来分配TcpClient对象
  • 一旦有了一个TcpClient对象,我将它传递给一个线程,该线程调用客户端的GetStream方法来创建一个NetworkStream
  • 这个NetworkStream循环,在每次迭代中执行networkStream.Read(someBuffer,0,4096)
  • 现在客户端和服务器位于同一网络上,没有拥塞可言
  • 我的服务器有足够的内存空间
  • 如果我将服务器软件加载到另一台机器上,问题就会消失
  • 踢球者:来自网络Linux盒子的流量可以准时到达

tcpClient.AcceptTcpClient()方法一次阻塞大约一分钟,导致服务器不久之后必须读取一大块字节,而不是它应该做的事情.它应该像发送它们一样频繁地执行networkStream.Read()小块字节(并且客户端每隔5秒发送一次,而不是每分钟发送一次).

之前对其他用户的评论表明,低负荷网络或连接问题可能是罪魁祸首,这一点似乎是合理的.但事实并非如此.

我更进了一步,在客户端和服务器上安装了数据包分析器.结果:

  • 客户端发送一个它出现在服务器分析器上的瞬间
  • 网络延迟或连接不是问题
  • 数据包/帧在正确的时间到达服务器
  • 在我的分析仪正在监视的网络接口卡和我的应用程序之间的某处导致这种延迟
  • .NET运行时是我的应用程序和网络接口之间唯一的东西
  • .NET中的某种套接字错误是造成这种巨大延迟的原因

环境:

  • 在我的具体情况下,我使用的是英特尔PRO/1000 MT网卡和.NET
  • 标准版Server 2003 R2,SP2
  • 已安装.NET框架:2.0 SP2,3.0 SP2,3.5 SP1,4客户端配置文件,4扩展

如果有人有任何建议,我非常想知道它是什么.

Ben*_*Ben 1

这可能是由于以下原因之一造成的。

  • 最有可能的是:硬件 TCP 卸载。

据观察,该型号的网卡在其他情况下存在 TCP 卸载问题。您可以在设备驱动程序配置中禁用此功能。

如果这是分段卸载处理的问题,那么您可能会发现它只发生在某些网络路由上,这可以解释您观察到的 Linux 客户端和 Windows 客户端之间的差异。

示例:http://forums.novell.com/novell-product-support-forums/netware/nw-other/communications/187741-offload-tcp-segmentation-intel-pro-1000-mt.html

  • 不太可能:路径 MTU 问题。

路径 MTU 应该是自动发现的,但如果干预路由器丢弃所有 ICMP 流量(包括“需要分段”),那么您可能会看到挂起的连接。在您的情况下,连接最终会成功,所以我认为这不是您的问题,但值得检查。(如果需要,您还可以减少 MTU 并更改 MTU 发现算法,但您可能应该不理会它,除非这是您的问题并且您无法修复路由器。)

  • 可能性较小:尝试建立 IPSec 连接失败。

如果 Windows 计算机位于域中,则它可能会尝试建立 IPSec 关系,但失败。这将取决于客户端和服务器的配置。通常这会很快失败,但如果您阻止某些 IPSec 流量,您可能会看到它缓慢失败。在网络分析器中查找 IKE 和 IPSec 流量。