FD_ACCEPT如何接受多线程的连接请求?
how to accept multi thread's connection request in FD_ACCEPT?
如果我有n个客户端连接服务器,如何在FD_ACCEPT中接受它,如何在FD_READ中接收它,如何在FD_WRITE中发送它,而不是像这样使用[=12] =]
e.p。
而(1){
ClientSocket=接受(ListenSocket,0,0);
如果(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;
或者这种形式只能处理一个客户端连接?
有必要以这种形式进行吗?
我想将它用于一个简单的聊天应用程序
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;
}
如果我有n个客户端连接服务器,如何在FD_ACCEPT中接受它,如何在FD_READ中接收它,如何在FD_WRITE中发送它,而不是像这样使用[=12] =]
e.p。
而(1){ ClientSocket=接受(ListenSocket,0,0); 如果(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;
或者这种形式只能处理一个客户端连接? 有必要以这种形式进行吗? 我想将它用于一个简单的聊天应用程序
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;
}