Socket 发送与 sendasync。发送实际上什么时候会阻塞?

问题描述 投票:0回答:2

 阅读 MSDN 页面,很明显,如果套接字传输层中没有内部缓冲区,则 Send 将阻塞。这实际上是一件好事,因为我不想出现 NoBufferSpaceAvailable 错误。我的理解是传输缓冲区空间相当大,但如果发送限制以防止这些错误,我很高兴。

但是,尚不清楚还有什么会导致 Send 阻塞。我的猜测是,它不会阻塞等待发送的确认,并且 Send 只会将数据排队到传输缓冲区并返回。

如果发送确实阻塞,直到特定套接字实际上完全阻塞直到传输完成,那将是一件非常糟糕的事情。如果是这种情况,那么 1000 个慢速连接中就有一个可能会减慢整个发送过程。在这种情况下,SendAsync 确实是强制性的。

有人有更详细的资料吗?

.net sockets asyncsocket
2个回答
5
投票

正如 EJP 所说,发送缓冲区负责处理任何未确认的数据,也就是说,您发送的任何数据都将保留在缓冲区中,直到被接收方确认为止。这是为了在数据包的 ACK 从未到达的情况下允许稍后重新发送数据。

此外,正如 EJP 所说,每当收到 ACK 时,刚刚 ACK 的数据就会从发送缓冲区中删除,并释放空间,以便您可以将其用于进一步的发送。

但是,在发送大量数据的情况下,并且 ACK 回来很慢(由于高延迟、嘈杂的连接或只是一路上断开连接),那么发送缓冲区将被填满,最终会导致由于缺少发送缓冲区空间而导致发送阻塞。

因此,未确认的数据本身不会直接导致发送阻塞,但如果您发送大量数据并且存在网络问题,这意味着 ACK 不会返回给您,那么是的...未确认的数据将最终导致发送阻塞。这是正确的行为。

您不会希望在没有收到 ACK 的情况下一直发送数据。如果您确实想要这样,那么您可能会使用 UDP 而不是 TCP :)

编辑:此外,每个连接使用一个线程的情况并不少见,以避免您提到的特定情况,即一个坏连接可能会影响一千个连接。如果您担心扩展,那么无论如何您可能应该使用异步调用。


5
投票

TCP 发送不会阻塞等待接收该发送的 ACK。这就是缓冲的目的。发送被缓冲,并且仅在缓冲区已满时阻塞。同时,TCP 异步地将缓冲区的内容发送到对等方,并在收到 ACK 后将其丢弃。

© www.soinside.com 2019 - 2024. All rights reserved.