【问题标题】:how to accept multi thread's connection request in FD_ACCEPT?FD_ACCEPT如何接受多线程的连接请求?
【发布时间】:2015-03-20 12:23:28
【问题描述】:

如果我有 n 个客户端连接服务器,如何在 FD_ACCEPT 中接受它以及如何在 FD_READ 中接收它以及如何在 FD_WRITE 中发送它而不像这种形式使用

e.p.

而(1){ ClientSocket=accept(ListenSocket,0,0); if(ClientSocket!=INVALID_SOCKET) _beginthreadex(); }

如何以这种形式实现

case WM_SERVER_SOCKET:
    wEvent = WSAGETSELECTEVENT(lParam);//LOWORD
    switch (wEvent) {
    case FD_ACCEPT:
        ClientSocket=accept(ListenSocket, nullptr, nullptr);
        break;
    case FD_READ:

        break;
    case FD_WRITE:

        break;
    case FD_CLOSE:

        break;
    }
    break;

或者这种形式只能处理一个客户端连接? 有必要以这种形式做吗? 我想将它用于一个简单的聊天应用程序

【问题讨论】:

  • 你的意思是我不应该这样做吗?我以前认为它不需要创建更多线程,希望它有一些方法来自动处理多客户端消息

标签: c multithreading sockets winapi chat


【解决方案1】:

WSAAsyncSelect() 就是你要找的,例如:

WNDCLASS cls = {0};
cls.lpfnWndProc = &SocketWndProc;
cls.hInstance = ...;
cls.lpszClassName = TEXT("MySocketWnd");

RegisterClass(&cls);

HWND hWnd = CreateWindowEx(0, cls.lpszClassName, nullptr, 0, 0, 0, 0, 0, HWND_MESSAGE, nullptr, cls.hInstance, nullptr);

SOCKET ListenSocket = socket(...);
bind(ListenSocket, ...);
listen(ListenSocket, ...);

WSAAsyncSelect(ListenSocket, hWnd, WM_SERVER_SOCKET, FD_ACCEPT | FD_READ | FD_WRITE | FD_CLOSE);

MSG msg;
while (GetMessage(&msg, nullptr, 0, 0) > 0)
{
    TranslateMessage(&msg);
    DispatchMessage(&msg);       
}

closesocket(ListenSocket);
DestroyWindow(hWnd);

LRESULT CALLBACK SocketWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if (uMsg != WM_SERVER_SOCKET)
        return DefWindowProc(hWnd, uMsg, wParam, lParam);

    SOCKET sckt = (SOCKET) wParam;
    WORD wEvent = WSAGETSELECTEVENT(lParam);
    WORD wError = WSAGETSELECTERROR(lParam);

    if (wError != 0)
    {
        // wEvent on sckt failed, do something ...
        return 0;
    }

    switch (wEvent)
    {
        case FD_ACCEPT:
        {
            // sckt has a pending client...
            SOCKET ClientSocket = accept(sckt,...);
            // do something with new client (add it to a tracking list, etc) ...
            break;
        }

        case FD_READ:
        {
            // sckt has pending data...
            int numBytes = recv(sckt, ...);
            // process data as needed...
            break;
        }

        case FD_WRITE:
        {
            // sckt can receive data, send any pending data ...
            break;
        }

        case FD_CLOSE:
        {
            // sckt has disconnected, do something (remove it from list, etc)...
            break;
        }
    }

    return 0;
}

【讨论】:

  • int numBytes = recv(sckt, ...); - -,sckt 将是ClientSocket 吗?以及如何发送给客户端,保存ClientSocket然后SendMessage()?发送都类似吗?
  • FD_ACCEPT 事件中,提供的套接字将是监听套接字。在所有其他事件中,提供的套接字将是接受的客户端套接字之一,是的。
猜你喜欢
  • 2019-11-10
  • 2013-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-22
  • 2019-09-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多