我尝试使用以下代码来查找TCP和UDP套接字中的最大段大小。我可能错了,因为我正在使用IPPROTO_TCP
和TCP_MAXSEG
作为SOCK_DGRAM
,但我得到了一个值,我想知道原因。
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
perror("cant create socket");
aopt = sizeof(optval);
getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, (char *)&optval, &aopt);
printf("tcp max segment size is=%d\n", optval);
输出:
tcp max segment size is=536
然后我尝试使用UDP套接字:
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
perror("cant create socket");
aopt = sizeof(optval);
getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, (char *)&optval, &aopt);
printf("udp max segment size is=%d\n", optval);
输出:
udp max segment size is=134514139
答案 0 :(得分:3)
TCP有段,UDP有数据报。 UDP数据报长度受UDP数据报长度头字段的大小限制(它是16位)。
来自维基百科:
A field that specifies the length in bytes of the entire datagram: header and data.
The minimum length is 8 bytes since that's the length of the header.
The field size sets a theoretical limit of 65,535 bytes
(8 byte header + 65,527 bytes of data) for a UDP datagram.
The practical limit for the data length which is imposed by the underlying
IPv4 protocol is 65,507 bytes (65,535 − 8 byte UDP header − 20 byte IP header).
检查getsockopt
的返回值,UDP没有tcp段,所以肯定会返回错误。
答案 1 :(得分:2)
我确信getsockopt
实际上失败了(并返回你忽略的非零状态),所以你打印垃圾(可能你没有初始化optval
)。
UDP
没有MSS。数据报的最大大小受到许多因素的限制(操作系统如何发送大数据报)。硬限制是IP可以承载的大小。 IP
有16b Total Length
字段。所以我猜测操作系统是否允许你,65535 - iphdr
是数据报的最大大小。
答案 2 :(得分:2)
没有“UDP的最大段大小”这样的东西,因为UDP没有段或MSS。根据yi_H的答案,最大可能的UDP数据报有效载荷大小为65535-28 = 65507。在实践中,它进一步受到NIC的MTU和中间路由器的限制,其方式与TCP的MSS完全相同,但它在路径的长度上不协商,就像TCP MSS一样;因此,UDP堆栈不知道它;因此,您无法通过任何API使用它。
答案 3 :(得分:0)
我认为您获得的UDP值是因为您使用的是 level 和选项,它们不适用于TCP的UDP BUT 。您需要按以下方式使用getsockopt
$data = Model::whereRaw(<condition 1>);
$data_cloned = $data->replicate();
$data1 = $data->whereRaw(<condition 2>);
$data2 = $data_cloned->whereRaw(<condition 3>);
return $data1->toSql();