Monday, August 29, 2011

Using Separate Read and Write Streams on socket


Sockets with separate Read and Write Streams : 

Listing 10.1 (follow this link) showed how you could associate a socket with a stream that allows both input and output. Although this might be conceptually appealing, it is actually a safer practice to open separate streams for input and output. The reason for this is the fact that the buffering of the stream plays a more complex role on one stream than it does for two separate streams. The Linux fdopen(3) man page indicates that for I/O streams it is often necessary for a fgetpos(3) call to be performed between switching from write to read modes and vice versa. Rather than try to explain why and when these special circumstances apply to an I/O stream, I'll just advise you to use two separate streams for reading and writing instead. This technique has very little overhead and provides better overall buffering performance in many cases.

Listing 10.2 shows how to create a separate read and write stream from one file descriptor.

Example
/*
 * Listing 10.2: Creating a Read and Write Stream
 */
 int s;     /* socket */
 FILE *rx;  /* read stream */
 FILE *tx   /* write stream */
 s = socket(PF_INET,SOCK_STREAM,0);
/*
 * some code part. I am skipping for time being
 */
 rx = fdopen(s,"r");
 if ( rx == NULL ) {
    fprintf(stderr, "%s: fdopen(s,'r')\n",strerror(errno));
    exit(1);
 }
 tx = fdopen(dup(s),"w");
 if ( tx == NULL ) {
    fprintf(stderr,"%s: fdopen(s,'w')\n",strerror(errno));
    exit(1);
 }

Examine Listing 10.2 carefully. Although the listing looks simple, there is one subtle function call included, which must not be overlooked. Can you find it? Look at the statement where the variable tx is assigned. Then, examine the first argument to the fdopen(3) call in that statement. Did you notice the dup(2) call when you first looked at Listing 10.2? This is very important, because different streams should use different file descriptors. One simple reason for this is so that when fclose(tx) is called, it will not close the same file descriptor being used by the rx stream.

No comments:

Post a Comment