According to tcp protocol when ever tcp connection termination is going on, tcp socket of initiator go to following states FIN-WAIT-1, FIN-WAIT-2,TIME-WAIT before connection is completly closed and the tcp socket of other end go to following states CLOSE-WAIT, LAST-ACK, CLOSED before connection is completly closed.
In our application server is initiating connection termination which leading to server side sockets are waiting in FIN_WAIT2 state infinitely, due to this connections made by clients are dropped by server because of unavailability of ports.
Is connection termination initiated by clients is favourable or not?
Initiating termination from the client can be favorable because it prevents the server from going to TIME_WAIT. Your problem is different.
A socket in FIN_WAIT2 is "half open": the client side can still send data and you can read it, but you can't send anything back. The socket will stay in this state until the client closes its socket, or the server resets the connection.
So it sounds like your clients are simply not closing their sides of the connections.
Related
In a client-server application, I send a string to the server in a separate thread:
dataOutputStream.writeUTF(_dos);
dataOutputStream.flush();
But I get in another thread java.net.SocketException: Connection reset in the line:
mes = dataInputStream.readUTF();
At the same time, the server does not receive anything (I checked this in wireshark) and continues to listen to the socket.
The question is: is it possible, if the client socket is damaged, but the server socket is working, to restore the operation of the client socket and thus restore the client-server connection, without restarting both?
The connection is gone. On the client side, you will need to connect again.
Generally speaking, TCP implementations do not allow you to issue a connect on a socket that has become disconnected. You can try, but it's safest to make a new socket object. Even if it works for you, the result may be non-portable.
The server of course also has a socket on a defunct connection, so it needs to close its end. A new socket will be created on 'accepting' the new connection from the client.
Is it possible that I will close(forcibly) server and then start it so the other side will not notice it? Some SO_ADDRREUSE or Linger time magic possible??
I don't think that is possible. When you stop your server socket, you lose any TCP connection information, so any traffic will have to establish a new connection after the server restarts.
My TCP server is implemented using Netty. My client using vanilla java.net.Socket to connect to this server. I'm using the same socket to send multiple requests to the server. Once done with all the requests the client calls socket.close().
I'm not closing the channel anywhere in my server code. Also, I've set TCP KEEP_ALIVE on my server. Will closing the socket on the client end automatically close the channel on the server or do I've to do something else explicitly and what is the best practice ?
Usually, if an application closes a socket, its remote peer also notices that the closure. Therefore, you don't need to call close() on both side. However, sometimes, due to network problems, you might not get notified when the remote peer closes the connection. To work around this problem, it's a good idea to send some message periodically, and then you will detect the unexpected closure sooner.
Please note SO_KEEP_ALIVE will not help much here because for most operating systems because the default keep alive time is very long.
In Java, if I connect to a client to a server via a socket and the client has an exception which causes it to crash, is there any way the server can detect that the socket connection is lost.
I assume one method would be have some sort of heartbeat polling the client, but is there a simpler/easier way?
There are a few ways, depending on what you consider to be a "crash".
If the client process dies, the client OS will close the socket. The server can detect this by performing a read(), which will either return -1 (EOF) or raise a SocketException ("connection reset").
If the client gets into an infinite loop, the connection will remain open; the only way to detect this is by incorporating some kind of "heartbeat" into your protocol.
If the client host is rebooted or the network connection breaks, the server may not notice unless either:
the protocol has a "heartbeat" mechanism as above, with some kind of timeout, or
TCP keepalive is enabled on the socket by calling socket.setKeepAlive(true) - this instructs the OS to periodically* send a packet to check that the remote end of the connection is alive, closing the connection if not
*both Windows and Linux default to 2 hours; you can change this system-wide but not per-socket (under Java, anyway)
TCP sockets do this anyway, and Java exposes it to the developer. See setKeepAlive() / getKeepAlive() in the Socket class. If a TCP message isn't sent from the client to the server for a certain period of time, the socket will close, and the server can remove the session information because it still has its endpoint.
I learned an example of usage of sockets. In this example a client sends a request to a server to open a socket and then the server (listening to a specific port) opens a socket and everything is fine, socket is "opened" from both sides (client and server).
But it is still not clear to me how flexible is this stuff. For example, is it possible for the client to close an opened (from both ends) socket and to reopen it again (under condition that the server keeps the socket opened).
Is it possible for the server to "know" that a socket was closed on the client side? Is it possible for the client to know that a socket was closed on the server side?
ADDED:
One more important thing to me. What happens if a application (no mater server or client) crashes, abnormally terminated, killed? Will it close all sockets opened on the side of the application?
ADDED 2:
What if an application on one side of the socket is switched off (killed, closed, terminated) and then it is switched on again (on the same IP address and the same port). Should we create a new socket between the two applications or we can use the old socket (created before the crash).
A socket can be used for a lot of things for which the answers to these questions would change, but I'll assume you're talking about TCP.
For example, is it possible for the client to close an opened (from both ends) socket and to reopen it again (under condition that the server keeps the socket opened).
No, because TCP will perform a goodbye and you can't pick up the connection from there again. You'd have to do the three-way handshake again, and that starts a brand new connection.
Is it possible for the server to "know" that a socket was closed on the client side? Is it possible for the client to know that a socket was closed on the server side?
Yes. TCP can send out a goodbye packet or one side can time out and it's entirely possible to detect these scenarios in both cases.
Is it possible for the server to
"know" that a socket was closed on the
client side?
When server tries to send some data to that client a correspondent exception will be thrown.
One more important thing to me. What
happens if a application (no mater
server or client) crashes, abnormally
terminated, killed? Will it close all
sockets opened on the side of the
application?
Exceptions are created for handling these abnormal cases. If there is a black out and a client (or server) is turned off then other side will get an exception as soon as it try to interact with turned off side.
UPD:
What if an application on one side of
the socket is switched off (killed,
closed, terminated) and then it is
switched on again (on the same IP
address and the same port). Should we
create a new socket between the two
applications or we can use the old
socket (created before the crash).
Create new socket.
Q1->Is it possible for the server to "know" that a socket was closed on the client side? Is it possible for the client to know that a socket was closed on the server side?
A1 -> The sever will know, if client closes socket and vice versa. Actually FIN will be sent from the end, which is initiating to close connection.
Q2-> What if an application on one side of the socket is switched off (killed, closed, terminated) and then it is switched on again (on the same IP address and the same port). Should we create a new socket between the two applications or we can use the old socket (created before the crash).
A2->If socket is created, fd number is bind with ip-addr & port, so socket on server side has server-ip & some port and socket on client side has client-ip & some port. if crash happened at client the all fd are freed and it can not be reused.if we use the same fd, system will treat it as normal file fd.