5

我正在编写一个程序,它接收 UDP 消息并从用户那里获取输入,但是我的 STDIN 仍然被 select 阻塞。当我 FD_CLR 选择程序之前的 stdin fd 运行良好时,表明 stdin 套接字始终准备好从中读取数据。我尝试引入 timeval tv 以将其超时,但这似乎也不起作用。我应该在某处关闭套接字还是在我不在的地方调用 FD_CLR?最终结果应该是一个非阻塞的 STDIN,但目前它是阻塞的。谢谢你

int
wait_for_input(){
            fd_set fds;
            int maxfd, sd, err, n;
            struct sockaddr_in addr;
            char stdbuf[BUFLEN];
            unsigned char udpbuf[BUFLEN];

            //memset(stdbuf,0x0,sizeof(stdbuf));
            memset(stdbuf,0x0,sizeof(udpbuf));

            sd = socket(AF_INET, SOCK_DGRAM, 0);

            if(sd<0) {
            printf("Failed to Open UDP socket");
            }

            addr.sin_family = AF_INET;
            addr.sin_addr.s_addr = htonl(INADDR_ANY);
            addr.sin_port = htons(host_list[0]->port);
            err = bind(sd,(struct sockaddr *) &addr,sizeof(addr));

            if(err < 0){
                            printf("ERROR: Cant bind port");

            }

                            struct timeval tv;
            while(1){
                            FD_ZERO(&fds);
                            FD_SET(STDIN_FILENO,&fds);
                            FD_SET(sd,&fds);
                            tv.tv_sec = 1;
                            tv.tv_usec = 0;
                            fflush(stdout);
                            select(sd+1,&fds,NULL,NULL,&tv);

                            // If a UDP message arrives
                            if(FD_ISSET(sd,&fds)){
                                            n = recv(sd,udpbuf,sizeof(udpbuf),0);
                                            unpack(udpbuf);
                                            recompute_my_dv();
                                            fflush(stdout);

                             }
                            //If console data is entered.
                                if(FD_ISSET(STDIN_FILENO, &fds)){
                                            fgets(stdbuf,sizeof(stdbuf),stdin);
                                            parse(stdbuf);
                                            printf("server> ");
                                            fflush(stdout);
                                            FD_CLR(STDIN_FILENO,&fds);


                             }

                     }



 return 0;
 }
4

1 回答 1

0

如果您在该套接字的缓冲区上有消息,FD_ISSET 不会返回 1(或 true),如果给定的文件描述符是文件描述符集的一部分,它会返回 true。这是一个问题。

接下来是您的循环应该开始(即 while 循环)应该在 select 语句之前开始并循环返回。您应该捕获选择返回的值。这是因为 select 返回您在 select 的参数 2 中指定的缓冲区中有多少位(读取、写入或错误)。因此,如果您将 read 指定为缓冲区,您将需要读取 select 返回了多少位。

我认为这是两个主要问题。希望这可以帮助。

于 2013-05-10T14:01:12.153 回答