tcp通讯,为啥执行AcceptTcpClient()的时候没有响应呢? C#

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了tcp通讯,为啥执行AcceptTcpClient()的时候没有响应呢? C#相关的知识,希望对你有一定的参考价值。

刚学习tcp通讯,但下面的代码老是没有响应,为什么? TcpListener tcplistener = new TcpListener(IPAddress.Parse( "127.0.0.1 "),13); tcplistener.Start(); byte[] btServerReceive = new byte[256]; string strServerReceive = string.Empty; while (true) TcpClient tcp = tcplistener.AcceptTcpClient(); NetworkStream ns = tcp.GetStream(); int intReceiveLength = ns.Read(btServerReceive, 0, btServerReceive.Length); strServerReceive = UnicodeEncoding.Unicode.GetString(btServerReceive, 0, intReceiveLength); txtServerResult.AppendText( "ServerReceive: " + strServerReceive + " "); ns.Write(btServerReceive, 0, btServerReceive.Length); txtServerResult.AppendText( "ServerSend: " + strServerReceive + " "); tcp.Close(); 建议先查查MSDN AcceptTcpClient()是一直阻塞的 直到有客户端执行Connect 你单单执行这一块代码 到AcceptTcpClient()没有响应才是最正常的了

参考技术A 要等client发消息过来了才有响应,所以最好放在一个线程里

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

【中文标题】.NET 运行时中的 Tcp 缓冲损坏【英文标题】:Tcp buffering breakage in .NET runtime 【发布时间】: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 位。是的,我将在与嗅探器一起工作的服务器上运行我的项目。 【参考方案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 流量。

【讨论】:

已解决,点赞。这就是问题所在。谢谢一百万,我自己永远不会得出这个结论。 实际上,还有一个简单的问题。硬件 TCP 卸载是否会发生,然后迅速消失?我有这个问题三天,第三天一切恢复正常。没有更新,同样的软件。硬件 TCP 卸载问题会永远存在还是会悄悄消失?

以上是关于tcp通讯,为啥执行AcceptTcpClient()的时候没有响应呢? C#的主要内容,如果未能解决你的问题,请参考以下文章

为啥两台主机通讯时需要三个唯一的地址:mac、IP、端口?请说明理由,并对每个地址的作用进行说明。

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

为啥TCP段最大是65535字节,怎么计算的

Socket为啥要翻译成套接字?

TCP为啥需要3次握手与4次挥手

MQTT协议和TCP协议有啥区别?为啥人们推荐MQTT协议?