我真的不太了解套接字,除了如何读取和写入它们就好像它们是文件一样。我对使用套接字选择器知之甚少。我不明白你为什么要冲洗插座,实际发生了什么?这些位只是挂在内存中的某个地方,直到它们被推掉?我在网上读了一些关于套接字的东西,但它都是非常抽象和高级的。
这里到底发生了什么?
答案 0 :(得分:48)
写入网络套接字和发送数据涉及一定的开销。如果每次进入套接字时都发送数据,那么对于实际数据的每个字节,最终会有40多个字节的TCP头。 (假设您正在使用TCP套接字。其他套接字将具有不同的值)。为了避免这种低效率,套接字维护一个本地缓冲区,通常有一些超过1000字节。填充该缓冲区时,会在数据周围包裹一个标头,并将数据包发送到目的地。
在许多情况下,您不需要立即发送每个数据包;如果您正在传输文件,如果没有文件的最终数据,早期数据可能没有任何用处,因此这很有效。但是,如果您需要强制立即发送数据,则刷新缓冲区将发送尚未发送的任何数据。
请注意,当您关闭套接字时,它会自动刷新任何重新生成的数据,因此在关闭之前无需刷新。
答案 1 :(得分:10)
你真的无法冲洗插座。
(来自How can I force a socket to send the data in its buffer?)
你不能强迫它。期。 TCP在何时确定自己的想法 可以发送数据。现在,通常在TCP套接字上调用write()时,
TCP确实会发送一个段,但是没有保证也没办法 迫使这个。 TCP不会发送的原因有很多 segment:一个关闭的窗口和Nagle算法是两件事 马上就会想到。
阅读完整的帖子,这是非常深入的,并为我澄清了很多东西。
答案 2 :(得分:2)
Nagle的算法经常在套接字上使用。简而言之,它会等待发送非常重要的数据。问题是在传输延迟和发送数据包的开销成本之间取得平衡。
数据有效负载越大,浪费的带宽越小,因为标头(大部分)固定大小。此外,中间系统通常具有基于分组速率而不是整体数据速率的性能限制。
答案 3 :(得分:1)
我没有使用flush进行套接字编程。我确实记得有些模式你可以设置,其中面向流的发送尝试减少发送的小数据包的数量。但是,您将使用sendall()来确保缓冲区中的所有内容都已发送。
shutdown()函数非常有用,因为你正在进行假脱机。当然,如果你不想让东西闲逛,你必须使用close()调用。
有关详细信息,请查看Beej's guide。