[ Team LiB ] Previous Section Next Section

Chapter 6

6.1

The array of integers is contained within a structure and C allows structures to be assigned across an equals sign.

6.2

If select tells us that the socket is writable, the socket send buffer has room for 8,192 bytes, but when we call write for this blocking socket with a buffer length of 8,193 bytes, write can block, waiting for room for the final byte. Read operations on a blocking socket will always return a short count if some data is available, but write operations on a blocking socket will block until all the data can be accepted by the kernel. Therefore, when using select to test for writability, we must set the socket to nonblocking to avoid blocking.

6.3

If both descriptors are readable, only the first test is performed, the test of the socket. But this does not break the client; it just makes it less efficient. That is, if select returns with both descriptors readable, the first if is true, causing a readline from the socket followed by an fputs to standard output. The next if is skipped (because of the else we prepended), but select is then called again and immediately finds standard input readable and returns immediately. The key concept here is that what clears the condition of "standard input being readable" is not select returning, but reading from the descriptor.

6.4

Use the getrlimit function to fetch the values for the RLIMIT_NOFILE resource and then call setrlimit to set the current soft limit (rlim_cur) to the hard limit (rlim_max). For example, under Solaris 2.5, the soft limit is 64 but any process can increase this to the default hard limit of 1,024.

getrlimit and setrlimit are not part of POSIX.1, but are required by Unix 98.

6.5

The server application continually sends data to the client, which the client TCP acknowledges and throws away.

6.6

shutdown with SHUT_WR or SHUT_RDWR always sends a FIN, while close sends a FIN only if the descriptor reference count is 1 when close is called.

6.7

6.7 read returns an error, and our Read wrapper function terminates the server. Servers must be more robust than this. Notice that we handle this condition in Figure 6.26, although even that code is inadequate. Consider what happens if connectivity is lost between the client and server and one of the server's responses eventually times out. The error returned could be ETIMEDOUT.

In general, a server should not abort for errors like these. It should log the error, close the socket, and continue servicing other clients. Realize that handling an error of this type by aborting is unacceptable in a server such as this one, where one process is handling all clients. But if the server was a child handling just one client, then having that one child abort would not affect the parent (which we assume handles all new connections and spawns the children), or any of the other children that are servicing other clients.


    [ Team LiB ] Previous Section Next Section