The recv , recvfrom , and rcvmsg calls allow the user to look at received data without consuming it (the data will still be available for the next receive-type call). This is handy should the receiving process need to examine a message to, say, perhaps act upon it rather than pass it on to another process. To implement a nonconsumptive receive, the user must set the integer flags argument for the receive call to the defined constant MSG_PEEK. A modified Internet domain server program (Program 10.6) shows how this can be done. The processing loop of the program (where a child process is generated to handle the connection from the client) is modified to include a peek at the incoming message. These modifications are shown in Program 10.14.
Program 10.14 Internet domain connection-oriented server using MSG_PEEK.
File : p10.14.cxx /* Internet domain, connection-oriented SERVER - MSG_PEEK */ . . // Same as Program p10.6.cxx . if ( fork ( ) ==0 ) { // Generate a CHILD while ( (len==recv(new_sock, buf, BUFSIZ, MSG_PEEK)) > 0){ write( fileno(stdout), "Peeked and found: ",19); 50 write( fileno(stdout), buf, len); // show peeked msg if ( !strncmp(buf, ".done", len-1) ) break; len=recv(new_sock, buf, BUFSIZ, 0 ); // retrieve same msg write( fileno(stdout), "Re-read buffer : ",19); write( fileno(stdout), buf, len); + } write( fileno(stdout),"Leaving child process ",22); close(new_sock); // In CHILD process return 0; } else close(new_sock); // In PARENT process 60 } while( true ); // FOREVER . . // Same as Program p10.6.cxx .
The modifications to the client program (Program 10.7) are shown in the partial listing in Program 10.15.
Program 10.15 Internet domain connection-oriented client using MSG_PEEK.
File : p10.15.cxx /* Internet domain, connection-oriented CLIENT */ . . // Same as Program p10.7.cxx . + do { // Process write(fileno(stdout),"> ", 3); if ((len=read(fileno(stdin), buf, BUFSIZ)) > 0) { write(fileno(stdout), "Sending ", 9); write(fileno(stdout), buf, len); 40 send(orig_sock, buf, len, 0); } } while( strncmp(buf, ".done", len-1) ); // until end of input . . // Same as Program p10.7.cxx .
When these modified programs are compiled and run (as shown in Figure 10.18), it is easy to see that the server process can peek at the received data by specifying MSG_PEEK. When the second receive call is made, the peeked-at data is received again.
Figure 10.18 Peeking at messagesserver and client running on separate hosts .
linux$ g++ p10.14.cxx -o server linux$ g++ p10.15.cxx -o client perseus$ client linux linux$ server > George Orwell was an optimist. Peeked and found: George Orwell was Sending George Orwell was an an optimist. optimist. Re-read buffer : George Orwell was > Life is like a simile. an optimist. Sending Life is like a simile. Peeked and found: Life is like a > .done simile. Sending .done Re-read buffer : Life is like a perseus$ simile. Peeked and found: .done Leaving child process
Programs and Processes
Processing Environment
Using Processes
Primitive Communications
Pipes
Message Queues
Semaphores
Shared Memory
Remote Procedure Calls
Sockets
Threads
Appendix A. Using Linux Manual Pages
Appendix B. UNIX Error Messages
Appendix C. RPC Syntax Diagrams
Appendix D. Profiling Programs