1 #include <WinSock2.h> 2 #include <Windows.h> 3 #include <StrSafe.h> 4 5 #pragma comment(lib, "Ws2_32") 6 7 #define WM_SOCKET WM_USER+1 8 9 LRESULT CALLBACK WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 10 { 11 switch (uMsg) 12 { 13 case WM_SOCKET: 14 { 15 if (WSAGETSELECTERROR(lParam)) 16 { 17 shutdown(wParam, SD_BOTH); 18 closesocket(wParam); 19 return 0; 20 } 21 22 switch (WSAGETSELECTEVENT(lParam)) 23 { 24 case FD_ACCEPT: 25 { 26 SOCKET client = accept(wParam, NULL, NULL); 27 WSAAsyncSelect(client, hWnd, WM_SOCKET, FD_READ | FD_WRITE | FD_CLOSE); 28 } 29 break; 30 case FD_WRITE: 31 break; 32 case FD_READ: 33 { 34 CHAR szText[1024] = { 0 }; 35 if (SOCKET_ERROR == recv(wParam, szText, 1024, 0)) 36 { 37 shutdown(wParam, SD_BOTH); 38 closesocket(wParam); 39 } 40 else 41 { 42 CHAR szMsg[1100] = "接收数据:"; 43 strcat_s(szMsg, szText); 44 MessageBoxA(hWnd, szMsg, "结果", MB_OK); 45 } 46 } 47 break; 48 case FD_CLOSE: 49 shutdown(wParam, SD_BOTH); 50 closesocket(wParam); 51 break; 52 } 53 } 54 return 0; 55 case WM_DESTROY: 56 PostQuitMessage(0); 57 return 0; 58 default: 59 return DefWindowProc(hWnd, uMsg, wParam, lParam); 60 } 61 return DefWindowProc(hWnd, uMsg, wParam, lParam); 62 } 63 64 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, PSTR pcszCommand, int iShow) 65 { 66 TCHAR szAppName[] = TEXT("WSAAsyncSelect"); 67 WNDCLASSEX wndClsEx; 68 69 wndClsEx.cbClsExtra = 0; 70 wndClsEx.cbSize = sizeof(wndClsEx); 71 wndClsEx.cbWndExtra = 0; 72 wndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 73 wndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW); 74 wndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION); 75 wndClsEx.hIconSm = NULL; 76 wndClsEx.hInstance = hInstance; 77 wndClsEx.lpfnWndProc = WinProc; 78 wndClsEx.lpszClassName = szAppName; 79 wndClsEx.lpszMenuName = NULL; 80 wndClsEx.style = CS_HREDRAW | CS_VREDRAW; 81 82 if (!RegisterClassEx(&wndClsEx)) 83 { 84 MessageBox(NULL, TEXT("注册窗口类失败,本程序需要在Windows NT系统上才能运行。"), TEXT("错误"), MB_OK | MB_ICONERROR); 85 return 0; 86 } 87 88 HWND hWnd = CreateWindowEx( 89 0, 90 szAppName, 91 szAppName, 92 WS_OVERLAPPEDWINDOW, 93 CW_USEDEFAULT, 94 CW_USEDEFAULT, 95 CW_USEDEFAULT, 96 CW_USEDEFAULT, 97 NULL, 98 NULL, 99 hInstance, 100 NULL); 101 if (NULL == hWnd) 102 { 103 MessageBox(NULL, TEXT("创建窗口失败"), TEXT("错误"), MB_OK | MB_ICONERROR); 104 return 0; 105 } 106 107 ShowWindow(hWnd, iShow); 108 UpdateWindow(hWnd); 109 110 WSADATA wsaData; 111 WSAStartup(WINSOCK_VERSION, &wsaData); 112 113 SOCKET sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 114 if (INVALID_SOCKET == sListen) 115 { 116 MessageBox(hWnd, TEXT("创建套接字失败"), TEXT("错误"), MB_OK | MB_ICONERROR); 117 WSACleanup(); 118 return 0; 119 } 120 121 SOCKADDR_IN sin; 122 USHORT uPort = 4567; 123 124 ZeroMemory(&sin, sizeof(sin)); 125 sin.sin_family = AF_INET; 126 sin.sin_port = htons(uPort); 127 sin.sin_addr.S_un.S_addr = INADDR_ANY; 128 129 if (SOCKET_ERROR == bind(sListen, (PSOCKADDR)&sin, sizeof(sin))) 130 { 131 MessageBox(hWnd, TEXT("绑定套接字失败"), TEXT("错误"), MB_OK | MB_ICONERROR); 132 shutdown(sListen, SD_RECEIVE); 133 closesocket(sListen); 134 WSACleanup(); 135 return 0; 136 } 137 138 //将套接字设为窗口通知消息类型 139 WSAAsyncSelect(sListen, hWnd, WM_SOCKET, FD_ACCEPT | FD_CLOSE); 140 listen(sListen, 5); 141 142 MSG msg; 143 while (GetMessage(&msg, NULL, 0, 0)) 144 { 145 TranslateMessage(&msg); 146 DispatchMessage(&msg); 147 } 148 149 WSACleanup(); 150 151 return msg.wParam; 152 }