2013-05-12 117 views
0

這裏是我正在使用的代碼。每當我向Stdin寫入內容時,它都能正常工作,但它不適用於套接字。它無法進入Socket的循環。我是socket編程的新手。套接字不工作的文件描述符

void HandleConnection(int socket) 
{ 
    fd_set rfd; 
    struct timeval tv; 
    int retval; 

    printf("%d",socket); 
    MakeNonBlocking(socket); 

    /* Watch stdin (fd 0) to see when it has input. */ 
    FD_ZERO(&rfd); 

    while(1) 
    { 
    FD_SET(STDIN, &rfd); 
    FD_SET(socket, &rfd); 

    /* Wait up to five seconds. */ 
    tv.tv_sec = 50; 
    tv.tv_usec = 0; 

    retval = select(2, &rfd,NULL, NULL, &tv); 
    if(retval == 0) 
    { 
     printf("No data within fifty seconds.\n"); 
     exit(1); 
    } 
    if(FD_ISSET(socket,&rfd)) 
    { 
     printf("socket wala\n"); 
     recieve_message(&socket); 
     send_message(&socket); 
    } 
    if(FD_ISSET(STDIN,&rfd)) 
    { 
     printf("stdin wala\n"); 
     recieve_message(&socket); 
     send_message(&socket); 
    } 
    } 
} 
+0

您需要在循環內放置'FD_ZERO(&rfd)'。你需要正確地將第一個參數設置爲'select()',2可能不是正確的值,它應該是'max(STDIN,socket)+ 1'。 – Barmar 2013-05-12 10:52:07

回答

1
  1. FDZERO必須FDSET前走循環
  2. 選擇內(2,...)應選擇(最高文件描述符+1,...)。
  3. 當選擇返回時,您應該檢查負值以防出現錯誤
  4. 您應該考慮使用pselect而不是select。
  5. 重新初始化之前清除電視。
+0

謝謝!它的工作......我認爲「2」是我給的文件描述符的數量。 :) – 2013-05-12 16:47:27

+0

我在手冊頁中添加了一段引語給我的回答,我認爲它應該爲您澄清這一點。 – Barmar 2013-05-12 16:57:47

1

看來,你不明白是怎麼nfds參數select()使用。手冊頁明確說明了這一點:

在每個集合中檢查第一個nfds 描述符;即描述符集合中從0到nfds-1的描述符被檢查。 (例如: 如果設置兩個文件描述符 「4」 和 「17」,NFDs的不應該是 「2」,而是 「17 + 1」 或 「18」。)

因此,這裏是如何你應該重寫你的代碼。

int maxfd = (socket > STDIN ? socket : STDIN) + 1; /* select() requires the number of FDs to scan, which is max(fds)+1 */ 

while(1){ 

    FD_ZERO(&rfd); /* This needs to be done each time through the loop */ 
    /* Watch stdin (fd 0) to see when it has input. */ 
    FD_SET(STDIN, &rfd); 
    FD_SET(socket, &rfd); 

    /* Wait up to five seconds. */ 
    tv.tv_sec = 50; 
    tv.tv_usec = 0; 

    retval = select(maxfd, &rfd,NULL, NULL, &tv); 
    if(retval == 0) 
    { 
     printf("No data within fifty seconds.\n"); 
     exit(1); 
    } 
    if(retval == -1) /* Check for error */ 
    { 
     perror("Error from select"); 
     exit(2); 
    } 
    if(FD_ISSET(socket,&rfd)) 
    { 
     printf("socket wala\n"); 
     recieve_message(&socket); 
     send_message(&socket); 
    } 
    if(FD_ISSET(STDIN,&rfd)) 
    { 
     printf("stdin wala\n"); 
     recieve_message(&socket); 
     send_message(&socket); 
    } 

} 
+0

單純的代碼不是答案。你需要說明原因。 – EJP 2013-05-12 11:46:33

+0

@EJP我在更改旁添加了註釋 – Barmar 2013-05-12 12:33:33

+0

再次感謝您對代碼進行更改。 :) – 2013-05-12 16:47:51

相關問題