Click here to Skip to main content
15,887,464 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
some time recv case wait forever how can handle this
C++
int TCPClient::Read(char* data,int len ,int timeout , char * delem,int delm_len,int &r)
{
 int l;
     timeval t_out;

         fd_set set;
   
      if(timeout>10)
       t_out.tv_sec = 5;
      else 
      t_out.tv_sec = timeout;

       t_out.tv_usec = 0;
       FD_ZERO(&set);   
       FD_SET(Socket,&set);
      
        l = select(Socket +1, &set, NULL, NULL, &t_out);
      
         setsockopt(Socket,SOL_SOCKET|SO_LINGER,TCP_NODELAY|SO_RCVTIMEO,(char*)&t_out,sizeof(struct timeval));

       if(l==0)
         {
          printf("\n time out %i \n",timeout);
          return -10;
         }
       
         else if(len<0)
          {
         printf("\n error in select 2 TCPClient \n");
       
           return -5;
          }
         
     char a[1] = {0};
    
       memset(data,0,sizeof(data));
      // strcpy(data," ");   
     ssize_t l1;
     int i = 0;
     int cycle = 0;
     while(true)
     {
     
          l1 = recv(Socket,a,1,0);
          if(l1==0)
          {
          printf("\n closed \n");
          i = 0;
            break;
          }
          data =  stpcpy(data,a);
          if(l1 == -1)
          {
            if(r==5 &&cycle<5)
             {
                sleep(3);
                printf("wait");
                cycle++;
                    continue;
             }
             
            break;
          }
          i +=l1;
         
          if(delm_len>1 && strstr(data,delem)!=NULL)
          {
            printf("\n hit strstr \n  ");
            break;
          }
            else if(delm_len==1 && delem[0]==a[0])
            { 
            r = 1;
                break;
            }
            if(i>=len && r==1)
            break;
            
      }//while(i< len) ;    
       printf("\n data recv %i  r = %i ",i,r);
       printf("\n block data return %s \n",data);
      

	return i; 
}
Posted
Comments
Sergey Alexandrovich Kryukov 9-Mar-15 9:08am    
Why not "waiting forever"? Maybe the remote part supposed to write does not write expected amount of data in your test...
—SA
Mahmoud_Gamal 9-Mar-15 11:12am    
OK IF THIS CASE YOU SAY OCCUR HOW TO OVERCOME ALSO
DUE TO THIS SERVER MAY BE WRITE TRUE TO IT BUT NOT RESPONSE SO I WANT TO SOLVE WAITING
Sergey Alexandrovich Kryukov 9-Mar-15 12:31pm    
Please don't shout. (ALL CAPS are considered as shouting on the Web, not very polite.)

How to overcome? Develop client and server parts together. If your code is application-specific, you need to form the exchange as some application-specific protocol you better explicitly describe as such. One of the parts can fail by one or another reason, handling it is the complex problem. You need to detect such cases as early as possible. Under TCP, you can easily detect the socket as disconnected of, say, the host is turned off in the middle or application is non-gracefully closed. In other cases, you can deal with timeouts...
—SA
Mahmoud_Gamal 10-Mar-15 5:44am    
iam so sorry but i write quickly and capslock open :D

1 solution

From Linux man page for select[^]:
Under Linux, select() may report a socket file descriptor as "ready for reading", while nevertheless a subsequent read blocks. This could for example happen when data has arrived but upon examination has wrong checksum and is discarded. There may be other circumstances in which a file descriptor is spuriously reported as ready. Thus it may be safer to use O_NONBLOCK on sockets that should not block.

You have to follow the advice and use non blocking read even if using select.
 
Share this answer
 
Comments
Mahmoud_Gamal 10-Mar-15 6:13am    
O_NONBLOCK not recognize on AIX7.1 i use FIBNREAD
Frankie-C 10-Mar-15 7:32am    
I've no direct experience on AIX, but the command for not blocking sockets should be FIBNREAD.
I wondered that another reason for select to signal data when it is not present could be the presence of Out-Of-Band data. On some systems it is possible to set socket to ignore OOB data, or you can try to intercept the SIGURG signal.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900