我没有在这里发布代码,因为我想先通过一个简单的例子来理解它,我希望这没问题。
假设有数据包A, B, C, D
和 E
在网络内发送(已建立连接)。
包A, B, C
使用 TCP 作为传输协议(protocol)和 D, E
使用UDP。
A: Has source-IP S1 , destination-IP D1 , source-port SP1 , destination-port DP1 , data: hello , seq number 100
B: Has source-IP S1 , destination-IP D1 , source-port SP1 , destination-port DP1 , data: myname , seq number 105
C: Has source-IP S9 , destination-IP D9 , source-port SP9 , destination-port DP9 , data: is , seq number 105
D: Has source-IP S3 , destination-IP D3 , source-port SP3 , destination-port DP3 , data: kath
E: Has source-IP S8 , destination-IP D3 , source-port SP8 , destination-port DP3 , data: elk
包A
和 B
将使用相同的 TCP 套接字(因为它们具有相同的源 ip、目标 ip、源端口、目标端口)。包
C
将为自己使用另一个 TCP 套接字,包
D
和 E
将使用相同的 UDP 套接字(因为它们具有相同的目标 ip 和目标端口)。为了让这个例子更简单,我们假设套接字接收缓冲区是空的,并且我们不知道套接字是否都在同一台计算机上。
现在,如果应用程序在接收第一个数据包的套接字上进行第一次读取访问,将读取什么数据?
例如,如果我们将 TCP 套接字用于数据包
A, B
,那么我们将得到:hellomyname
, 对?如果我们为数据包使用 UDP 套接字
D, E
, 我们应该得到 kathelk
.我希望我的例子有意义,这样是否正确?
最佳答案
这取决于应用程序何时尝试读取以及它尝试读取的套接字。它还取决于应用程序在尝试读取套接字时提供的缓冲区大小以及应用程序为读取操作指定的选项。
但一般来说:
对 TCP 套接字的读取将获得当前可在该 TCP 连接上读取的数据量,直至应用程序提供的缓冲区大小。如果没有数据可用,则操作将阻塞,直到至少有一个字节可用。
如果缓冲区大小足以容纳它,则对 UDP 套接字的读取操作将获得第一个未读数据报。如果此时没有可用的未读数据报,它将阻塞,直到收到至少一个数据报。
因此,如果在接收到第一个数据包之前发出 TCP 连接读取将阻塞,如果在第一个数据包之后发出“hello”,如果在第二个数据包之后发出“hello myname”,以此类推。
如果在接收到第四个数据包之前发出对 UDP 套接字的读取,则会阻塞,否则将获得“kath”数据报。
关于sockets - 这两个套接字如何正确读取(无代码)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65313031/