public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* shutdown( socket, SHUT_WR ) - unexpected behaviour
@ 2004-05-01 22:07 Jacek Trzmiel
  2004-05-03 11:44 ` Corinna Vinschen
  0 siblings, 1 reply; 13+ messages in thread
From: Jacek Trzmiel @ 2004-05-01 22:07 UTC (permalink / raw)
  To: cygwin


Hi,

$ cygcheck -cd cygwin       
Cygwin Package Information
Package              Version        
cygwin               1.5.9-1        

I found some unexpected behaviour of shutdown call.  Here is example
program to reproduce problem.  It is supposed to send simple http
request to example.org, close writing part of socket, and then wait for
and print reply:

--- ShutdownTest.cpp ------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <assert.h>


const char *HOST    = "example.org";
const int   PORT    = 80;
const char *MESSAGE = "GET / HTTP/1.0\r\n\r\n";


void sendall( int sd, const char *data, int datalen )
{
    assert( data );
    assert( datalen >= 0 );
    while(datalen>0) {
        int sent = send(sd, data, datalen, 0);
        if( sent == -1) {
            perror("send");
            exit(1);
        }
        data += sent;
        datalen -= sent;
        assert( datalen>=0 );
    }
}


void recvandprintall( int sd )
{
    const int bufferlen = 65536;
    char buffer[bufferlen];

    while(true) {
        int got = recv(sd, buffer, bufferlen, 0);
        if(got == -1) {
            perror("recv");
            exit(1);
        }
        if(got==0) {
            break;
        }
        for( int i=0; i<got; ++i)
        {
            printf( "%c", buffer[i] );
        }
    }
}


void test()
{
    /* go find out about the desired host machine */
    struct hostent *he = gethostbyname(HOST);
    if (he == 0) {
        perror("gethostbyname");
        exit(1);
    }
    assert( he->h_addrtype == AF_INET );
    assert( he->h_addr_list[0] );

    /* fill in the socket structure with host information */
    struct sockaddr_in pin;
    memset( &pin, 0, sizeof(pin) );
    pin.sin_family = AF_INET;
    pin.sin_addr.s_addr = ((struct in_addr *)(he->h_addr))->s_addr;
    pin.sin_port = htons(PORT);

    /* grab an Internet domain socket */
    int sd;
    if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }

    /* connect to PORT on HOST */
    if (connect(sd,(struct sockaddr *)  &pin, sizeof(pin)) == -1) {
        perror("connect");
        exit(1);
    }

    /* send a message to the server PORT on machine HOST */
    sendall( sd, MESSAGE, strlen(MESSAGE) );

    /* shutdown writing part of socket */
    shutdown( sd, SHUT_WR );

    /* wait for data to come back from the server and print it */
    recvandprintall( sd );

    close(sd);
}


int main()
{
    test();
    return 0;
}
--- ShutdownTest.cpp ------------------------------------------------

If you compile and run it this way:
$ g++ ShutdownTest.cpp -o ShutdownTest && ./ShutdownTest.exe

it doesn't print anything.   Commenting out shutdown call or adding some
wait before it does make program work as expected:

$ g++ ShutdownTest.cpp -o ShutdownTest && ./ShutdownTest.exe
HTTP/1.1 200 OK
Date: Sat, 01 May 2004 23:28:20 GMT
Server: Apache/1.3.27 (Unix)  (Red-Hat/Linux)
Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
[...]



1. I suppose that shutdown(sd,SHUT_WR) does not force unflushed buffers
out (i.e. discards them).  Am I right?


2. Is this bug or feature?  Manual page isn't helpful:
$ man 2 shutdown
No entry for shutdown in section 2 of the manual
$ man shutdown
No manual entry for shutdown


3. If it's a feature, then how can I manually flush buffers out before
calling shutdown?


I've googled for this problem, but haven't found any relevant
information.


Best regards,
Jacek.

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 13+ messages in thread
* Re: shutdown( socket, SHUT_WR ) - unexpected behaviour
@ 2004-05-04  6:37 Arash Partow
  2004-05-04  9:21 ` Dave Korn
  0 siblings, 1 reply; 13+ messages in thread
From: Arash Partow @ 2004-05-04  6:37 UTC (permalink / raw)
  To: cygwin

Hi,

Just out of curiosity, if one were to do:

shutdown(sck,SHUT_WR)


which means as far as I understand it "stop all send reqs made to sck",
how would one reopen the sck so that you could make send reqs again?

Is that even possible or do you have to reestablish the connection
again from scratch?

I've been looking at the man pages for shutdown on linux and netbsd
and they don't say anything about how you can reverse this effect.

Any ideas anyone?


Regards



Arash

__________________________________________________
Be one who knows what they don't know,
Instead of being one who knows not what they don't know,
Thinking they know everything about all things.
http://www.partow.net






>>I've tried your application and I'm not able to reproduce your problem.
>>The shutdown call does not influence sending the buffered data apparently.
>
>Thanks for info.
>
>>I've tested with Cygwin 1.5.9 and with a recent snapshot on XP SP1.
>>What's your system?
>
>Cygwin 1.5.9, Win2kSP2.  I made additional test using winsock directly
>and got the same buggy result.  So it doesn't look like bug in cygwin,
>but rather in windows or some 3rd party app that is messing with the
>sockets (e.g. NIS).  I found similar bugreport in MS KB298871, but it's
>marked as WinCE only:
>
>http://support.microsoft.com/default.aspx?scid=kb;en-us;298871
>
>"If an application calls shutdown() to disable only sending from the
>socket, later attempts to read data sent to that socket will result in
>only portions of the data being received."
>
>
>Can somebody with Win2k box compile and run prog from my previous mail?
>I would like to know if it behaves incorrectly only on my system, or on
>Win2k in general:
>
>http://cygwin.com/ml/cygwin/2004-05/msg00013.html
>
>$ g++ ShutdownTest.cpp -o ShutdownTest && ./ShutdownTest.exe
>No output will mean that shutdown bug is present.
>
>
>> > 1. I suppose that shutdown(sd,SHUT_WR) does not force unflushed buffers
>> > out (i.e. discards them).  Am I right?
>>
>>It doesn't flush, but it also doesn't stop the data already buffered
>>from being sent.  It's only purpose is to disallow further send calls on
>>the socket.
>
>Yes, it works this way in practice (to have other reference, I've just
>tested in on FreeBSD).  I was unsure only because unix documentation I
>found was silent about this.  The only place I found now that declares
>it clearly is MSDN:
>
>http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/shutdown_2.asp
>
>"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."
>
>Regards,
>Jacek.











.

_________________________________________________________________
Protect your inbox from harmful viruses with new ninemsn Premium. Go to   
http://ninemsn.com.au/premium/landing.asp?banner=emailtag&referrer=hotmail


--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2004-05-05  2:05 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-05-01 22:07 shutdown( socket, SHUT_WR ) - unexpected behaviour Jacek Trzmiel
2004-05-03 11:44 ` Corinna Vinschen
2004-05-04  2:19   ` Jacek Trzmiel
2004-05-04  2:55     ` Larry Hall
2004-05-04  9:27       ` Dave Korn
2004-05-04 10:00         ` Keith Moore
2004-05-05  0:40           ` Jacek Trzmiel
2004-05-05  2:05           ` shutdown( socket, SHUT_WR ) - unexpected behaviour - RESOLVED Jacek Trzmiel
2004-05-05  0:35         ` shutdown( socket, SHUT_WR ) - unexpected behaviour Jacek Trzmiel
2004-05-04 12:37     ` Hannu E K Nevalainen
2004-05-05  0:42       ` Jacek Trzmiel
2004-05-04  6:37 Arash Partow
2004-05-04  9:21 ` Dave Korn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).