【问题标题】:c udp non-blocking socket with recvfrom and selectc udp 非阻塞套接字,带有 recvfrom 和 select
【发布时间】:2014-08-16 12:55:19
【问题描述】:

我想在客户端实现带有选择功能的非阻塞套接字。但它没有按预期工作。在下面的代码中,它永远不会遇到 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");


        }

}

使用 struct 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");


        }

}

【问题讨论】:

  • 您是否在检查fcntl 调用是否成功并且您的系统中是否有O_NONBLOCK 可用?
  • 是的,我检查了 fcntl 是否返回 -1 而不是,它返回 0

标签: c sockets udp


【解决方案1】:

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

【讨论】:

  • 我已经更改了最后一个参数并设置了 &tv 而不是 NULL,我之前设置了 tv_sec=0 和 tv_usec=0 但在这种情况下 select 总是返回 0,我怎么知道我什么时候有要读取的套接字?现在它总是进入它永远不会从服务器接收到的 else
  • 因为您将超时设置为 0(即不等待),如果您一直在打印没有数据,您最终会陷入一种忙碌的循环。您最终应该不时收到rv==1,但由于您的超时时间为零,所有案例中的 99.999% 都将一事无成。我不确定你想用这个设计实现什么。通常使用带有选择和非阻塞的设置来管理多个套接字或等待具有合理(非零)超时的数据。
  • 服务器正在向客户端发送带有序列号的数据包。我希望在客户端检测数据包何时丢失以及使用序列号丢失了哪个数据包。但显然,当套接字上没有任何内容时,这并不意味着数据包丢失。您知道如何检测丢失的数据包吗?
  • 要知道数据包是否丢失,您必须知道有数据包发送。如果发送方每秒发送一个数据包,如果您在 2 秒后没有收到它,您可能会认为该数据包丢失。如果您不知道何时发送数据包,则只有在您收到较晚的数据包时才能检测到它的丢失(但数据包可能以不同的顺序到达)。你可以看看处理所有这些问题的 TCP 的设计。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-04
  • 1970-01-01
  • 2011-09-13
  • 1970-01-01
  • 2011-09-12
相关资源
最近更新 更多