Robson
asked on
Socket shutdown: difference between Windows and Linux
I've read documentation for shutdown function in <a href="http://www.gnu.org/manual/glibc-2.2.5/html_node/Closing-a-Socket.html#Closing%20a%20Socket">GNU C Library</a> and <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/shutdown_2.asp">MSDN</a> and I'm slightly confused. It seems to me that glibc shutdown is "hard" (doesn't wait transmission of already send data), while behaviour of Windows shutdown depends on SO_LINGER setting. Or am I wrong? In both systems SO_LINGER option seems to affect close() syscall: maybe shutdown breaks connection non-gracefully on both systems regardless of SO_LINGER? Can anybody explain that?
I'm particulary interested in doing hard shutdown (discarding all data waiting to send) on both platforms. How to do that?
I'm particulary interested in doing hard shutdown (discarding all data waiting to send) on both platforms. How to do that?
ASKER
The behaviour of close() and closesocket() cobmined with SO_LINGER is quite clear for me. I'm still confused about shutdown(): does SO_LINGER apply to shutdown in the same way?
MSDN "The shutdown function does not block regardless of the SO_LINGER setting on the socket".
GNU documentation says: "Stop trying to transmit data from this socket. Discard any data waiting to be sent. Stop looking for acknowledgement of data already sent; don't retransmit it if it is lost."
It seems to me, that calling shutdown() just discards any data to be sent through the socket -- I just want to be sure. If I'm right I can call shutdown() followed by close[socket](), to break connection without blocking -- is it true?
MSDN "The shutdown function does not block regardless of the SO_LINGER setting on the socket".
GNU documentation says: "Stop trying to transmit data from this socket. Discard any data waiting to be sent. Stop looking for acknowledgement of data already sent; don't retransmit it if it is lost."
It seems to me, that calling shutdown() just discards any data to be sent through the socket -- I just want to be sure. If I'm right I can call shutdown() followed by close[socket](), to break connection without blocking -- is it true?
>>If I'm right I can call shutdown() followed by close
>>[socket](), to break connection without blocking -- is
>>it true?
That depends - 'shutdown()' itself won't block. If you want to totally get rid of the socket, calling 'shutdown ( s, SD_BOTH);' should be fine. There are however other possibilities, like e.g. the following:
"2.6 When should I use shutdown()?
From Michael Hunter ( mphunter@qnx.com):
shutdown() is useful for deliniating when you are done providing a request to a server using TCP. A typical use is to send a request to a server followed by a shutdown(). The server will read your request followed by an EOF (read of 0 on most unix implementations). This tells the server that it has your full request. You then go read blocked on the socket. The server will process your request and send the necessary data back to you followed by a close. When you have finished reading all of the response to your request you will read an EOF thus signifying that you have the whole response. It should be noted the TTCP (TCP for Transactions -- see R. Steven's home page) provides for a better method of tcp transaction management"
(from http://www.softlab.ece.ntua.gr/facilities/documentation/unix/unix-socket-faq/unix-socket-faq-2.html#ss2.5)
>>[socket](), to break connection without blocking -- is
>>it true?
That depends - 'shutdown()' itself won't block. If you want to totally get rid of the socket, calling 'shutdown ( s, SD_BOTH);' should be fine. There are however other possibilities, like e.g. the following:
"2.6 When should I use shutdown()?
From Michael Hunter ( mphunter@qnx.com):
shutdown() is useful for deliniating when you are done providing a request to a server using TCP. A typical use is to send a request to a server followed by a shutdown(). The server will read your request followed by an EOF (read of 0 on most unix implementations). This tells the server that it has your full request. You then go read blocked on the socket. The server will process your request and send the necessary data back to you followed by a close. When you have finished reading all of the response to your request you will read an EOF thus signifying that you have the whole response. It should be noted the TTCP (TCP for Transactions -- see R. Steven's home page) provides for a better method of tcp transaction management"
(from http://www.softlab.ece.ntua.gr/facilities/documentation/unix/unix-socket-faq/unix-socket-faq-2.html#ss2.5)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks for your help. I'll ask Community Support to split points between you in a week. I'm still waiting for any new comments, if someone know something that jkr and bryanh don't.
well, having written a big win32 web server, I've had to deal with shaking off connections that are no longer welcome.
I've given up on shutdown because it was too wimpy.
Under Windows, I do
WSAAsyncSelect(socket, windowhandle, 0, 0) ;
u_long ul = 0 ; ioctlsocket(socket, FIONBIO, &ul) ;
LingerStruct ls = {1, 0} ;
setsockopt(socket, SOL_SOCKET, SO_LINGER, (LPSTR)&ls, sizeof(ls)) ;
if (SOCKET_ERROR == closesocket(socket))
AddSocketToKillList(socket ) ;
the WSAAsyncSelect is needed because I used the async notifications.
The FIONBIO sets the socket as non blocking to avoid surprises.
TIP: also pay attention to the closesocket return value.
If it's not happy, it's not closed.
I keep a list that I torture later at intervals until they finally break off.
The test that they broke off is with a combination of getsockopt, getpeername, getsockname and setsockopt.
If the socket accepts to be manipulated, it's deemed to be alive and I keep trying to kill it.
I didn't do many unix experiments lately so I can't guarantee this will help on that side of the project.
I've given up on shutdown because it was too wimpy.
Under Windows, I do
WSAAsyncSelect(socket, windowhandle, 0, 0) ;
u_long ul = 0 ; ioctlsocket(socket, FIONBIO, &ul) ;
LingerStruct ls = {1, 0} ;
setsockopt(socket, SOL_SOCKET, SO_LINGER, (LPSTR)&ls, sizeof(ls)) ;
if (SOCKET_ERROR == closesocket(socket))
AddSocketToKillList(socket
the WSAAsyncSelect is needed because I used the async notifications.
The FIONBIO sets the socket as non blocking to avoid surprises.
TIP: also pay attention to the closesocket return value.
If it's not happy, it's not closed.
I keep a list that I torture later at intervals until they finally break off.
The test that they broke off is with a combination of getsockopt, getpeername, getsockname and setsockopt.
If the socket accepts to be manipulated, it's deemed to be alive and I keep trying to kill it.
I didn't do many unix experiments lately so I can't guarantee this will help on that side of the project.
Hello all
Robson has asked to split the points
https://www.experts-exchange.com/questions/20355901/Points-to-split-questions-to-delete.html
i lower the points here to give the user a chance to ask points for questions for the other two experts
JGould-EE Moderator
Robson has asked to split the points
https://www.experts-exchange.com/questions/20355901/Points-to-split-questions-to-delete.html
i lower the points here to give the user a chance to ask points for questions for the other two experts
JGould-EE Moderator
ASKER
Thaks for your comments! I'll give points to remster and jkr in separate questions just as CS said. I apologise for keeping you waiting for so long (ether EE was down, or our company network unusable).
ASKER
remster, go and take your reward please!
https://www.experts-exchange.com/questions/20366356/points-for-remster.html
https://www.experts-exchange.com/questions/20366356/points-for-remster.html
>>transmission of already send data), while behaviour of
>>Windows shutdown depends on SO_LINGER setting
The GNU document also states:
"If there is still data waiting to be transmitted over the connection, normally close tries to complete this transmission. You can control this behavior using the SO_LINGER socket option to specify a timeout period; see Socket Options."
So, that's basically the same behaviour as described in the MS document. Additionally, on the socket options:
SO_LINGER
Sets or gets the SO_LINGER option. The argument is
a linger structure.
struct linger {
int l_onoff; /* linger active */
int l_linger; /* how many seconds to linger for */
};
When enabled, a close(2) or shutdown(2) will not
return until all queued messages for the socket
have been successfully sent or the linger timeout
has been reached. Otherwise, the call returns imme
diately and the closing is done in the background.
When the socket is closed as part of exit(2), it
always lingers in the background.
(gnu manpages)
SO_LINGER
The SO_LINGER option controls the action taken when unsent data is queued on a socket and a closesocket is performed. See closesocket for a description of the way in which the SO_LINGER settings affect the semantics of closesocket. The application sets the desired behavior by creating a LINGER structure (pointed to by the optval parameter) with these members l_onoff and l_linger set appropriately.
(MSDN)