On Sat, 10 Jul 2004, Shachar Shemesh wrote: > The info pages. > > Do "info libc". Scroll down to "Function index". Search for "shutdown". > > It has a pretty detailed description of "close" sending all pending > data, and then says: > > > `1' > > 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.
this looks inconcievable, because it implies that shutdown is a useless function. i'd say this is a bug in the documentation. to demonstrate this, i've done the following experiment. - write a server that listens for a connection on a port, and when accept() returns a socket, read data from the socket until an EOF. after first passing the 1024*80 bytes (80KB) of data line mark, the server prints how much data it already got, goes to sleep for 10 seconds and then continues reading. in the end it prints the total number of bytes (octets) it received. - write a client that connects to a server, writes 200KB of data in 1024 bytes chunks, with a 100ms sleep after each 1024 chunk was sent (either in a single write() or in multiple write()-s). after the 200KB were written, the client prints the number of bytes written, preforms a shutdown(s, SHUT_WR) on the socket, and goes to sleep for 100 seconds. - run the above server. run the above client. in a terminal window, perform the following command repetedly, in order to see the kernel-level send-q and receive-q sizes. netstat -t | egrep 5050 (5050 was the port on which my server listened). when the client got to its sleeping point (seen by the printing of the above-mentioned message), the above netstat command showed that the client's send-q is non-zero, for several seconds (until the server wakes up). after the server wakes up, the queues quickly got down to zero, and the server reported receiving a total of 200KB of data (i.e. the exact number of bytes that the client sent). as i see it, shutdown() did NOT make the client discard the data stored in its send-Q. this contradicts the glibc documentation which states that shutdown will 'Discard any data waiting to be sent.' you may also look at the source code of the 'tcp_shutdown' function in the kernel, to see that it does not discard any data. note: the numbers above were chosen because: 1. a socket on my system has a default queue size of ~64KB. thus, 120KB will fill the server's recv-Q when it sleeps and fill most of the client's send-Q. 2. the reason for the sleeps between sends, is to give the user (that's me) enough time to run netstat and read its output, even if i'm a little tired, and to see how the queues fill up. 3. the reason for the long-sleep on the server, is to give the (artifically slow) client enough time to finish sending its data before the server resumes reading data from the socket. i'd suggest referring to the bible (W. richard steven's books about Unix network programming) for proper explanations regarding the shutdown() system call (i know, i know, on linux it's a specific function of the socketcall system call. lets not get too pesky). (... after a few minutes) ok, i took my own advice and checked the bible, and it contradicts the info page - shutdown(s, SHUT_WR) will send a FIN _AFTER_ sending any queued data, and will fail any _new_ writes to the socket. -- guy "For world domination - press 1, or dial 0, and please hold, for the creator." -- nob o. dy ================================================================= To unsubscribe, send mail to [EMAIL PROTECTED] with the word "unsubscribe" in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]