I have a C++ application called A which open a TCP connection to Application B.
Application C knows about this connection and can close the socket from B side.
My question is:
how can I know if the connection has closed in proper closing, or it is the network connection problem?
Currently I have a timeout which knows when there is no receive, but this not indicate about a proper closing or network connection problem.
I heard that since it is a TCP connection if application C close the connection properly the OS must know about it, do you know how can I know in application A that the connection has closed properly?
if you can attach a c++ sample it will be helpful.
If the connection was closed properly, recv() will return zero. If it was closed improperly, recv() will eventually timeout (although there can be other reasons for that), and send() will eventually return -1 with errno ECONNRESET or whatever it's called.
Related
This question already has answers here:
How to close Winsock UDP socket hard?
(3 answers)
UDP socket still bound to previous port – how to reuse it?
(2 answers)
Closed 11 months ago.
I am facing a strange issue where my UDP socket that was earlier bound to a port is not unbinding from the port when I call closesocket(). The API call doesn't return any error but netstat command and TCPView app still show that port is still in use by my application.
My application is a COM server and socket creation happens on one thread, binding closing happens on different thread, reading on a third thread.
So far tried creating the socket, binding, reading and closing on the same thread but still seeing the issue.
I am making a UPD socket application based on winsock. However, I cant figure out how to check if server socket is closed or not. I try to use recvfrom but it still return sent data even when the program closed. Is there anyway to check if a socket is closed or not.
(Winsock32 / C++ / Win32 environment)
To my understanding, as opposed to closing a file handle for instance (using CloseHandle()),
closing a socket is an operation of 2 parts, other then releasing the SOCK handle, and freeing the actual resource, it also responsible of informing the other side of the connection upon session termination.
The question is, how to handle the scenario of a server closing the connection for it's own reason , and then client trying to close it on their side. That means, how to do only the resources releasing part, as described above , without the termination informing.
how to handle the scenario of a server closing the connection for it's
own reason ?
If you call closesocket() on a socket that have already been invalidated by a closed connection, you are just releasing the socket descriptor, you don't have to worry whether the socket is closed on the other side or not.
In my program I have several sockets on the server. Each socket has its own port. I tried to detect if the client closed the connection with:
signal(SIGPIPE, sig_pipe);
But I have the problem that I don't know on which socket the connection was closed.
Is there some method to get it to know?
More about code:
In main program I started 3 Sockets on different ports. Accept, receive and send for each socket I put in one thread. So I have 3 threads at the end.
Thank you.
You should setup SIGPIPE to be ignored (see sigaction(2)) and handle EPIPE error code from write(2) and the likes.
Note, that reading zero bytes from TCP socket is the real indication of the other side closing the connection.
What is the easiest way to check if a socket was closed on the remote side of the connection? socket::is_open() returns true even if it is closed on the remote side (I'm using boost::asio::ip::tcp::socket).
I could try to read from the stream and see if it succeeds, but I'd have to change the logic of my program to make it work this way (I do not want data to be extracted from the stream at the point of the check).
Just check for boost::asio::error::eof error in your async_receive handler. It means the connection has been closed. That's the only proper way to do this.
Is there a boost peek function available? Most socket implementations have a way to read data without removing it from the queue, so you can read it again later. This would seem to satisfy your requirements.
After quickly glancing through the asio docs, I wasn't able to find exactly what I was expecting, but that doesn't mean its not there.
I'd suggest this for starters.
If the connection has been cleanly closed by the peer you should get an EOF while reading. Otherwise I generally ping in order to figure out if the connection is really alive.
I think that in general once you open a socket, you should start reading it inmediately and never stop doing so. This way you can make your server or client to support both synchronous and asynchronous protocols. The moment the client closes the connection, the moment the read will tell you this.
Using error_code is able to check the condition whether the client is connected or not. If the connection is success, the error_code error.value() will return 0, else return other value. You can also check the message() from the error_code.
boost::asio::socket_base::keep_alive keepAlive(true);
peerSocket->set_option(keepAlive);
Enable keep alive for the peer socket. Use the native socket to adjust the keepalive interval so that as soon as the connection is closed the async_receive handler will get EOF while reading.
Configuring TCP keep_alive with boost::asio