Why UDP maximum segment size is far greater than TCP maximum segment size in this output?
I tried the following code to find out maximum segment size in TCP and UDP sockets. I might be wrong because I am us开发者_如何学Cing IPPROTO_TCP
and TCP_MAXSEG
for SOCK_DGRAM
but I'm getting a value and I want to know the reason.
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);
output:
tcp max segment size is=536
then I tried then same with an UDP socket:
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);
output:
udp max segment size is=134514139
TCP has segments, UDP has datagrams. UDP datagram length is limited by the size of the UDP datagram length header field (it's 16 bits).
From wikipedia:
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).
check the return value of getsockopt
, UDP doesn't have tcp segments so it should definitely return with an error.
I am sure getsockopt
actually fails (and returns a non-zero status you are ignoring) so you are printing garbage (it's likely you didn't initialize optval
).
EDIT
UDP
doesn't have a MSS. The maximum size of a datagram is limited by many factors (how wiling is the OS to send a big datagram). The hard limit is the size IP can carry. IP
has 16b Total Length
field. So I'm guessing if the OS lets you, 65535 - iphdr
is the maximum size of a datagram.
There is no such thing as the 'maximum segment size of UDP', because UDP doesn't have segments or MSS. The maximum possible UDP datagram payload size is 65535-28=65507 as per yi_H's answer. In practice it is further limited by the NIC's MTU and by the intermediate routers, in exactly the same way that TCP's MSS is, however it is not negotiated across the length of the path like a TCP MSS is; it is therefore not known by the UDP stack; it is therefore not available to you via any API.
I think the UDP value that you got is because you're using level and options, which do not apply to UDP BUT to TCP. You need to use getsockopt as following
getsockopt(sockfd, SOL_SOCKET, SO_MAX_MSG_SIZE, (char *)&optval, &aopt);
check this Microsoft page about the function
精彩评论