gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 04:15:51 25 4
gpt4 key购买 nike

我正在尝试创建一个 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com