ReadingWriting All Available Data

 < Day Day Up > 



Reading/Writing All Available Data

The basis for this optimization is that the least number of calls should be made to move data between the Application and Sockets layer. This is due to a number of concerns, including user/kernel switches and the cost of buffer copies between the user layer and the kernel layer.

Consider the code in Listing 7.2, which illustrates a number of calls to write a series of data through a stream socket.

Listing 7.2 Multiple writes for a series of data.

start example
 int sock, ret; char cmd1[MAX_CMD_BUFFER+1]; char cmd2[MAX_CMD_BUFFER+1]; char cmd3[MAX_CMD_BUFFER+1]; char resp[MAX_RESP_BUFFER+1]; int cmd1_len, cmd2_len, cmd3_len; ... sock = socket( AF_INET, SOCK_STREAM, 0 ); ... /* Commands are formatted into the three command arrays */ /* Lengths are stored into cmd?_len */ /* Send the first command */ ret = send( sock, cmd1, cmd1_len, 0 ); /* Send the second command */ ret = send( sock, cmd2, cmd2_len, 0 ); /* Send the third (and final) command */ ret = send( sock, cmd3, cmd3_len, 0 ); /* Await the response */ ret = recv( sock, resp, MAX_RESP_BUFFER, 0 );
end example

From an execution standpoint, three send calls are made that, depending upon the target operating system can result in transitions between user and kernel space. Each call results in the transition plus a copy of a command between user and kernel space for subsequent transport through the socket. Because TCP is a stream protocol, there is no distinction made to the framing of the data that was sent. Therefore, the receiver could receive cmd1_len octets or the total of all three (depending upon how the sender’s protocol stack aggregated the data).

Listing 7.2 may be readable and more accurately mirror the intent of the developer, but rather than suffer the performance hit of the three potential kernel calls and three independent buffer copies between user space and kernel space, an alternative is to perform a single send call (as shown in Listing 7.3).

Listing 7.3 Single write for higher performance.

start example
int sock, ret; #define MAX_CMDS_BUFFER    (MAX_CMD_BUFFER*3) char cmd1_2_3[MAX_CMDS_BUFFER+1]; char resp[MAX_RESP_BUFFER+1]; int cmd1_len, cmd2_len, cmd3_len; ... sock = socket( AF_INET, SOCK_STREAM, 0 ); ... /* Commands are formatted into a single command array */ /* Lengths are stored into cmd?_len */ /* Send the commands */ ret = send( sock, cmd1_2_3,              (cmd1_len+cmd2_len+cmd3_len), 0 ); /* Await the response */ ret = recv( sock, resp, MAX_RESP_BUFFER, 0 );
end example

The advantage to Listing 7.3 over Listing 7.2 is that we perform only one kernel call and rather than three independent buffer copies between user space and kernel space, we perform only one. This has significant performance savings, especially when this activity is performed often.



 < Day Day Up > 



BSD Sockets Programming from a Multi-Language Perspective
Network Programming for Microsoft Windows , Second Edition (Microsoft Programming Series)
ISBN: 1584502681
EAN: 2147483647
Year: 2003
Pages: 225
Authors: Jim Ohlund

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net