【问题标题】:C++ Win32 socketsC++ Win32 套接字
【发布时间】:2025-12-04 17:05:01
【问题描述】:

我有一个带有多线程客户端应用程序的工作套接字控制台服务器。我只创建了控制台或 OpenGL 应用程序。所以一个windows应用是新的。

我正在将我的 stocket 服务器代码移植到 Win32 API 应用程序,但遇到了一些麻烦。服务器运行,客户端正确连接和通信,但服务器窗口冻结。

从我的屏幕截图中,您可以看到我的服务器消息正在输出到我的文本框中。但是在到达 msg 循环时,应用程序会冻结。

我已经从

更新了我的消息循环
while (GetMessage(&msg, NULL, 0, 0))
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);
}

boolean running = TRUE;

while (running) {
    if (PeekMessage(&sys.msg, NULL, 0, 0, PM_REMOVE)) {
        if (sys.msg.message == WM_QUIT)
        {
            running = FALSE;
            //exitCode = msg.wParam;
            break;
        }
        TranslateMessage(&sys.msg);
        DispatchMessage(&sys.msg);
    }

    try {
        pseucode_socket_checking();
    }
    catch (std::exception& e) {
        running = FALSE;
    }
}


pseucode_socket_checking() {
    SOCKET incoming = INVALID_SOCKET;
    incoming = accept(server_socket, NULL, NULL);

    if (incoming == INVALID_SOCKET) return;

    ...

    // create thread for socket.
}

【问题讨论】:

  • 使用异步套接字api和AcceptEx
  • @RbMm 您的偏好是异步还是线程?我的背景是 PHP,所以需要一段时间才能再次适应严格的 c。
  • 我的选择当然是异步 i/o。但对你来说这可能很难

标签: c++ visual-studio winapi


【解决方案1】:

accept() 是一个阻塞函数,它一直等到建立连接。 建议:将您的 accept() 循环放在一个线程中。

Windows 需要解除阻塞消息循环。当有东西卡住它时(如accept()),应用程序将冻结。所以,让消息循环不受任何阻塞。

【讨论】:

  • 嗯,这很有道理。我试图避免创建一个线程来监听连接,因为它是一个旨在监听连接的应用程序。
  • 我是否错过了检查连接是否正在等待的功能,或者线程是执行此操作的唯一/最佳方法?
  • 有 select() 但你必须循环调用它。还有一个 WSAAsyncSelect,当连接准备好时,它会向你的窗口发送一条消息——实际上,它的作用与线程一样,这是最简单的方法。一个建议:开始看看 Windows 是如何工作的,它与 Unix 完全不同。
  • WSAAsyncSelect() 是如果您想直接在 UI 中合并非阻塞套接字操作的正确方法。否则,改为在后台执行操作,使用单独的线程、重叠 I/O、I/O 完成端口等。
  • 谢谢大家,我现在将所有套接字代码放入线程中。经过更多研究后,我可能会在以后将其重写为异步。