【问题标题】:Maintain window motion and close actions while socket recv is blocking awaiting data?在套接字接收阻塞等待数据时保持窗口运动和关闭操作?
【发布时间】:2020-12-01 14:47:27
【问题描述】:

我有一个生成 SDL_window 的 SDL2 c++ 程序,同时还使用了一个通过 recv 接收数据的套接字服务器。我注意到,每当 recv 阻塞并期待数据时,SDL 窗口操作(例如用鼠标移动窗口,或通过单击角按钮最小化和关闭窗口)都会被禁用。当然,我希望程序功能在 recv 阻塞时被冻结,但我对窗口运动也被冻结感到惊讶,因为我希望这将由操作系统并行处理。有什么办法可以在 recv 阻塞时保留 SDL_window 运动吗?

编辑:

就代码而言,窗口是通过调用来创建的

gWindow = SDL_CreateWindow("Program", 0, 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 阻塞时禁用此功能是有道理的。我只是想知道是否可以添加一个额外的层来让操作系统接管这个任务,这根本不会出现在我的代码中。

【问题讨论】:

  • 展示代码而不是冗长地谈论问题真的很有帮助。我们可以用正确的代码重现问题,但我们不能用这个。
  • 您描述的UI窗口操作仍然需要消息处理。因此,您需要将套接字操作移至单独的工作线程,或者使用非阻塞套接字。无论哪种方式都不会阻止您的 UI 线程处理来自操作系统的 UI 消息。
  • 这里有一些有用的选项:stackoverflow.com/questions/47146174/…

标签: c++ windows sockets visual-studio-2017 sdl-2


【解决方案1】:

事实证明,我的问题的解决方案只是在 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

【讨论】:

  • 很高兴您得到了解决方案,感谢您的分享,如果您将它们标记为答案,我将不胜感激,这将对其他社区有益。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-30
  • 1970-01-01
  • 2014-11-01
  • 1970-01-01
  • 2010-12-30
  • 1970-01-01
相关资源
最近更新 更多