winsock -WSAAsyncSelect函数的网络事件类型表

来源:互联网 发布:linux graphics.h 编辑:程序博客网 时间:2024/05/16 17:42


1. WSAAsyncSelect 基于win事件机制处理的异步消息。
在使用异步网络中WSAAsyncSelect,需要处理的步骤:
{
1.在WM_CREATE消息处理函数中,初始化Windows Socket library,创建监听套接字,绑定,监听,
 并且调用WSAAsyncSelect函数表示我们关心在监听套接字上发生的FD_ACCEPT事件;
2.自定义一个消息WM_SOCKET,一旦在我们所关心的套接字(监听套接字和客户端套接字)上发生了某个事件,
 系统就会调用WndProc并且message参数被设置为WM_SOCKET;
3.在WM_SOCKET的消息处理函数中,分别对FD_ACCEPT、FD_READ和FD_CLOSE事件进行处理;
4.在窗口销毁消息(WM_DESTROY)的处理函数中,我们关闭监听套接字,清除Windows Socket library
}
下面这张用于WSAAsyncSelect函数的网络事件类型表可以让你对各个网络事件有更清楚的认识:
{
FD_READ   应用程序想要接收有关是否可读的通知,以便读入数据
FD_WRITE   应用程序想要接收有关是否可写的通知,以便写入数据
FD_OOB   应用程序想接收是否有带外(OOB)数据抵达的通知
FD_ACCEPT  应用程序想接收与进入连接有关的通知
FD_CONNECT 应用程序想接收与一次连接或者多点join操作完成的通知
FD_CLOSE   应用程序想接收与套接字关闭有关的通知
FD_QOS   应用程序想接收套接字“服务质量”(QoS)发生更改的通知
FD_GROUP_QOS 应用程序想接收套接字组“服务质量”发生更改的通知(现在没什么用处,为未来套接字组的使用保留)
FD_ROUTING_INTERFACE_CHANGE 应用程序想接收在指定的方向上,与路由接口发生变化的通知
FD_ADDRESS_LIST_CHANGE 应用程序想接收针对套接字的协议家族,本地地址列表发生变化的通知
}


SourceCode:
[cpp] view plain copy
  
#include <winsock.h>  
#include <tchar.h>  
#pragma comment(lib, "ws2_32.lib")  
  
  
#define PORT      5150  
#define MSGSIZE   1024  
#define WM_SOCKET WM_USER+0 //自定义消息  
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);//MFC中要重载  
  
  
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)  
{  
    static TCHAR szAppName[] = _T("AsyncSelect Model");//标题  
    HWND         hwnd;  
    MSG          msg;  
    WNDCLASS     wndclass;  
  
  
    wndclass.style = CS_HREDRAW | CS_VREDRAW;  
    wndclass.lpfnWndProc = WndProc;  
    wndclass.cbClsExtra = 0;  
    wndclass.cbWndExtra = 0;  
    wndclass.hInstance = hInstance;  
    wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);  
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);  
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);  
    wndclass.lpszMenuName = NULL;  
    wndclass.lpszClassName = szAppName;  
    if (!RegisterClass(&wndclass))//注册窗口类  
    {  
        MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR);  
        return 0;  
    }  
  
    hwnd = CreateWindow(szAppName,                  // window class name  
        TEXT("AsyncSelect Model"), // window caption  
        WS_OVERLAPPEDWINDOW,        // window style  
        CW_USEDEFAULT,              // initial x position  
        CW_USEDEFAULT,              // initial y position  
        CW_USEDEFAULT,              // initial x size  
        CW_USEDEFAULT,              // initial y size  
        NULL,                       // parent window handle  
        NULL,                       // window menu handle  
        hInstance,                  // program instance handle  
        NULL);                     // creation parameters  
  
    ShowWindow(hwnd, iCmdShow);  
    UpdateWindow(hwnd);  
  
    while (GetMessage(&msg, NULL, 0, 0))  
    {  
        TranslateMessage(&msg);  
        DispatchMessage(&msg);  
    }  
  
    return msg.wParam;  
}  
  
  
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
{  
    WSADATA       wsd;  
    static SOCKET sListen;  
    SOCKET        sClient;  
    SOCKADDR_IN   local, client;  
    int           ret, iAddrSize = sizeof(client);  
    char          szMessage[MSGSIZE];  
  
  
    switch (message)  
    {  
    case WM_CREATE:  
        // Initialize Windows Socket library  
        WSAStartup(0x0202, &wsd);  
  
        // Create listening socket  
        sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  
  
        // Bind  
        local.sin_addr.S_un.S_addr = htonl(INADDR_ANY);  
        local.sin_family = AF_INET;  
        local.sin_port = htons(PORT);  
        bind(sListen, (struct sockaddr *)&local, sizeof(local));  
  
        // Listen  
        listen(sListen, 3);  
  
        // Associate listening socket with FD_ACCEPT event  
        WSAAsyncSelect(sListen, hwnd, WM_SOCKET, FD_ACCEPT);  
        return 0;  
    case WM_DESTROY:  
        closesocket(sListen);  
        WSACleanup();  
        PostQuitMessage(0);  
        return 0;  
  
    case WM_SOCKET:  
        if (WSAGETSELECTERROR(lParam))  
        {  
            closesocket(wParam);  
            break;  
        }  
  
        switch (WSAGETSELECTEVENT(lParam))  
        {  
        case FD_ACCEPT:  
            // Accept a connection from client  
            sClient = accept(wParam, (struct sockaddr *)&client, &iAddrSize);  
  
            // Associate client socket with FD_READ and FD_CLOSE event  
            WSAAsyncSelect(sClient, hwnd, WM_SOCKET, FD_READ | FD_CLOSE);  
            break;  
        case FD_READ:  
            ret = recv(wParam, szMessage, MSGSIZE, 0);  
            if (ret == 0 || ret == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET)  
            {  
                closesocket(wParam);  
            }  
            else  
            {  
                szMessage[ret] = '\0';  
                send(wParam, szMessage, strlen(szMessage), 0);  
            }  
            break;  
  
        case FD_CLOSE:  
            closesocket(wParam);  
            break;  
        }  
        return 0;  
    }  
  
    return DefWindowProc(hwnd, message, wParam, lParam);  
}  
0 0
原创粉丝点击