问题描述
我有一个生成SDL_window的SDL2 c ++程序,同时还使用了一个通过recv接收数据的套接字服务器。我注意到,每当recv阻止并期望数据时,SDL窗口操作(例如,用鼠标移动窗口或通过单击角按钮来最小化和关闭窗口)都会被禁用。当然,我希望在recv被阻止时冻结程序功能,但是我也对窗口运动也被冻结感到惊讶,因为我希望这将由OS并行处理。在recv阻止时我还能做些什么来保持SDL_window的运动?
编辑:
就代码而言,该窗口是通过调用
创建的gWindow = SDL_CreateWindow("Program",55,SCREEN_WIDTH,SCREEN_HEIGHT,SDL_WINDOW_SHOWN | SDL_WINDOW_ALWAYS_ON_TOP);
在SDL初始化调用中。该程序循环运行,并且有一个SDL事件处理程序
SDL_Event e;
用于捕获例如单击以关闭窗口
while (SDL_PollEvent(&e) != 0)
{
//User requests quit
if (e.type == SDL_QUIT)
{
quit = true;
}
}
我认为在recv阻止时禁用此功能是有道理的。我只是想知道是否可以添加一个额外的层来让操作系统接管这项任务,而这根本不在我的代码中。
解决方法
结果是,解决我的问题的方法只是向recv添加100毫秒的超时时间
DWORD timeout = 100;// millisecond timeout for receiving data
setsockopt(ClientSocket,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout));
然后,如果没有收到任何数据,我将跳过此周期中期望非平凡数据的代码部分
iResult = recv(ClientSocket,recvbuf,recvbuflen,0);
if (iResult == SOCKET_ERROR)
{
if (WSAGetLastError() == WSAETIMEDOUT) {
goto SKIP;
}
}
现在recv不会无限期地阻塞,并且所有窗口功能对于人类(其反应时间约为200毫秒)都保持不变。
请注意,这特定于Windows系统。有关其他系统上的类似解决方案,请参见this thread。