WSAAsyncSelect Model
The WSAAsyncSelect model allows applications to receive network event notifications from Windows messages. This model is set to adapt to the Windows Message Drive environment. Currently, many network applications with low performance requirements use the WSAAsyncSelect model, and the CSocket class in MFC also uses it.
The WSAAsyncSelect function automatically sets the socket to non-blocking mode, binds a window handle to the socket, and sends notifications such as FD_READ ). When a network event occurs, a program-defined message is sent to the window.
Specific Programming process:
1. Customize a network notification message to notify the window in the WSAsyncSelect binding.
2. Create a window for binding WSAAsyncSelect to the specified socket.
3. Compile the message processing functions in the preceding window. After receiving a custom network notification message, extract the corresponding error code and network events (FD_ACCEPT,
FD_READ, FD_WRIET, and FD_CLOSE) and handle the issue accordingly.
# Define _ WIN32_WINNT 0x0400 # include <windows. h> # include <cstdio> # include "InitSocket. h "// You Need to customize a message # define WM_SOCKET WM_USER + 1 CInitSock initSock; // initialize long callback WindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); int main (void) {char szClassName [] = "MainWClass"; WNDCLASSEX wndclass; wndclass. cbSize = sizeof (wndclass); wndclass. style = CS_HREDRAW | CS_VREDRAW; wndclass. lpfnWnd Proc = WindowProc; wndclass. cbClsExtra = 0; wndclass. cbWndExtra = 0; wndclass. hInstance = NULL; wndclass. hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass. hCursor = LoadCursor (NULL, IDC_ARROW); wndclass. hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass. lpszMenuName = NULL; wndclass. lpszClassName = szClassName; wndclass. hIconSm = NULL; RegisterClassEx (& wndclass); // Create the main window HWND hWnd = Create Export Wex (0, szClassName, "", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, NULL); if (NULL = hWnd) {MessageBox (NULL, "An error occurred while creating the window! "," Error ", MB_ OK); return-1;} USHORT nPort = 4567; SOCKET sListen = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); sockaddr_in sin; sin. sin_family = AF_INET; sin. sin_port = htons (nPort); sin. sin_addr.s_addr = INADDR_ANY; if (bind (sListen, (sockaddr *) & sin, sizeof (sin) = SOCKET_ERROR) {printf ("Failed bind () \ n "); return-1;} // set the socket to the window notification message type. The socket is automatically set to the non-blocking mode WSAAsyncSelect (sListen, hWnd, WM_SOCKET, FD_ACCEPT | FD_CLOSE); listen (sListen, 5); MSG msg; while (GetMessage (& msg, NULL, 0, 0) {TranslateMessage (& msg); DispatchMessage (& msg);} return msg. wParam;} long callback WindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {switch (uMsg) {case WM_SOCKET: {SOCKET s = wParam; if (WSAGETSELECTERROR (lParam) {closesocket (s); return 0;} switch (WSAGETSELECTEVENT (lParam) {case FD_ACCEPT: {SOCKET client = accept (s, NULL, NULL); WSAAsyncSelect (client, hWnd, WM_SOCKET, FD_READ | FD_WRITE | FD_CLOSE); printf ("receive a connection \ n");} break; case FD_WRITE: break; case FD_READ: {char szText [1024] = {0}; if (recv (s, szText,) = SOCKET_ERROR) {closesocket (s);} else {printf ("receive data: % s ", szText) ;}break;} case FD_CLOSE: {printf (" close a connection \ n "); closesocket (s) ;}break;} return 0 ;} case WM_DESTROY: PostQuitMessage (0); return 0 ;}// send the unprocessed message to the system for default processing. return DefWindowProc (hWnd, uMsg, wParam, lParam );}