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 }