next up previous
Next: Code Up: Computer Networks/Computer Networks and Previous: Grading

Subsections

Lecture Notes

Notes (4-up) Notes (1-up) Relevant textbook material
A crash course in C++ A crash course in C++  
Multi-file programs1 Multi-file programs1  
The client-server model The client-server model Chapter 2
Concurrency Concurrency Chapter 3
Application program interfaces APIs Chapter 4, Chapter 5, part of Chapter 6
Client design Client Chapter 6 (the TCP part)
Server design2 Server design2 Chapters 8 (the TCP part) and 13; critical regions
Multithreaded servers3 Multithreaded servers3 Chapter 12
Multiservice servers Multiservice servers Chapter 15
Managing concurrency Managing concurrency Chapter 16
Practical issues Practical issues Sections 30.1 to 30.23
Logging and debugging Logging and debugging The remainder of Chapter 30, extra
Deadlock and starvation Deadlock and starvation Chapter 31
Secure programming4 Secure programming4 Based on the Secure programs howto
The User Datagram Protocol UDP Sections 6.18 to 6.24, 8.19, 8.22, 8.27, 8.28
The Internet Protocol5 IP5 RFC 791, routing algorithms extra
A short primer to socket programming on other platforms Other platforms  

Note: Reusing a Socket

When you use the close command to close a socket your program tells the system that it is done with using the respective socket. The socket is however not deallocated, and even the port binding created by your program is still in place. Since nobody is using it, the port binding will eventually time out (according to the TCP timeout value, typically of the order of minutes) and die, but you get in the meantime slapped with an ``port already in use'' error if you want to bind another socket to the same port. This could become a serious nuisance when one uses thread preallocation, and especially when this is combined with dynamic reconfiguration.

This kind of behaviour occurs when the client does not shut down the socket. Indeed, the TCP stack on the server side assumes that communication will come from the client in the future unless the client has sent an end of file. But then the end of file is sent only upon shoudown. One solution is thus to convince one's clients to be well-behaved, but this is no real solution from the server's programmer point of view (typically the server's programmer has no control over the clients).

I could find no server-side solution to convince a socket to just die for good (should anybody know one, I would be very interested to hear about it). So I will present here the next best thing, a workaround. The workaround consists in convincing your socket to tell bind to reuse the initially provided address. You can do this by modifying the properties of the socket as follows (with sd the descriptor of your master socket):

    int reuse = 1;
    setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));

This must be done after creating the socket and before binding it. See the manual page of socket in Section 7 for details on this and other options, and of course the manual page for setsockopt.

Finally, it is worth pointing out that when a client dies in an uncivilized manner the server receives a SIGPIPE signal from its TCP stack. This may be be used as well in the context of this problem (though I don't really know how).

This discussion has been enhanced as the result of a dialogue with Lauren del Giudice. Lauren also points out to this explanation of what happens when the socket closes.

Recommended Readings

You have done and still do assignments (and will write the exam too). Hopefully, all of these will help you understand the concepts presented during the lectures. However, it is also a good idea to read the examples presented in the textbook for a supplementary (and some times alternative) view of the domain, as follows:

Chapter 7
deals with client design (both TCP and UDP). You will not necessarily be able to use those clients (most ECHO ports are actually closed), but they do make good simple examples.
Chapters 10 and 11
deal with TCP server design (iterative and concurrent, respectively).
Section 13.5
presents an implementation that simulates concurrency in a single thread of execution. It is similar in spirit with the implementation you have seen in the lab, but does not allocate memory dynamically, and uses select instead of poll. You may find it more palatable.
Section 15.9
presents a sample super server, worth a look.
Chapters 7, 9, 14, and 15
present UDP clients and servers. I strongly advise at least a quick look at them.



Footnotes

... programs1
More information on the matter of programming with multiple modules can be found on the Web here (continued in the next section; previous section also worth a look). See the reference material for more details on makefiles.
... design2
The code for critical regions discussed in these slides is here.
... servers3
The code for critical regions discussed in these slides is here.
... programming4
Exploiting buffer oferflows is explained in details in the classic ``Smashing the Stack for Fun and Profit.'' A couple of examples are from this paper on race conditions
... Protocol5
Dijkstra's algorithm (the non-distributed variant) is discussed in a bit more details in this set of slides.

next up previous
Next: Code Up: Computer Networks/Computer Networks and Previous: Grading
Stefan Bruda 2012-04-28