1. 程式人生 > >TCP流式套接字的非同步事件WSAAsyncSelect程式設計

TCP流式套接字的非同步事件WSAAsyncSelect程式設計

#define WM_SOCKET WM_USER+101 
#include <WINSOCK2.H> 
/*#include <windows.h>*/ 
#pragma comment(lib,"WS2_32"
//----------------視窗過程函式的宣告------------- 
LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam); 
//----------------WinMain()函式------------------ 
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int
 nShowCmd ) 

    WNDCLASS wc; 
    wc.style=CS_HREDRAW|CS_VREDRAW; 
    wc.lpfnWndProc=WindowProc; 
    wc.cbClsExtra=0
    wc.cbWndExtra=0
    wc.hInstance=hInstance; 
    wc.hIcon=LoadIcon(NULL,IDI_EXCLAMATION); 
    wc.hCursor=LoadCursor(NULL,IDC_ARROW); 
    wc.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH); 
    wc.lpszMenuName=NULL; 
    wc.lpszClassName="Test"

    //---註冊視窗類---- 
    RegisterClass(&wc); 
    //---建立視窗---- 
    HWND hwnd=CreateWindow("Test","視窗標題",WS_SYSMENU,300,0,600,400,NULL,NULL,hInstance,NULL); 
    if (hwnd==NULL) 
    { 
        MessageBox(hwnd,"建立窗口出錯","標題欄提升",MB_OK); 
        return 1
    } 
    //---顯示視窗---- 
    ShowWindow(hwnd,SW_SHOWNORMAL); 
    UpdateWindow(hwnd); 
    //---socket----- 

    WSADATA wsaData; 
    WORD wVersionRequested=MAKEWORD(2,2); 
    if (WSAStartup(wVersionRequested,&wsaData)!=0
    { 
        MessageBox(NULL,"WSAStartup() Failed","呼叫失敗",0); 
        return 1
    } 
    SOCKET s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 
    if (s==INVALID_SOCKET) 
    { 
        MessageBox(NULL,"socket() Failed","呼叫失敗",0); 
        return 1
    }     
    sockaddr_in sin; 
    sin.sin_family=AF_INET; 
    sin.sin_port=htons(1111); 
    sin.sin_addr.S_un.S_addr=inet_addr("192.168.31.1"); 
    if (bind(s,(sockaddr*)&sin,sizeof(sin))==SOCKET_ERROR) 
    { 
        MessageBox(NULL,"bind() Failed","呼叫失敗",0); 
        return 1
    } 
    if (listen(s,3)==SOCKET_ERROR) 
    { 
        MessageBox(NULL,"listen() Failed","呼叫失敗",0); 
        return 1
    } 
    else 
        MessageBox(hwnd,"進入監聽狀態!","標題欄提示",MB_OK); 
    WSAAsyncSelect(s,hwnd,WM_SOCKET,FD_ACCEPT|FD_CLOSE); 
    //---訊息迴圈---- 
    MSG msg; 
    while (GetMessage(&msg,0,0,0)) 
    { 
        TranslateMessage(&msg); 
        DispatchMessage(&msg); 
    } 
    closesocket(s); 
    WSACleanup(); 
    return msg.wParam; 

//-------------------視窗過程---------------------- 
LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam) 

    switch(uMsg) 
    { 
    case WM_SOCKET: 
        { 
            SOCKET ss=wParam;   //wParam引數標誌了網路事件發生的套介面 
            if (WSAGETSELECTERROR(lParam)) 
            { 
                closesocket(ss); 
                return 0
            } 
            switch (WSAGETSELECTEVENT(lParam)) 
            { 
            case FD_ACCEPT:   //-----①連線請求到來 
                { 
                     sockaddr_in Cadd; 
                     int Cadd_len=sizeof(Cadd); 
                    SOCKET sNew=accept(ss,(sockaddr*)&Cadd,&Cadd_len); 
                    if (ss==INVALID_SOCKET)                     
                        MessageBox(hwnd,"呼叫accept()失敗!","標題欄提示",MB_OK);                     
                    WSAAsyncSelect(sNew,hwnd,WM_SOCKET,FD_READ|FD_CLOSE); 
                }break
            case FD_READ:   //-----②資料傳送來 
                { 
                    char cbuf[256]; 
                    memset(cbuf,0,256); 
                    int cRecv=recv(ss,cbuf,256,0); 
                    if ((cRecv==SOCKET_ERROR&& WSAGetLastError() == WSAECONNRESET)|| cRecv==0
                    { 
                        MessageBox(hwnd,"呼叫recv()失敗!","標題欄提示",MB_OK); 
                        closesocket(ss); 
                    } 
                    else if (cRecv>0
                    { 
                        MessageBox(hwnd,cbuf,"收到的資訊",MB_OK);     
                        char Sbuf[]="Hello client!I am server"
                        int isend=send(ss,Sbuf,sizeof(Sbuf),0); 
                        if (isend==SOCKET_ERROR || isend<=0
                        { 
                            MessageBox(hwnd,"傳送訊息失敗!","標題欄提示",MB_OK);                             
                        } 
                        else 
                            MessageBox(hwnd,"已經發資訊到客戶端!","標題欄提示",MB_OK); 
                    } 
                }break
            case FD_CLOSE:    //----③關閉連線 
                { 
                    closesocket(ss); 
                } 
                break
            } 
        } 
        break
    case WM_CLOSE: 
        if (IDYES==MessageBox(hwnd,"是否確定退出?","message",MB_YESNO)) 
            DestroyWindow(hwnd); 
        break
    case WM_DESTROY: 
        PostQuitMessage(0); 
        break
    default
        return DefWindowProc(hwnd,uMsg,wParam,lParam); 
    } 
    return 0