C++ 如何退出 while 循环 recvfrom()

标签 c++ sockets while-loop

我正在尝试创建一个 UDP 广播程序来检查本地游戏服务器,但我在接收端遇到了一些问题。由于始终不知道有多少服务器处于事件状态,因此您必须有一个只有在停止时才会退出的循环。所以在这段代码中:

while(1) // start a while loop
       {
     if(recvfrom(sd,buff,BUFFSZ,0,(struct sockaddr *)&peer,&psz) < 0) // recvfrom() function call
        {
            cout << red << "Fatal: Failed to receive data" << white << endl;
            return;
        }
     else
     {
            cout << green << "Found Server :: " << white;
            cout << yellow << inet_ntoa(peer.sin_addr), htons(peer.sin_port);
            cout << endl;
   }
       }

我希望运行此 recvfrom() 函数,直到我按下 Ctrl + C。我已经尝试设置处理程序等(来自相关问题),但它们对我来说都太复杂了,或者它是一个简单的函数只是作为演示退出程序。这是我的问题: 该程序卡在 recvfrom 上,直到它收到连接(我的猜测),因此,它永远没有机会专门等待输入。我如何设置一个可以很好地解决这个问题的事件?

谢谢!

最佳答案

在 CTRL-C 处理程序中,设置一个标志,并将该标志用作 while 循环中的条件。

哦,如果你不是在系统调用可以被信号中断的 POSIX 系统上,你可能想要使套接字成为非阻塞的并使用例如选择(超时时间短)以轮询数据。


Windows 的这种方案存在一些问题。主要问题是函数调用不能被 CTRL-C 处理程序中断。相反,您必须轮询循环中是否有任何要接收的内容,同时还要检查“退出循环”标志。

可以这样做:

bool ExitRecvLoop = false;

BOOL CtrlHandler(DWORD type)
{
    if (type == CTRL_C_EVENT)
    {
        ExitRecvLoop = true;
        return TRUE;
    }

    return FALSE;  // Call next handler
}

// ...

SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE);

while (!ExitRecvLoop)
{
    fd_set rs;
    FD_ZERO(&rs);
    FD_SET(sd, &rs);

    timeval timeout = { 0, 1000 };  // One millisecond

    if (select(sd + 1, &rs, NULL, NULL, &timeout) < 0)
    {
        // Handle error
    }
    else
    {
        if (FD_ISSET(sd, &rs))
        {
            // Data to receive, call `recvfrom`
        }
    }
}

您可能必须使套接字成为非阻塞的才能工作(请参阅 ioctlsocket 函数了解如何操作)。

关于C++ 如何退出 while 循环 recvfrom(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18119428/

相关文章:

c++ - Visual Studio的以下代码构建没有任何错误?

c - 无法使用 tcpdump 捕获 IP 广播数据包

Java启动while循环而不暂停当前线程

计算字符串中某个单词出现次数的C代码

c++ - 公斤到磅转换器构建错误 (CLion)

c++ - 在类中初始化 vector

c++ - 因为调用RegOpenKeyEx导致一长串依赖关系正常吗?

python - socket.error[Errno 99] 无法分配请求的地址

android - 带有Delphi Android应用程序的Socket

java - 当条件设置为 false 时,While 循环执行最后一次