Reputation: 1698
I have implement socket communication like the following :
The socket Client send "0010ABCDEFGHIJ" to the socket server , the first 4 bytes(in this case , "0010") describe the message body has 10 bytes, and those bytes followed are message body !!
I use "The Linux Programming Interface" readn function in server side , the source :
ssize_t
readnx(int fd, void *buffer, size_t n)
{
ssize_t numRead; /* # of bytes fetched by last read() */
size_t totRead; /* Total # of bytes read so far */
char *buf;
buf = (char*) buffer; /* No pointer arithmetic on "void *" */
for (totRead = 0; totRead < n; ) {
numRead = recv(fd, buf, n - totRead,MSG_NOSIGNAL);
if (numRead == 0) /* EOF */
return totRead; /* May be 0 if this is first read() */
if (numRead == -1) {
if (errno == EINTR)
continue; /* Interrupted --> restart read() */
else
return -1; /* Some other error */
}
totRead += numRead;
buf += numRead;
}
return totRead; /* Must be 'n' bytes if we get here */
}
void *thread1(void *param)
{
int nread = 0 ;
char strdata[1024]={0},strtmp[128]={0} ;
pthread_detach(pthread_self());
while(1)
{
memset(strtmp,0x00,sizeof(strtmp)) ;
if ( (nread = readnx(sd,strtmp,4)) <= 0){
break ;
}
int ilen = atoi(strtmp) ;
memset( strdata,0x00,sizeof(strdata) ) ;
if ( (nread = readnx(sd,strdata,ilen)) <= 0){
break ;
}
}//while
}
This works fine to me , I like to know more details about performance , I have 2 readnx function calls in my source code , and doing it in blocking mode , If I change my code to make recv with MSG_PEEK first , once all 14 bytes are all available , then call readnx once to fetch all datas, Would it be faster than my original 2 readnx calls ?!
I am wondering in my original source , I have 2 readnx to recv "0010" and "ABCDEFGHIJ" separately , Would this cause linux kernel to copy to user space twice even all 14 bytes are all there already at the time I called first readnx ?! Or the kernel copy all 14 bytes to user space just once , the readnx function just read it from user space ?!
If I like to know those details about kernel to user space procedures , what documents,function call could help me to go through the details.
Upvotes: 2
Views: 1136
Reputation: 311028
If I change my code to make recv with MSG_PEEK first, once all 14 bytes are all available
That implies that you're going to sleep and retry. How long are you going to sleep for? How do you know how far apart in time the pieces are going to arrive?
then call readnx once to fetch all datas, Would it be faster than my original 2 readnx calls?
No. You won't sleep for the correct amount of time, unlike recv()
, and you might do a lot more than one MSG_PEEK receives.
If you're concerned about the performance of the two recv()
calls, or however many it takes, you should do your best at the sender to ensure the header and the message are sent at the same time: have a look at sendmsg()
.
Upvotes: 2