By using select function handling multiple client connection in RPI using c. If CLOSE_WAIT came code is not working.if it occurs I am trying to kill the socket but code is hanging. Without restart how to resolve this
Please help in this.....
When CLOSE_WAIT will come how to avoid this.
I am thinking it will come if we didn't close the socket but how to close during network loss. Or else How to do read timeout on server side
Call shutdown(fd, 2) before close(fd), otherwise your socket will go into CLOSE_WAIT state to wait for the FIN handshake. This can take quite a while. I believe it is four minutes on Solaris, for example.
If you have a newer unix, you can use SHUT_RDWR instead of 2.
Related
I am developing a 9p server, it is pretty much like an nfs server. Subsequent mounting and unmounting causes no socket descriptor file leakage because I am able to close the socket. However, in the following scenario, the server does not do a proper clean up and close the socket. The scenario is, when the client at Machine A mount a FS from the server machine. Then for some reason, Machine A restarts or is shut down. If this happens, I am expecting the server to clean up the work and close the socket but for some reason it blocks on read(). I thought a read() should return 0 when a connection is closed but it doesnt. I assume thats because a proper tcp termination has not occured so the server is waiting for some data from the client. Here is a pseudo code of my server
while(1){
n = read(sockfd, buffer, 4); //4 is protocol header that specifies the size
if ( n == 0 ) break;
/* iteratively read the rest of bytes until the incoming message ends */
}
cleanup(); // close socket and some other tasks
However, when the client restarts while the server is blocking on read, nothing happens. What is the best way and easiest to solve this? Some people suggest running a separate thread that checks connections but this is too involved. I am sure there must be a faster way
When the client does a shutdown then the OS on client terminates all TCP connection. But when the client crashes or it is switched off or when an network problem occurs somewhere at path between the client and the server then there is no way to deliver an information to server and the server may be blocked in the read() call forever.
There are two possible solutions. Either you can use standard TCP keep alive probes or you can implement an application level health-check.
TCP keep alive
TCP keep-alive is well described for example at http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html :
In order to understand what TCP keepalive (which we will just call keepalive) does, you need do nothing more than read the name: keep TCP alive. This means that you will be able to check your connected socket (also known as TCP sockets), and determine whether the connection is still up and running or if it has broken...
When you want you application use TCP keep alive the just set the socket option (error checking is missing):
int optval = 1;
socklen_t optlen = sizeof(optval);
setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen);
The TCP keep alive is easy to use but it depends on the OS configuration and application cannot set own timeouts because they are configurable system wide.
Application level health check
Use an application level mechanism when you need application specific timeouts for disconnection detection. There are plenty of ways how to implement it. The idea is to send periodically a piece of useless data and assume connection is destroyed when it is not received.
I want to amend Zaboj Campula's good answer with the most important way to deal with this: Timeouts. Normally, you would assign a timeout to any socket operation. A typical value is 30 seconds. That way there is no need for keep alives most of the time. Connection failure will be detected within 30 seconds.
Some people suggest running a separate thread that checks connections but this is too involved.
That does not work because your machine does not know that the connection is gone. There is nothing to check.
I have write a simple program using socket in C that create a connect between X86 running windows and ARM running embedded linux(consist of only Busybox and libc).Suddenly this small program could not connect the windows and linux,then I running "netsta -a" found 3 socket's state is CLOSE_WAIT and PID is NULL.So I try to modify “net.ipv4.tcp_keepalive_×” but because busybox has only the basic functions that I could not using /etc/rc.d/init.d/network restart makes the modify take effect.
So I want to know:
how to make the change take effect with Busybox?
how I using socket can avoid the CLOSE_WAIT problem?
How do I remove a CLOSE_WAIT connection that doesn't belong to any tasks?
As we've established that the process is still running, it does belong to a task. We've also established that the netstat output was a complete red herring.
All you have to do is close the socket. You probably forget to close it after you got the connection failure. It's just a common or garden file/socket descriptor leak.
You might want to check out: https://github.com/rghose/kill-close-wait-connections
What this script does is send out the ACK which the connection was waiting for.
This is what worked for me.
A typical answer to the question of how to put time limit on connection attempt when using sockets is this:
1) make socket non-blocking,
2) call connect(),
3) use select() to see if connection is successful.
What is not clear to me at the moment is how to terminate connection attempt after certain amount of time if connection cannot be established. As far as I understand OS will continue trying to establish connection even after select() returns (providing select() timeout is smaller than OS timeout).
Is this correct? If so, how can I stop this process? Is switching socket back to blocking sufficient? Are there any other options except closing a socket? Thanks.
Just close the socket. It isn't any further use to you if you've decided the connect is taking too long. The OS will stop trying, release the resources, etc., everything you want.
I want to be able to stop listening on a server socket in linux and ensure that all connections that are open from a client's point of view are correctly handled and not abruptly closed (ie: receive ECONNRESET).
ie:
sock = create_socket();
listen(sock, non_zero_backlog);
graceful_close(sock);
if thought calling close() and handling already accept'd sockets would be enough but there can be connections that are open in the kernel backlog which will be abruptly closed if you call close() on the server socket.
The only working way to do that (that I have found) is to:
prevent accept() from adding more clients
have a list of the open sockets somewhere and to wait until they are all properly closed which means:
using shutdown() to tell the client that you will no longer work on that socket
call read() for a while to make sure that all the client has sent in
the meantime has been pulled
then using close() to free each client socket.
THEN, you can safely close() the listening socket.
You can (and should) use a timeout to make sure that idle connections will not last forever.
You are looking at a limitation of the TCP socket API. You can look at ECONNRESET as the socket version of EOF or, you can implement a higher level protocol over TCP which informs the client of an impending disconnection.
However, if you attempt the latter alternative, be aware of the intractable Two Armies Problem which makes graceful shutdown impossible in the general case; this is part of the motivation for the TCP connection reset mechanism as it stands. Even if you could write graceful_close() in a way that worked most of the time, you'd probably still have to deal with ECONNRESET unless the server process can wait forever to receive a graceful_close_ack from the client.
Is it possible for me to accept a connection and have it die withouit my knowing, then accept another connection on the same socket number?
I've got a thread to do protocol parsing and response creation. I've got another thread to handle all my network IO and one more thread to handle new incomcing connection requests. That makes three threads total. Using select in the IO thread, I get a failure and have to search for the dead socket. I am afraid there is the case that accept might want to accept a new connection on a socket number that was previous dead.
I'd assume this can't happen until I "shutdown() || close();" the socket that may be dead on the server side. If it could happen, is the only solution to setup mutexes to halt everything while I sort out what sockets have gone bonkers?
Thanks,
Chenz
A socket descriptor wont get reused until you close it.
Assuming we're talking TCP, then if the remote side closes its send side of the connection then you'll get a recv() returning 0 bytes to tell you of this. Since TCP support half closed connections you could still be able to send data to the remote side of the connection (if your application level protocol is made that way) or you might take the fact that the remote side has closed its send side as an indication that you should do the same.
You use shutdown() to close either your send side or your recv side or both sides of the connection. You use close() to close the socket and release the handle/descriptor for reuse.
So, in answer to your question. No, you wont be able to accept another connection with the same socket descriptor until you call close() on the descriptor that you already have.
You MAY accept a connection on a new socket descriptor; but that's probably not a problem for you.