How to know Socket client got disconnected? - linux

I am doing coding in linux architecture.
I have question regarding socket server and client.
I have made one sample code in which server continue to accept the connection and client is connected to server.
if somehow someone has remove the network cable so i am disconnecting client (client socket disconnected from PC) while in server side connection is still alive because i am not able to notify that client is disconnected because network is unplugged.
How can i know that client got disconnected ?
Thanks,
Neel

You need to either configure keepalive on the socket or send an application level heartbeat message, otherwise the listening end will wait indefinitely for packets to arrive. If you control the protocol, the application level heartbeat may be easier. As a plus side, either solution will help keep the connection alive across NAT gateways in the network.
See this answer: Is TCP Keepalive the only mechanism to determine a broken link?
Also see this Linux documentation: http://tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/#programming

SIGPIPE for local sockets and eof on read for every socket type.

Related

What could cause one side of the TCP connection in FIN_WAIT2 state and the other side is fully closed (i.e. not in CLOSE_WAIT state)?

I recently encountered an TCP related issue and hope someone could shed some light on it.
I have an application1 in container1/pod1 that is connected to a server (client_ip:12345 <-> server_ip:443). After running for a while, the server decided to close this connection, so it sent FIN to the client and the client sends ACK back to the server (saw these two packets in the pcap). This sould leave the client in CLOSE_WAIT and the server in FIN_WAIT2.
In this situation, the client should call close() and send FIN back to the server. But I've found that the application lack close() in its code, so in theory, the client should be stuck in CLOSE_WAIT and the server will be in FIN_WAIT2 until FIN_WAIT2 timeout. The port 12345 on the client side shouldn't be reused by any other new connections.
However, it seems somehow the client_ip:12345 <-> server_ip:443 socket state on the client side was no longer in CLOSE_WAIT state (become fully closed and available), so when another application2 in container2 was up, it randomly pick the same port 12345 (the kernel assign the ephemeral source port from the range) to connect to the server's port 443. Because the server side were still in FIN_WAIT2, so the connection couldn't be established, and thus the service got interrupted until FIN_WAIT2 state timeout (300 secs).
I understand I should fix the application code by adding close(). However, I'm curious about what could make the CLOSE_WAIT state disappear/reset on the client side and let another application be able to pick the same 12345 port to connect to the server?
I found a F5 Bug mentioned a similar situation: "Client side connection has been fully closed. This may occur if a client SSL profile is in use and an 'Encrypted Alert' has been received."
https://cdn.f5.com/product/bugtracker/ID812693.html
I'm wondering if there are any other possibilities that could cause FIN_WAIT2 on one side and fully closed on the other side (not in CLOSE_WAIT)?
For example, the process using this socket was killed? But AFAIK, after killing that process, the socket file descriptor should be closed and a FIN should still be sent by TCP?
I hope someone could shed some light on it!

TCP server ignores incoming SYN

I have a tcp server running. A client connects to the server and send packet periodically. For TCP server, this incoming connections turns to be CONNECTED, and the server socket still listens for other connections.
Say this client suddenly get powered off, no FIN sent to server. When it powers up again, it still use the same port to connect, but server doesn't reply to SYNC request. It just ignores incoming request, since there exists a connection with this port.
How to let server close the old connection and accept new one?
My tcp server runs on Ubuntu 14.04, it's a Java program using ServerSocket.
That's not correct, a server can accept multiple connections and will accept a new connection from a rebooted client as long as it's connecting from a different port (and that's usually the case). If your program is not accepting it it's because you haven't called accept() a second time. This probably means that your application is only handling one blocking operation per time (for example, it might be stuck in a read() operation on the connected socket). The solution for this is to simultaneously read from the connected sockets and accept new connections. This might be done using an I/O multiplexer, like select(), or multiple threads.

regd setsocketopt and socket memory usage in TCP server

I have a server socket which listens on clients. This server run in an infinite loop.
After each connected client is processed, the "connected socket" is closed. Should I use the setsocketopt on the file descriptor of the connected socket for reusability? As the server socket file descriptor is never closed, I want that socket to exist all the time.
Also, I am assuming that a listening server socket is blocked until a new client establishes connection, therefore this is not using up memory.Isn't it? Please help.
thanks,
If you are thinking about SO_REUSEADDR, it doesn't let you re-use same socket for new connection. Also, I don't think this is going to buy you much. Creating new fd/socket isn't much of a task. You would find other bottlenecks than this.
But you can optimize, by not closing the connection (at server as well as client) so that same client can communicate over that connection for next requests. This will reduce your connection setup time.
Yes, by default listening socket is blocking so the accept call will be blocking. Also, this wouldn't be using much memory. You can make it non-blocking and use poll or select to determine new incoming connection.
You don't appear to know what SO_REUSEADDR is for. It doesn't have the magical properties you are attributing to it. The socket will exist until you close it. SO_REUSEADDR isn't required for any socket descriptor in most circumstances. If you're not getting bind errors you don't need it at all.

node.js tcp socket disconnect handling

I'm establishing a TCP client socket connection to an XMPP server and need a reliable way to detect interruptions in the connection (e.g. server crashes, restarts etc). I have listeners attached to the end, error and close events, but they do not fire reliably when I cut my internet connection during an active connection. How can my client detect when the connection has been broken? I would prefer not to resort to pinging/timeouts.
I'm in no way an expert on TCP or socket programming, but I'm pretty sure that there exists no "reliable way to detect interruptions in the connection". See e.g. this Unix.com thread.
In node, your options seem to be socket.setTimeout/socket.on('timeout', callback) and/or socket.setKeepAlive.
Edit: Here is a guide on TCP keepalive.

Tcp connections hang on CLOSE_WAIT status

Client close the socket first, when there is not much data from server, tcp connection shutdown is okay like:
FIN -->
<-- ACK
<-- FIN, ACK
ACK -->
When the server is busying sending data:
FIN -->
<-- ACK,PSH
RST -->
And the server connection comes to CLOSE_WAIT state and hang on there for a long time.
What's the problem here? client related or server related? This happens on Redhat5 for local sockets.
This article talk about why "RST" is sent, but I do not know why the server connection stuck on CLOSE_WAIT, and do not send a FIN out.
[EDIT]I ignored the most important information, this happens on qemu's slirp network emulation. It seems to be a problem of slirp bug for dealing with close connection.
This means that there is unread data left in in the stream, that the client hasn't finished reading.
You can force it off by using the SO_LINGER option. Here's relevant documentation for Linux (also see the option itself, here), and [here's the matching function2] for Win32.
It's the server side that is remaining open, so it's on the server side you can try disabling SO_LINGER.
It may mean that the server hasn't closed the socket. You can easily tell this by using "lsof" to list the file descriptors open by that process which will include TCP sockets. The fix is to have the process always close the socket when it's finished (even in error cases etc)
This a known defect for qemu.

Resources