2013-05-12 85 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

相关问题