我有一个小测试程序,在客户端 - >服务器 - >客户端(ping/pong测试)之间发送大量的udp数据包.每次运行时数据包都是固定大小的(最后一次运行是udp数据包的最大允许大小)我正在用随机数据填充数据包,除了包含数据包编号的每个数据包的开头.所以我只想知道我是否收到客户端的所有数据包.
我正在使用sendto()和recvfrom(),我只读取sizeof(packet_number)(在本例中是一个int).其他数据会发生什么变化?它最终是在仙境中(被丢弃)吗?或者到达的新数据包是否附加到此"旧"数据?
(使用linux)
无论您的用户区缓冲区大小是多少,每次从UDP套接字读取都会将一个完整的数据报从内核套接字接收缓冲区中取出.那是:
如果您的缓冲区大于下一个待处理数据报,则读取的缓冲区大小将小于缓冲区大小.
如果您的缓冲区较小,您将读取您的缓冲区大小值,其余数据将被丢弃.
您可以在中设置MSG_TRUNC
选项flags
,因此recv(2)
将返回整个数据报长度,而不仅仅是您读入userland缓冲区的部分.
希望这可以帮助.
要回答您的第一个问题,数据是否会被丢弃? 是的,它确实.当您的数据包大于Path MTU时,IP和ARP协议将发挥作用.路径MTU是客户端和服务器之间路径的最大传输单位.假设您的NIC卡是标准以太网卡,那么您的最大MTU为1500.现在,假设您的客户端和服务器之间的整个路径MTU是1500.在这种情况下,如果您发送任何大于1472字节的数据包(1500 - (20字节ip标头) - (8字节UDP标头))然后将发生IP分段.然后会发生的是IP层将数据包切成片段以满足以太网链路的MTU.现在,在发送任何数据之前,需要解析目标的MAC地址.所以突然之间,ARP协议将接收多个IP片段,请求相同的IP到MAC地址解析.然后会发生什么是ARP将为第一个收到的数据包发起ARP请求并等待ARP响应.在等待时,ARP将丢弃所有发出相同ARP请求的片段,并仅排队最新到达的片段.因此,如果您发送的数据包大于1472字节,如果您的ARP缓存为空,请不要期望在另一端收到整个数据包.
新到的数据包是否附加到 No,它不会被追加.UDP是具有严格消息边界的数据报协议.因此,每个到达的数据包被认为是一个完整的自包含数据报; 数据不会被追加.