据我所知,这个问题的答案是“是”,但我想检查我的理解并希望获得更详细、更深入的理解。
呼叫 和 的呼叫是否send
以 1:1 的比例对应recv
?
换句话说,如果一个程序调用通过网络套接字将一些数据发送到另一个网络连接的程序,那么在连接的接收端send
是否会有且仅有 1 个调用?(假设缓冲区足够大。)recv
recv
我知道操作系统和其他网络硬件可能会对 IP 数据包进行分段。但是,我的理解是,接收端的操作系统将重新组合分段的数据包,然后通过 向客户端应用程序呈现重新组合的数据包recv
。
询问的原因是我想弄清楚在某些情况下是否需要多次调用才能获取通过其他机器上的recv
调用发送的所有数据。send
之所以需要这样做,显而易见的原因是 因为send
发送的数据量超过了 使用的缓冲区所能容纳的数据量recv
。但是,为了回答这个问题,我们假设 发送的最大数据量send
可以容纳 使用的缓冲区recv
。
对于数据报套接字(如 UDP)来说,答案大多是肯定的,而对于流套接字(如 TCP)来说,答案是否定的。错误地假设 TCP 中也存在发送和接收之间的 1:1 关系是一种非常常见的编程错误。流套接字的类似错误是假设发送将发送所有内容(检查返回值实际发送了多少),而接收将尝试读取给定大小的所有内容(检查返回值实际读取了多少)。
即使对于数据报套接字,答案也并非总是肯定的。与 TCP 相反,UDP 套接字不可靠,因此数据报可能会丢失(只有完整的数据报,而不是部分数据报)。这意味着由于数据包丢失,可能会发送而没有匹配的接收。