LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Is recv() is blocking function... (https://www.linuxquestions.org/questions/programming-9/is-recv-is-blocking-function-859969/)

manohar 02-01-2011 06:23 AM

Is recv() is blocking function...
 
Hi,

Is recv() in socket is a blocking function...?

Basically iam waiting for data on socket connection using recv(). Some times iam receiving recv_data as < 0. Could you guys please tell me the reasons for this.
while(1) {
recv_len = 0;
do{
recv_len += recv(sockId, &Rx_buffer[recv_len], 8, 0);
}while((recv_len>0) && (recv_len < 8));
if(recv_len < 0) {
printf("error while receiving: error %d",recv_len);
}else if(recv_len == 0) {
close(sockId);
}else {
printf("Received data");
}
}

tecknophreak 02-01-2011 07:32 AM

No and yes, depending on how you open your connection, which was not shown. I'm assuming that you have opened it as blocking, as this is the default action. You are not showing any of your output, which would help identify what the problem is. You can take the line:

printf("error while receiving: error %d",recv_len);

and change it to either

perror("Error while receiving);
or
printf("error while receiving: error %s", strerror(errno));

Then check the error against the possible return values for recv, which can be seen in the man page for recv. Usually the error string shown will shed light on what issue your program is having.

dwhitney67 02-01-2011 07:45 AM

I would also recommend re-coding this section:
Code:

recv_len = 0;
do{
recv_len += recv(sockId, &Rx_buffer[recv_len], 8, 0);
}while((recv_len>0) && (recv_len < 8));

Try something like:
Code:

#define MSG_SIZE 8
...

recv_len = 0

do
{
  ssize_t rtn = recv(sockId, Rx_buffer + recv_len, MSG_SIZE - recv_len, 0);

  if (rtn > 0)
  {
    recv_len += rtn;  /* only increment recv_len when you know that you have valid data! */
  }
  else if (rtn == 0)
  {
      /* peer disconnected */
      break;
  }
  else
  {
      if (errno != EAGAIN && errno != EINTR)  /* decide if you want to check for EINTR (interrupt) */
      {
        perror("Error with socket!");
      }
  }
} while (recv_len < MSG_SIZE);


manohar 02-01-2011 11:32 PM

Hi tecknophreak,

I changed the code as per your suggestion. Iam getting the following error
error while receiving: error Interrupted system call

manohar 02-01-2011 11:37 PM

This is the code iam using, tell me recv() is the blocking/non-blocking function
sockId = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sockId < 0) {
printf("Failed to crete listen socket\n");
return NULL;
}

lSockAddr.sin_family = AF_INET;
lSockAddr.sin_port = htons(params->sock_port);
lSockAddr.sin_addr.s_addr = INADDR_ANY;
while(connect(sockId, (struct sockaddr_in *)&lSockAddr,
sizeof(lSockAddr)) != 0) {
/* try to connect always*/
printf("Failed to connect on port =%d", sock_port);
sleep(1);
}
while(1) {
recv_len = 0;
do{
recv_len += recv(sockId, &Rx_buffer[recv_len], 8, 0);
}while((recv_len>0) && (recv_len < 8));
if(recv_len < 0) {
printf("error while receiving: error %d",recv_len);
}else if(recv_len == 0) {
close(sockId);
}else {
printf("Received data");
}
}

manohar 02-01-2011 11:40 PM

In man pages i found "EINTR The receive was interrupted by delivery of a signal before any data were availabl". what is this exactly means...?

dwhitney67 02-02-2011 03:46 AM

Earlier, I provided a suggestion on how to fix the following section of code; I suggest you employ it. You cannot update 'recv_len' as you have below -- you must check for the return value from recv() before you do that.
Code:

while(1) {
recv_len = 0;
do{
recv_len += recv(sockId, &Rx_buffer[recv_len], 8, 0);
}while((recv_len>0) && (recv_len < 8));
if(recv_len < 0) {
printf("error while receiving: error %d",recv_len);
}else if(recv_len == 0) {
close(sockId);
}else {
printf("Received data");
}
}

As for the EINTR, it could (and probably is) caused by a signal interrupt to your application. I suspect that there is more to your application than you are showing here on the forum.


All times are GMT -5. The time now is 03:31 PM.