2012-09-15 25 views
0

我試圖寫一個服務器 - 客戶端代碼,並且我被困在一個點上。我希望客戶端讀取一定的時間和超時時間。我嘗試使用setsockopt()與SO_RCVTIMEO指定timeval結構中的時間,但我的read()不等待我在timeval結構中指定的時間。 事情是,如果我在setsockopt()之後使用read(),read()正在等待指定的時間。如果我首先調用write()然後read(),那麼read()函數會立即超時,而不會等待timeval struct中給出的指定時間。 我的代碼如下所示:在C中使用setsockopt()讀取()

//樣本客戶機代碼

#include<stdio.h> 
    #include<sys/types.h> 
    #include<sys/socket.h> 
    #include<netinet/in.h> 
    #include<netdb.h> 


    void error(char *msg) 
    { 
     perror(msg); 
     exit(1); 
    } 

    int main(int argc, char *argv[]) 
    { 
     int a=1; 
     fd_set readfds,writefds; 
     int ready_for_reading,reading; 
     struct timeval time_out; 

     int sockfd,newsockfd,portno,n; 
     struct sockaddr_in serv_addr; 
     struct hostent *server; 
    // server=gethostbyname(argv[1]); 
     char buffer[256]; 
     portno=atoi(argv[2]); 
     sockfd=socket(AF_INET,SOCK_STREAM,0); 
     server=gethostbyname(argv[1]); 
     serv_addr.sin_family=AF_INET; 
     serv_addr.sin_port=htons(portno); 
     bcopy((char *)server->h_addr, 
      (char *)&serv_addr.sin_addr.s_addr, 
      server->h_length); 
     time_out.tv_sec = 15; // 15 seconds 
      time_out.tv_usec = 0; // 0 milliseconds 

    // sockfd=socket(AF_INET,SOCK_STREAM,0); 
     if(sockfd==-1) 
      error("\nError creating socket"); 
    //  if(setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&time_out, sizeof (time_out))) 
    //    error("\n\tsetsockopt function has a problem\n"); 

     n=connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)); 
     if(n==-1) 
      error("\nError connecting to server"); 
     printf("\nEnter client's msg:"); 
     fgets(buffer,255,stdin); 
     n=write(sockfd,buffer,strlen(buffer)); 
     if(n<0) 
      error("\nMsg not written to server"); 
     if(setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&time_out, sizeof(time_out))) 
      error("\n\tsetsockopt function has a problem\n"); 

    // FD_ZERO(&readfds); 
    // FD_SET(sockfd,&readfds); 

     n=read(sockfd,buffer,255); 
    // ready_for_reading=select(sockfd,&readfds,NULL,NULL,&time_out); 
    // printf("\nready_for_reading=%d",ready_for_reading); 
    /* if (ready_for_reading) 
      { 
       // reading = read(newsockfd, buffer, 255); 
       printf("Read, %d bytes from input : %s \n", n,buffer); 
      } 
      else 
      { 
       printf(" 10 Seconds are over - no data input \n"); 
       return 0; 
      } 
    */ 
     if(n<0) 
      printf("\nMsg not read from server"); 
     if(n==0) 
     { 
      printf("\n No ack from server"); 
      return 0; 
     } 
     printf("\nServer's ack:%s\n",buffer); 

    /* if (ready_for_reading) 
     { 
      // reading = read(newsockfd, buffer, 255); 
       printf("Read, %d bytes from input : %s \n", n,buffer); 
      } 
     else 
     { 
        printf(" 10 Seconds are over - no data input \n"); 
      return 0; 
      } 
    */ 
     return 0; 
    } 

在我的代碼以上,我想讀()操作來在15secs超時。但它立即超時。我需要幫助!!!

+0

閱讀是否返回負值? –

+0

no .. read()返回'0',我猜的意思是'0'字節讀取... – Richard

+0

你檢查過'setsockop''errno'設置後嗎? –

回答

1

如果read返回零,表示連接已關閉。沒有什麼可以等待的,所以它不能等待。

此外,該代碼被打破:

printf("\nServer's ack:%s\n",buffer); 

您只能使用%s格式說明打印C風格的字符串。您使用它的方式,無法知道要打印多少個字節,因爲在您的代碼中此處只保存在變量n中。

+0

ohk ..非常感謝大衛指出了..我正在關閉服務器端的連接..現在它的工作.. :) – Richard

+0

@Richard:確保修復其他錯誤,否則它只是運氣好運。 –