|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|
|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|
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
to reuse the initially provided address. You can do this by
modifying the properties of the socket as follows (with
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
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.
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:
poll. You may find it more palatable.