WSAAsynSelect的基本使用,下面是一个简单的例子
#include <windows.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
#define LISTEN_PORT 5080
#define UWM_SOCKET WM_USER+1
TCHAR szClassName[] = TEXT("WSAAsynSelectClass");
TCHAR szWndName[] = TEXT("WSAAsynSelectWnd");
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASS wndClass = {0};
HWND hMainWnd;
MSG msg;
WSADATA wsaData;
int ret;
SOCKET listen_sock;
TCHAR szErrorMsg[256];
SOCKADDR_IN listen_addr;
ret = WSAStartup(MAKEWORD(2,2), &wsaData);
if(0 != ret)
{
wsprintf(szErrorMsg, TEXT("WSAStartup failed. Error:%d.\n"), WSAGetLastError());
MessageBox(NULL, szErrorMsg, szWndName, MB_OK);
return ret;
}
listen_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(INVALID_SOCKET == listen_sock)
{
wsprintf(szErrorMsg, TEXT("socket failed, Error:%d.\n"), WSAGetLastError());
MessageBox(NULL, szErrorMsg, szWndName, MB_OK);
goto rettag1;
}
listen_addr.sin_family = AF_INET;
listen_addr.sin_addr.s_addr = htonl(INADDR_ANY);
listen_addr.sin_port = htons(LISTEN_PORT);
ret = bind(listen_sock, (SOCKADDR*)&listen_addr, sizeof(listen_addr));
if(SOCKET_ERROR == ret)
{
wsprintf(szErrorMsg, TEXT("bind failed. Error:%d.\n"), WSAGetLastError());
MessageBox(NULL, szErrorMsg, szWndName, MB_OK);
goto rettag2;
}
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hbrBackground = GetStockObject(WHITE_BRUSH);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndClass.hInstance = hInstance;
wndClass.lpfnWndProc = MainWndProc;
wndClass.lpszClassName = szClassName;
wndClass.lpszMenuName = NULL;
if(!RegisterClass(&wndClass))
{
wsprintf(szErrorMsg, TEXT("RegisterClass failed."));
MessageBox(NULL, szErrorMsg, szWndName, MB_OK);
goto rettag2;
}
hMainWnd = CreateWindow(szClassName, szWndName, WS_OVERLAPPEDWINDOW | WS_VSCROLL,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);
if(NULL == hMainWnd)
{
wsprintf(szErrorMsg, TEXT("CreateWindow failed."));
MessageBox(NULL, szErrorMsg, szWndName, MB_OK);
UnregisterClass(szClassName, hInstance);
goto rettag2;
}
ShowWindow(hMainWnd, nShowCmd);
UpdateWindow(hMainWnd);
ret = WSAAsyncSelect(listen_sock, hMainWnd, UWM_SOCKET, FD_ACCEPT|FD_CLOSE);
if(SOCKET_ERROR == ret)
{
wsprintf(szErrorMsg, TEXT("WSAAsyncSelect failed. Error:%d.\n"), WSAGetLastError());
MessageBox(NULL, szErrorMsg, szWndName, MB_OK);
goto rettag2;
}
ret = listen(listen_sock, 5);
if(SOCKET_ERROR == ret)
{
wsprintf(szErrorMsg, TEXT("listen failed. Error:%d.\n"), WSAGetLastError());
MessageBox(NULL, szErrorMsg, szWndName, MB_OK);
goto rettag2;
}
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
rettag2:
closesocket(listen_sock);
rettag1:
WSACleanup();
return 0;
}
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam,LPARAM lParam)
{
TCHAR szErrorMsg[256];
char szMsg[256];
SOCKET client_sock = INVALID_SOCKET;
SOCKADDR_IN client_addr;
int client_addr_len = sizeof(client_addr);
int ret;
HDC hdc;
static int row = 0;
TEXTMETRIC textMetric;
int textHeight = 5;
hdc = GetDC(hwnd);
GetTextMetrics(hdc, &textMetric);
textHeight = textMetric.tmHeight;
switch(uMsg)
{
case WM_DESTROY:
ReleaseDC(hwnd, hdc);
PostQuitMessage(0);
break;
case UWM_SOCKET:
if(WSAGETSELECTERROR(lParam))
{
wsprintf(szErrorMsg, TEXT("WSAGETSELECTERROR failed. Error:%d.\n"), WSAGETSELECTERROR(lParam));
MessageBox(NULL, szErrorMsg, szWndName, MB_OK);
break;
}
switch(WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT:
client_sock = accept(wParam, (SOCKADDR*)&client_addr, &client_addr_len);
if(INVALID_SOCKET == client_sock)
{
wsprintf(szErrorMsg, TEXT("accept failed. Error:%d.\n"), WSAGetLastError());
MessageBox(NULL, szErrorMsg, szWndName, MB_OK);
break;
}
sprintf_s(szMsg, 256, "accept client:%s:%d.", inet_ntoa(client_addr.sin_addr), client_addr.sin_port);
// MessageBoxA(NULL, szMsg, "Information", MB_OK);
TextOutA(hdc, 0, row, szMsg, strlen(szMsg));
row += textHeight;
ret = WSAAsyncSelect(client_sock, hwnd, UWM_SOCKET, FD_READ|FD_WRITE|FD_CLOSE);
if(SOCKET_ERROR == ret)
{
wsprintf(szErrorMsg, TEXT("WSAAsyncSelect failed. Error:%d.\n"), WSAGetLastError());
MessageBox(NULL, szErrorMsg, szWndName, MB_OK);
}
break;
case FD_READ:
ret = recv(wParam, szMsg, 256, 0);
if(SOCKET_ERROR == ret)
{
wsprintf(szErrorMsg, TEXT("recv failed. Error:%d.\n"), WSAGetLastError());
MessageBox(NULL, szErrorMsg, szWndName, MB_OK);
break;
}
else if(0 == ret)
{
sprintf_s(szMsg, 256, "client closed.\n");
row += textHeight;
TextOutA(hdc, 0, row, szMsg, strlen(szMsg));
row += textHeight;
break;
}
else
{
TextOutA(hdc, 0, row, szMsg, strlen(szMsg));
row += textHeight;
}
break;
case FD_WRITE:
break;
case FD_CLOSE:
closesocket(wParam);
break;
}
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return TRUE;
}