What am I missing?
I have very simple client and server. The server uses recv with timeout (using select) for 3 seconds. Then it shutdowns and closes the sockets and exits.
The client connects to the server, sleeps 30 seconds and sends very short message. The sending is about 27seconds after the server has closed the sockets and exited.
And send does not fail..? Why? Why it does not return -1 for error?
Please note: I cut all checks for return codes and removed all logs, to make this as short as I can. Also, I removed all includes, to make this shorter. But it IS a real code.
client code:
int main( int argc, char* argv[] )
{
addrinfo hints;
memset(&hints, 0, sizeof hints); // make sure the struct is empty
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM; // TCP stream sockets
addrinfo *res;
getaddrinfo( "127.0.0.1", "1313", &hints, &res );
int nSocketFD = socket( res->ai_family, res->ai_socktype, res->ai_protocol );
assert( -1 != connect( nSocketFD, res->ai_addr, res->ai_addrlen) );
freeaddrinfo( res ); // free the linked-list, we don't need it anymore
sleep( 30 );
if( send( nSocketFD, "bla", 4, 0 ) > 0 )
{
printf( "Message successfully sent!\n" );
}
close( nSocketFD );
return 0;
}
and server:
int main()
{
addrinfo hints;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
addrinfo *res; // will point to the results
getaddrinfo( NULL, "1313", &hints, &res );
int nSocketFD = socket( res->ai_family, res->ai_socktype, res->ai_protocol );
bind( nSocketFD, res->ai_addr, res->ai_addrlen );
freeaddrinfo( res ); // free the linked-list
listen( nSocketFD, 1 );
sockaddr_storage their_addr;
socklen_t addr_size = sizeof( sockaddr_storage );
int nAcceptedSocket = accept( nSocketFD, (sockaddr*)&their_addr, &addr_size );
assert( -1 != nAcceptedSocket );
fd_set fds;
FD_ZERO( &fds );
FD_SET( nAcceptedSocket, &fds );
timeval tv;
tv.tv_sec = 3;
tv.tv_usec = 0;
if( 0 == select( nAcceptedSocket + 1, &fds, NULL, NULL, &tv) )
{
printf( "recv timeout! Exiting..\n" );
shutdown( nSocketFD, SHUT_RDWR );
close( nSocketFD );
shutdown( nAcceptedSocket, SHUT_RDWR );
close( nAcceptedSocket );
return 1;
}
assert( false );
return 0;
}
When I execute it, I see the messages for recv timeout and for successful sent message.
Sorry for the long and probably stupid question.
In general you need to read from a socket to get it to notice that the remote end has closed the connection.
From the manual page of
send(which is justwritebut with flags):