Start with Figure and modify it to call sleep(5) after the peer's protocol address is printed, and to also print the number of bytes returned by read each time read returns a positive value.
Start with Figure and modify it to call write for each byte of the result that is sent to the client. (We discussed similar modifications in the solution to Exercise 1.5.) Run the client and server on the same host using TCP. How many bytes are read by the client?
Run the client and server on the same host using a Unix domain socket. Does anything change?
Now call send instead of write in the server and specify the MSG_EOR flag. (You need a Berkeley-derived implementation to finish this exercise.) Run the client and server on the same host using a Unix domain socket. Does anything change?
Write a program to determine the values shown in Figure. One approach is to create a stream pipe and then fork into a parent and child. The parent enters a for loop, incrementing the backlog from 0 through 14. Each time through the loop, the parent first writes the value of the backlog to the stream pipe. The child reads this value, creates a listening socket bound to the loopback address, and sets the backlog to that value. The child then writes to the stream pipe, just to tell the parent it is ready. The parent then attempts as many connections as possible, detecting when it has hit the backlog limit because the connect blocks. The parent may use an alarm set at two seconds to detect the blocking connect. The child never calls accept to let the kernel queue the connections from the parent. When the parent's alarm expires, it knows from the loop counter which connect hit the backlog limit. The parent then closes its sockets and writes the next new backlog value to the stream pipe for the child. When the child reads this next value, it closes its listening socket and creates a new listening socket, starting the procedure again.