WSAAsyncSelect模型

WSAAsyncSelect模型容許程序以windows消息的形式接受網絡事件通知windows

WSAAsyncSelect函數自動把套接字設爲非阻塞模式,而且爲套接字綁定一個窗口句柄,當有網絡事件發生時,便向這個窗口發送消息服務器

int WSAAsyncSelect( SOCKET s, //套接字句柄
    HWND hWnd,//指定一個窗口句柄
    u_int wMsg,//網絡事件到來的消息ID
    long lEvent//指定那些須要發送
);

FD_READ:接收對方發送的數據包網絡

FD_WRITE:繼續發送數據socket

FD_ACCEPT:有鏈接進入函數

FD_CONNECT:鏈接對方主機ui

FD_CLOSE:鏈接被關閉spa

調用WSAAsyncSelect函數監聽套接字code

::WSAAsyncSelect(sListen,hWnd,WM_SOCKET,FD_ACCEPT|FD_CLOSE);

成功調用後,應用程序開始以windows消息形式在窗口函數接受網絡事件通知blog

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam,//發送網絡事件的套接字句柄
                            LPARAM lParam//指定了發生的網絡事件
);

下面是簡單的TCP服務器程序,接受客戶端的鏈接請求,打印出接收的數據。隊列

// WSATCPSERVER.cpp : 定義控制檯應用程序的入口點。 //  #include "stdafx.h" #include <winsock2.h> #include <stdio.h> 
#pragma comment(lib,"WS2_32")
class CInitSock { public: CInitSock(BYTE minorVer=2,BYTE majorVer=2) { WSADATA wsaData; WORD sockVersion = MAKEWORD(minorVer,majorVer); if(::WSAStartup(sockVersion,&wsaData)!=0) { exit(0); } } ~CInitSock() { ::WSACleanup(); } }; CInitSock initSock; LRESULT CALLBACK WindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam); int _tmain(int argc, _TCHAR* argv[]) { char szClassName[] = "MainWClass"; WNDCLASSEX wndclass; //用描述主窗口的參數填充WNDCLASSEX結構
    wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_HREDRAW|CS_VREDRAW; wndclass.lpfnWndProc = WindowProc; wndclass.cbWndExtra = 0; wndclass.cbClsExtra = 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); //建立主窗口
    HWND hWnd = ::CreateWindowEx( 0, szClassName, "", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL); if(hWnd == NULL) { ::MessageBox(NULL,"建立窗口出錯!","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_un.S_addr = INADDR_ANY; if(::bind(sListen,(sockaddr*)&sin,sizeof(sin)) == SOCKET_ERROR) { printf("Failed bind()\n"); return -1; } //套接字設爲窗口通知消息類型
    ::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;//當GETMESSAGE返回0時結束
} LRESULT 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); } break; case FD_WRITE: { } break; case FD_READ: { char szText[1024]={0}; if(::recv(s,szText,1024,0) == -1) ::closesocket(s); else printf("接收數據:%s",szText); } break; case FD_CLOSE: { ::closesocket(s); } break; } } case WM_DESTROY: ::PostQuitMessage(0); return 0; } //不處理的消息交給系統默認處理
    return ::DefWindowProc(hWnd,uMsg,wParam,lParam); }

好多錯誤啊...首先 char 不能轉成LPSZ  其次,WM_SOCKET不認,爲何......哎

相關文章
相關標籤/搜索