What shutdown(socket, SHUT_RD) does?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Could somebody explain the difference between
"shutdown(socket, SHUT_RD)"   and
"shutdown(socket, SHUT_WR)"

Condition:
1. TCP connection has been established
2. Side A call shutdown(socket, SHUT_RD)

Question:
1. Could the side B send(...), and what is the result if call send(...)?
2. How could side B know that side A has called "shutdown(socket, SHUT_RD)"?

I have a sample below,
1. why the program doesn't exit with the singal SIGPIPE?
2. why side A could do send while side B has call "shutdown(socket,
SHUT_RD)"?

/*-------------  sample ------------------*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <unistd.h>
#include <errno.h>
extern int errno;

int main( int argc, char* argv[] )
{
        int sock[3];
        int ret;

        struct sockaddr_in local;

        fd_set rset;
        fd_set wset;

        struct timeval timeout;
        int width;

        socklen_t len;
        struct tcp_info info;

        char buffer[32*1024];

        sock[0] = socket( AF_INET, SOCK_STREAM, 0 );
        sock[1] = socket( AF_INET, SOCK_STREAM, 0 );

        if( sock[0]==-1 || sock[1]==-1 )
        {
                printf( "create sockets error\n" );
                return -1;
        }

        local.sin_family = AF_INET;
        local.sin_port = htons( 9999 );
        local.sin_addr.s_addr = inet_addr( "127.0.0.1" );

        bind( sock[0], (struct sockaddr*)&local, sizeof(local) );
        listen( sock[0], 5 );

        ret = connect( sock[1], (struct sockaddr*)&local, sizeof(local) );
        if( ret )
        {
                printf( "connect fail\n" );
        }

        len = sizeof( local );
        sock[2] = accept( sock[0], (struct sockaddr*)&local, &len );

        FD_ZERO( &rset );
        FD_ZERO( &wset );

        width = (sock[0]>sock[1]) ? sock[0] : sock[1];
        width++;

        send( sock[2], "ABCDEFG", 6, 0 );
        shutdown( sock[2], SHUT_RD );

AGAIN:
        timeout.tv_sec = 1;
        timeout.tv_usec = 0;

        FD_SET( sock[1], &rset );
        FD_SET( sock[1], &wset );

        ret = select( width, &rset, &wset, NULL, &timeout );
        if( !ret )
        {
                printf( "timeout\n" );
                goto END;
        }
        else
        {
                if( FD_ISSET(sock[1], &rset) )
                {
                        ret = recv( sock[1], buffer, sizeof(buffer), 0 );
                        if( ret>0 )
                        {
                                buffer[ret] = '\0';
                                printf( "recv %d bytes: %s\n", ret,
buffer );
                        }
                        else if( !ret )
                        {
                                printf( "sock[2] sending pipe closed\n" );
                        }
                        else
                        {
                                printf( "recv error: %d\n", ret );
                        }
                }

                if( FD_ISSET(sock[1], &wset) )
                {
                        ret = send( sock[1], buffer, sizeof(buffer), 0 );
                        if( ret<0 )
                        {
                                printf( "send error: %d\n", errno );
                        }
                        else if( ret==0 )
                        {
                                printf( "send 0 byte\n" );
                        }
                        else
                        {
                                printf( "send ok: %d bytes\n", ret );
                        }
                }
        }
        goto AGAIN;

END:
        len = sizeof( info );
        ret = getsockopt( sock[1], SOL_TCP, TCP_INFO, &info, &len );
        if( ret )
        {
                printf( "getsockopt fail: %d\n", errno );
        }
        else
        {
                printf( "sock[1]: tcpi_state = %d\n", (int)
info.tcpi_state );
        }

        len = sizeof( info );
        ret = getsockopt( sock[2], SOL_TCP, TCP_INFO, &info, &len );
        if( ret )
        {
                printf( "getsockopt fail: %d\n", errno );
        }
        else
        {
                printf( "sock[2]: tcpi_state = %d\n", (int)
info.tcpi_state );
        }

        return 0;
}
/*----------------- end of source ------------------*/

-
: send the line "unsubscribe linux-net" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux