C语言 c udp 非阻塞套接字与 recvfrom 和选择

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25340366/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 11:16:25  来源:igfitidea点击:

c udp non-blocking socket with recvfrom and select

csocketsudp

提问by user3852803

I want to implement at the client side non-blocking socket with select function. But it doesn't work as expected. In the code below it never runs into else , rv is always 1 and when nothing is on the socket application stops for a while and continue when another messages is on the socket. I don't want that behavior , I want that client sends back message to the server when there is nothing on the socket to recvfrom.

我想在客户端使用 select 函数实现非阻塞套接字。但它没有按预期工作。在下面的代码中,它永远不会遇到 else , rv 始终为 1 并且当套接字上没有任何内容时,应用程序会停止一段时间并在套接字上有另一条消息时继续。我不想要这种行为,我希望客户端在套接字上没有任何要接收的内容时将消息发送回服务器。

fd_set readfds; 

fcntl(sd, F_SETFL, O_NONBLOCK); 


while (1) {

        FD_ZERO(&readfds);
        FD_SET(sd, &readfds);

        rv = select(sd + 1, &readfds, NULL, NULL, NULL); 

        if(rv == 1){ 

            nbytes = recvfrom(sd, buf, RW_SIZE, 0, (struct sockaddr *) &srv_addr, &addrlen); 


        } else {

            printf("I'm never here so I can't send message back to the server!\n");


        }

}

with struct timeval:

使用结构 timeval:

fd_set readfds; 
fcntl(sd, F_SETFL, O_NONBLOCK); 
struct timeval tv;


while (1) {

        FD_ZERO(&readfds);
        FD_SET(sd, &readfds);

        tv.tv_sec = 0;
        tv.tv_usec = 0;

        rv = select(sd + 1, &readfds, NULL, NULL, &tv); 

        if(rv == 1){ 

            nbytes = recvfrom(sd, buf, RW_SIZE, 0, (struct sockaddr *) &srv_addr, &addrlen); 


        } else {

            printf("I'm always here like now ! \n");


        }

}

采纳答案by Steffen Ullrich

You set the timeout (last parameter of select) to NULL, which means it will only return once data are available on the socket (or interrupt). You need to set a timeout it should wait. The timeout might be 0 if you don't want to wait, but 0 means to use a struct timeval*with tv_sec=0and tv_usec=0and not use a struct timeval*of NULL like you did.

您将超时(select 的最后一个参数)设置为 NULL,这意味着它只会在套接字(或中断)上的数据可用时返回。您需要设置它应该等待的超时时间。如果您不想等待,超时可能为 0,但 0 表示使用struct timeval*withtv_sec=0tv_usec=0而不是struct timeval*像您那样使用NULL 。