(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.
Related
I'm working on a big server in C++ where we provide service to multiple users. I noticed recently that after some cases in my code, sockets are not closed properly and we have thousands of them in the state CLOSE_WAIT. I read what this mean
CLOSE_WAIT Indicates that the server has received the first FIN
signal from the client and the connection is in the process of being
closed
So this essentially means that his is a state where socket is waiting
for the application to execute close()
A socket can be in CLOSE_WAIT state indefinitely until the application
closes it. Faulty scenarios would be like filedescriptor leak, server
not being execute close() on socket leading to pile up of close_wait
sockets
I'm starting to search where is my bug because it's clear that we are not closing properly these sockets.
What implies for my program memory having all these sockets in CLOSE_WAIT state? I noticed that when I have a lot of these sockets the process start to consume a lot of memory (4GB). Which implications in relation with memory have this? Maybe this memory leak is not related with this? Thank you very much.
This question already has answers here:
close vs shutdown socket?
(9 answers)
Closed 6 years ago.
On this MSDN page:
Sending and Receiving Data on the Client
It recommends closing the sending side of the socket by using:
shutdown(SOCK_ID, SD_SEND);
Why should I?
Maybe I dont have to, and its just a recommendation? Maybe its for saving memory? Maybe for speed?
Does anyone have an idea?
The answer is in the shutdown() documentation:
If the how parameter is SD_SEND, subsequent calls to the send function are disallowed. For TCP sockets, a FIN will be sent after all data is sent and acknowledged by the receiver.
...
To assure that all data is sent and received on a connected socket before it is closed, an application should use shutdown to close connection before calling closesocket. One method to wait for notification that the remote end has sent all its data and initiated a graceful disconnect uses the WSAEventSelect function as follows :
Call WSAEventSelect to register for FD_CLOSE notification.
Call shutdown with how=SD_SEND.
When FD_CLOSE received, call the recv or WSARecv until the function completes with success and indicates that zero bytes were received. If SOCKET_ERROR is returned, then the graceful disconnect is not possible.
Call closesocket.
Another method to wait for notification that the remote end has sent all its data and initiated a graceful disconnect uses overlapped receive calls follows :
Call shutdown with how=SD_SEND.
Call recv or WSARecv until the function completes with success and indicates zero bytes were received. If SOCKET_ERROR is returned, then the graceful disconnect is not possible.
Call closesocket.
...
For more information, see the section on Graceful Shutdown, Linger Options, and Socket Closure.
In other words, at least for TCP, calling shutdown(SD_SEND) notifies the peer that you are done sending any more data, and that you will likely be closing your end of the connection soon. Preferably, the peer will also do the same courtesy for you. This way, both peers can know the connection was closed intentionally on both ends. This is known as a graceful disconnect, and not an abortive or abnormal disconnect.
By default, if you do not call shutdown(SD_SEND), closesocket() will attempt to perform a graceful shutdown for you UNLESS the socket's linger option is disabled. It is best not to rely on this behavior, you should always call shutdown() yourself before calling closesocket(), unless you have good reason not to.
It is unnecessary and redundant except in the following cases:
You want to achieve a synchronized close as described in the documentation quoted by Remy Lebeau.
The socket has been duplicated somehow, e.g. it is shared with child or parent processes or via the API, and you want to ensure the FIN is sent now.
Your application protocol requires that the peer receive a shutdown but needs to continue to send. This can arise for example when writing a proxy server.
You may have unread data in your socket receive buffer and you want to close and ignore it and send a FIN before provoking a connection reset, which will happen when you close if there is unread pending data.
These are the only cases I've ever come across in about 30 years: there may be others but I'm not aware of them.
There are no specific resources associated with sending or receiving operation on the socket, the socket is either used or closed. There reason for shutdown is not related to resource-management. Shutting down the socket is implementation of so-called graceful shutdown protocol, which allow both sides of the communication to realize the connection is going down and allows to minimize loss of data.
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Send buffer empty of Socket in Linux?
I want to create a socket server sending some data to a connecting client and disconnect him again.
I'm using non-blocking sockets so I don't know how to figure out if all data have at least been sent (send?) correctly (in short: no more data in my send buffer).
I don't want to keep the connection established if it's not neccessary anymore because I can't ensure that the client disconnects on his own.
Currently I'm just shutting down the client using shutdown() and later close(). But testing showed me a client does not always recieve all data before the connection gets closed.
There must be a way to ensure all data got send before closing the connection on non-blocking sockets, too, isn't there? Hope my question is clear enough and you can help me (:
The only way you can know your data has been sent prior to ending the connection is for the peer to acknowledge it in the application protocol. You can ensure that both ends get to EOS at the same time by shutting down for output at both ends and then reading to EOS at both ends, then closing the socket at both ends.
you can send the file size prior to data of the file. While closing the socket just check the file size and take appropriate action to close or resend the file....
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.
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.