Link to home
Start Free TrialLog in
Avatar of Robson
RobsonFlag for Poland

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?
Avatar of jkr
jkr
Flag of Germany image

>>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

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)
Avatar of Robson

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?
>>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)
ASKER CERTIFIED SOLUTION
Avatar of bryanh
bryanh

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Robson

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.
Avatar of remster
remster

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.
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
Avatar of Robson

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).