Assignment 4

This is an individual assignment. Each of you have to submit both hard copy and electronic copy of your assignment. The hard copy must have a cover sheet. Students are encouraged to discuss the problems in the assignment together, but you are not allowed to show your answers to the other students.
  1. In the 3-way handshaking stage of a TCP connection setup, will the server send the acknowledgement to the client before the server calls accept?
    Hint: You can modify the daytime server so that the server sleeps for a sufficiently long period of time before calling accept, and then observe the result. Section 15.6 might also be helpful to understand this problem.

  2. Describe the procedure to accomplish a non-blocking connect operation. Explain briefly why such a non-blocking connection operation is necessary.
    Hint: Read Section 15.3-4, you are strongly recommended to type the code in Figure 15.11 into your computer, and integrate the code into your daytime client.

  3. When a socket is in the TIME_WAIT state, the port number can not be reused except that the SO_REUSEADDR option is set. Answer the following questions:
    1. Explain why this is a problem for server programs instead of client programs? In other words, why generally you have to wait for 2*MSL to restart the server, while you can restart the client immediately.
    2. Suppose the server host has two IP addresses: IP1 and IP2, whether can the server program bind one linstening socket to the address IP1:port bind another linstening socket to address IP2:port.
      ? Explain your reason. Hint: read the following man pages: man 2 bind and man 7 socket.

  4. The following pseudo code for a server program:
    listensock = socket (...);
    bind (listensock, ...);
    listen (listensock);
    flags = fcntl (listensock, F_GETFL, 0);
    fcntl (listensock, F_SETFL, flags | O_NONBLOCK);
    for (i = 0; i < MAXCLIENTS; i++) 
        clients[i] = -1;
    
    while (1) {
        datasock = accept (listensock, ...);
        if (datasock != -1) {
            for (i = 0; i < MAXCLIENTS; i++) 
                if (clients[i] == -1) {
                    clients[i] = datasock;
                    break;
                }
            if (i == MAXCLIENTS)
                close (datasock);   // too many clients
        }
        else if (errno != E_WOULDBLOCK && errno != EINTR)
            // process some real error, may terminate the server
        }
        
        for (i = 0; i < MAXCLIENTS; i++)
            if (clients[i] != -1) {
                n = read (clients[i], buf, ...);
                if (n > 0) {
                    // process the request in buf, and send back the response
                }
                else if (n == 0) {
                    close (clients[i]);
                    clients[i] = -1;
                }
                else if (errno != E_WOULDBLOCK && errno != EINTR)
                    // process some real error, may terminate the server
                }
            }
    }
    
    Read the code and answer the following questions:
    1. Why is the data socket not set the non-blocking mode in the program. Hint: read the man page: man 7 socket.
    2. What's the logic inside the if statement for checking the value of errno.
    3. You can also use the select to implement the same server behavior, which implement is more efficient?

  5. Explain in which situation the realsize and size may not be equal after read/write and read returns. You can assume the socket is a blocking socket.
        // size is the size of the expected request
        realsize = read (datasock, request, size); 
    
        // size is the size of the response
        realsize = write (datasock, response, size);
    

Note:
Hosted by www.Geocities.ws

1