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