Unix Socket Programming Question:

Code Sample: a very simple client process.

Answer:

/*
*The quick example below is a fragment of
* a very simple client process.
* After establishing the connection with
* the server it forks. Then
* child sends the keyboard input to the
* server until EOF is received and
* the parent receives answers from the server.
*
* variables declarations and error handling are omitted
*/
s=connect(...);

if( fork() ){
/*The child, it copies its stdin to the socket*/
while( gets(buffer) >0)
write(s,buf,strlen(buffer));

close(s);
exit(0);
}

else {
/* The parent, it receives answers */
while( (l=read(s,buffer,sizeof(buffer)){
do_something(l,buffer);

/* Connection break from the server is assumed */
/* ATTENTION: deadlock here */
wait(0); /* Wait for the child to exit */
exit(0);
}


What do we expect? The child detects an EOF from its stdin, it closes the socket (assuming connection break) and exits. The server in its turn detects EOF, closes connection and exits. The parent detects EOF, makes the wait() system call and exits. What do we see instead? The socket instance in the parent process is still opened for writing and reading, though the parent never writes. The server never detects EOF and waits for more data from the client forever. The parent never sees the connection is closed and hangs forever and the server hangs too. Unexpected deadlock!

You should change the client fragment
as follows:

if( fork() ) {
/* The child */
while( gets(buffer) }
write(s,buffer,strlen(buffer));

shutdown(s,1);
/* Break the connection
for writing, The server will detect EOF now.
Note: reading from the socket is still allowed.
The server may send some more data
after receiving EOF, why not? */
exit(0);
}


Previous QuestionNext Question
When should I use shutdown()?What are Sockets?