T
Thomas Hawkins
Perhaps someone with a better understanding of TCP/IP will be able to
explain this. I have a small client-server application that works in
the following way:
An instance of a Runnable class called Server is created and started
as a thread. In this thread a ServerSocket is created, which blocks on
accept(). When the ServerSocket receives a connection, the resulting
Socket is handed to the constructor of another Runnable object called
ServerConnection. The ServerConnections starts itself as a thread and
handles the Socket from that point on. Once a new ServerConnection has
been created, the ServerSocket returns to blocking on accept(). The
lifetime of a ServerConnection is indefinite and can be terminated by
either the client or the server. Upon termination, the IO Streams and
Sockets are closed at both ends and the threads expire. The admin can
stop the Server by issuing a command that calls close() on the
ServerSocket. Once the closing Server thread has reported that it has
expired gracefully, the admin can restart the server by issuing a
command that creates a new instance of the Server thread. This all
appears to work as expected.
Now for the part I don't understand:
1. The Server is started: netstat indicates a socket LISTENING on the
designated port.
2. A connection is received: netstat indicates an additional socket on
that port in an ESTABLISHED state.
3. The Server is stopped: netstat indicates no change, but the
Server's final message states that the ServerSocket is now closed and
unbound.
4. A new Server is started: netstat indicates *another* socket
LISTENING on the same port. No BindException occurs. The new Server
reports that its ServerSocket is open, bound and listening.
5. At this point one of two things can happen. Either the new
ServerSocket will accept connections exactly as the first did, or
clients attempting to connect to the designated port will get a
"ConnectException: Connection refused", as if no server was there. The
connection that was spawned from the first ServerSocket continues to
work normally. If the second ServerSocket is not working, it will only
start working once this first connection is terminated. Terminating
the first connection causes the first ServerSocket to disappear from
netstat.
Can anyone explain what is going on here? It seems that the open
connection prevents the descriptor for the first ServerSocket from
disappearing from netstat, even though the ServerSocket no longer
exists as far as Java is concerned. So maybe the fact that clients
cannot connect to the new Server is due to their packets being routed
to the disappeared ServerSocket, even though there is another
ServerSocket that's actually bound to the port. The really perplexing
factor is the inconsistency of the behaviour.
I guess the obvious solution is to prevent the Server from shutting
down while there are still Sockets open. I can't think of another
server application that doesn't do this. For various reasons it would
be desirable in this case if one could restart the server without
closing existing connections. Is this impossible?
Any thoughts, theories or explanations would be appreciated.
Thanks
Tom
explain this. I have a small client-server application that works in
the following way:
An instance of a Runnable class called Server is created and started
as a thread. In this thread a ServerSocket is created, which blocks on
accept(). When the ServerSocket receives a connection, the resulting
Socket is handed to the constructor of another Runnable object called
ServerConnection. The ServerConnections starts itself as a thread and
handles the Socket from that point on. Once a new ServerConnection has
been created, the ServerSocket returns to blocking on accept(). The
lifetime of a ServerConnection is indefinite and can be terminated by
either the client or the server. Upon termination, the IO Streams and
Sockets are closed at both ends and the threads expire. The admin can
stop the Server by issuing a command that calls close() on the
ServerSocket. Once the closing Server thread has reported that it has
expired gracefully, the admin can restart the server by issuing a
command that creates a new instance of the Server thread. This all
appears to work as expected.
Now for the part I don't understand:
1. The Server is started: netstat indicates a socket LISTENING on the
designated port.
2. A connection is received: netstat indicates an additional socket on
that port in an ESTABLISHED state.
3. The Server is stopped: netstat indicates no change, but the
Server's final message states that the ServerSocket is now closed and
unbound.
4. A new Server is started: netstat indicates *another* socket
LISTENING on the same port. No BindException occurs. The new Server
reports that its ServerSocket is open, bound and listening.
5. At this point one of two things can happen. Either the new
ServerSocket will accept connections exactly as the first did, or
clients attempting to connect to the designated port will get a
"ConnectException: Connection refused", as if no server was there. The
connection that was spawned from the first ServerSocket continues to
work normally. If the second ServerSocket is not working, it will only
start working once this first connection is terminated. Terminating
the first connection causes the first ServerSocket to disappear from
netstat.
Can anyone explain what is going on here? It seems that the open
connection prevents the descriptor for the first ServerSocket from
disappearing from netstat, even though the ServerSocket no longer
exists as far as Java is concerned. So maybe the fact that clients
cannot connect to the new Server is due to their packets being routed
to the disappeared ServerSocket, even though there is another
ServerSocket that's actually bound to the port. The really perplexing
factor is the inconsistency of the behaviour.
I guess the obvious solution is to prevent the Server from shutting
down while there are still Sockets open. I can't think of another
server application that doesn't do this. For various reasons it would
be desirable in this case if one could restart the server without
closing existing connections. Is this impossible?
Any thoughts, theories or explanations would be appreciated.
Thanks
Tom