Socket.Send 是不是有可能阻塞代码并永远完成?

Posted

技术标签:

【中文标题】Socket.Send 是不是有可能阻塞代码并永远完成?【英文标题】:Is it possible that Socket.Send block the code and take forever to finish?Socket.Send 是否有可能阻塞代码并永远完成? 【发布时间】:2014-05-15 08:15:46 【问题描述】:

我得到了这个 Socket.Send 代码,我的协议是 tcp。

byte[] commandBytes = Encoding.ASCII.GetBytes(command);
int iBytesSent = socket.Send(commandBytes, commandBytes.Length, SocketFlags.None);
Debug.WriteLine("SEND: " + command);

我有超过 10,000 个命令要发送,每个命令大约 100 个字符。 我在 foreach 循环中调用 Socket.Send 来处理 10,000 个命令。

我通知 Socket.Send 代码阻塞了当前线程并且需要永远完成。 (debug.WriteLine 停止打印到输出控制台。)

所以我的问题:

是否有可能是因为我发送命令太快而导致流已满?

所以它必须等到流可用并继续发送?

我还通知说有片刻 Socket.Send 阻塞代码 5-10 秒,然后继续。 但随着时间的推移,5-10 秒变成了 20-30 秒,然后就一直持续下去。

【问题讨论】:

【参考方案1】:

是的,Send 可以阻止,尽管在大多数代码中你很少看到它。如果不想占用线程,可以使用异步套接字 IO(BeginSend/EndSendSendAsync)。然而,这并没有让它变得更快——它只是意味着当套接字忙时你没有阻塞线程。您是否可能超过了此连接的另一端?

【讨论】:

我不控制此连接的另一端。下单端为金融报价数据提供商IQFeed。我的应用程序只是向 IQFeed 发送命令并接收报价。我的问题与大数据有关。例如我可以接收数亿条记录,有时我必须发送超过 20,000 条或命令。 @VuNguyen 这并不意味着您需要一次发送所有内容 - 这样做也没有好处。你说你也收到了:也许将待处理请求的数量限制在一个合理的数字 - 这样你就不会超过另一端。 @VuNguyen 或者,如前所述:使用异步 IO;然后它会自动退出 我试过这个:发送命令后,我调用 Thread.Sleep(1000) 直到现在(约 30 分钟)它仍然有效,这意味着线程/连接/套接字有 1 秒处理事情。不知道取什么名字(Thread/Connection/Socket)? @VuNguyen 再次;不是它没有发送:而是它不完整。这里的根本问题是远程服务器太慢了。这里的套接字从根本上没有任何问题 - 我的套接字保持打开数天,不断发送。问题几乎可以肯定是您连接到的服务没有处理积压。如果远程端点拒绝接受新数据包,并且您的缓冲区已满,那么您需要等待

以上是关于Socket.Send 是不是有可能阻塞代码并永远完成?的主要内容,如果未能解决你的问题,请参考以下文章

如果一个 I/O 函数不能因 EINTR 而失败,这是不是意味着它永远不会阻塞?

如何测试调用socket.send时是不是引发异常[重复]

boost async_write() 和 non_blocking socket.send() 之间的区别

apue 第14章 高级I/O

iPhone3GS 是不是支持阻塞队列?

Java并发-取消与关闭