Chapter 8
8.1 | Yes, read returns 4,096 bytes of data, but the recvfrom returns 2,048 (the first of the two datagrams). A recvfrom on a datagram socket never returns more than one datagram, regardless of how much the application asks for. |
8.2 | If the protocol uses variable-length socket address structures, clilen could be too large. We will see in Chapter 15 that this is acceptable with Unix domain socket address structures, but the correct way to code the function is to use the actual length returned by recvfrom as the length for sendto. |
8.4 | Running ping like this is an easy way to see ICMP messages that are received by the host on which ping is being run. We reduce the number of packets sent from the normal one per second just to reduce the output. If we run our UDP client on our host aix, specifying the server's IP address as 192.168.42.1, and also run the ping program, we get the following output:
|
8.5 | It probably has a socket receive buffer size, but data is never accepted for a listening TCP socket. Most implementations do not preallocate memory for socket send buffers or socket receive buffers. The socket buffer sizes specified with the SO_SNDBUF and SO_RCVBUF socket options are just upper limits for that socket. |
8.6 | We run the sock program on the multihomed host freebsd, specifying the -u option (use UDP) and the -l option (specifying the local IP address and port).
The local IP address is the Internet-side interface in Figure 1.16, but the datagram must go out the other interface to get to the destination. Watching the network with tcpdump shows that the source IP address is the one that was bound by the client, not the outgoing interface address.
|
8.7 | Putting a printf in the client should introduce a delay between each datagram, allowing the server to receive more datagrams. Putting a printf in the server should cause the server to lose more datagrams. |
8.8 | The largest IPv4 datagram is 65,535 bytes, limited by the 16-bit total length field in Figure A.1. The IP header requires 20 bytes and the UDP header requires 8 bytes, leaving a maximum of 65,507 bytes for user data. With IPv6 without jumbogram support, the size of the IPv6 header is 40 bytes, leaving a maximum of 65,487 bytes for user data. Exercise 7.1). But if we set the client's socket buffer sizes as shown in Figure E.9 and run the client program, nothing is returned by the server. We can verify that the client's datagram is sent to the server by running tcpdump, but if we put a printf in the server, its call to recvfrom does not return the datagram. The problem is that the server's UDP socket receive buffer is smaller than the datagram we are sending, so the datagram is discarded and not delivered to the socket. On a FreeBSD system, we can verify this by running netstat -s and looking at the "dropped due to full socket buffers" counter before and after our big datagram is received. The final solution is to modify the server, setting its socket send and receive buffer sizes. Figure E.9 Writing the maximum-sized UDP/IPv4 datagram.udpcliserv/dgclibig.c
On most networks, a 65,535-byte IP datagram is fragmented. Recall from Section 2.11 that an IP layer must support a reassembly buffer size of only 576 bytes. Therefore, you may encounter hosts that will not receive the maximum-sized datagrams sent in this exercise. Also, many Berkeley-derived implementations, including 4.4BSD-Lite2, have a sign bug that prevents UDP from accepting a datagram larger than 32,767 bytes (line 95 of p.770 of TCPv2). |