【发布时间】:2012-02-18 04:08:42
【问题描述】:
这是我不久前放弃的一个老问题,因为我无法解决任何问题,而且它只影响了一台服务器(所以我只是将我的服务放在其他地方)。 This 用户遇到了与我的症状相同的问题:
- C# .net 同步 Tcp 服务器
- 通过使用 AcceptTcpClient 方法阻塞 TcpListener 来分配 TcpClient 对象
- 一旦有了 TcpClient 对象,我就将它传递给调用客户端的 GetStream 方法以创建 NetworkStream 的线程
- 此 NetworkStream 循环,在每次迭代中执行 networkStream.Read(someBuffer, 0, 4096)
- 现在客户端和服务器位于同一个网络上,没有拥塞可言
- 我的服务器有足够的可用内存
- 如果我将服务器软件加载到另一台机器上,问题就会消失
- 踢球者:来自网络 Linux 机器的流量可以按时顺利通过
tcpClient.AcceptTcpClient() 方法一次阻塞大约一分钟,导致服务器不得不在不久之后读取一个巨大的字节块,而不是它应该做的事情。它应该像发送一样频繁地执行 networkStream.Read() 小字节块(并且客户端每 5 秒发送一次,而不是每分钟一次)。
以前的 cmets 向其他用户建议,可能是因为网络或连接问题低于标准,这乍一看似乎是合理的。但事实并非如此。
我更进一步,在客户端和服务器上都安装了数据包分析器。结果:
- 即时客户端发送一个它显示在服务器的分析器上
- 网络延迟或连接不是问题
- 数据包/帧在正确的时间到达服务器
- 在我的分析仪正在监控的网络接口卡和我的应用程序之间的某处导致此延迟
- .NET 运行时是我的应用程序和网络接口之间唯一的东西
- .NET 中的某种套接字错误是造成这种巨大延迟的原因
环境:
- 在我的具体情况下,我使用的是 Intel PRO/1000 MT 网卡和 .NET
- 标准版服务器 2003 R2,SP2
- .NET Framework 已安装:2.0 SP2、3.0 SP2、3.5 SP1、4 客户端配置文件、4 扩展
如果有人有任何建议,我非常想知道它是什么。
【问题讨论】:
-
你是如何处理并发请求的?即您是否为每个客户端生成一个线程,或者其他什么? ,并且在发生这种情况时,调试当时连接了多少并发客户端可能会有所帮助(以确保您没有达到几个死/坏客户端挂起的限制,它可能只需要有人做端口扫描以在您的应用中触发大量线程)
-
@nos 有一个入口点,并且为唯一的客户端分配了自己唯一的 TcpClient 对象,该对象拥有自己的线程来处理 NetworkStream.Read() 的传入内容。所以是的,每个客户端 1 个线程,在可预见的未来很少有客户端使用该服务。在测试中,只有 1 个客户端连接。
-
除了操作系统堆栈和您的应用程序之间的问题之外,我唯一能想到的就是通过网络发送的数据包标头中的某些内容。更具体地说,对于失败的情况,可能没有在 TCP 标头中设置 PSH 位。您可以尝试在一台正常工作的服务器上运行数据包嗅探。然后比较两者,看看有没有区别。
-
这听起来像是一个连接问题,使用您当前的代码,它将阻止其他连接,直到该 1 连接成功。您应该尝试使用 BeginAcceptTcpClient 异步接受客户端。
-
@High 现在,在测试中,只有一个客户端,因此侦听器上阻塞 AcceptTcpClient 的竞争为零,我的嗅探器也指示在标头中设置了 PSH 位。是的,我将在与嗅探器一起工作的服务器上运行我的项目。