• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            yehao's Blog

            套接字IO模型(三) WSAEventSelect模型

            http://www.cnblogs.com/NeuqUstcIim/archive/2008/08/14/1268214.html
            WSAEventSelect模型類似WSAAsynSelect模型,但最主要的區別是網絡事件發生時會被發送到一個事件對象句柄,而不是發送到一個窗口。這樣可能更加的好,對于服務器端的程序來說。

            使用步驟如下:

            a、 創建事件對象來接收網絡事件:

            WSAEVENT WSACreateEvent( void );

            該函數的返回值為一個事件對象句柄,它具有兩種工作狀態:已傳信(signaled)和未傳信(nonsignaled)以及兩種工作模式:人工重設(manual reset)和自動重設(auto reset)。默認未未傳信的工作狀態和人工重設模式。

             

            b、將事件對象與套接字關聯,同時注冊事件,使事件對象的工作狀態從未傳信轉變未已傳信。

            int WSAEventSelect( SOCKET s,WSAEVENT hEventObject,long lNetworkEvents );
            s為套接字
            hEventObject為剛才創建的事件對象句柄

            lNetworkEvents為掩碼,定義如上面所述

             

            c、I/O處理后,設置事件對象為未傳信
            BOOL WSAResetEvent( WSAEVENT hEvent );
            Hevent為事件對象

            成功返回TRUE,失敗返回FALSE。

             

            d、等待網絡事件來觸發事件句柄的工作狀態:

            DWORD WSAWaitForMultipleEvents( DWORD cEvents,const WSAEVENT FAR * lphEvents, BOOL fWaitAll,DWORD dwTimeout, BOOL fAlertable );
            lpEvent為事件句柄數組的指針
            cEvent為為事件句柄的數目,其最大值為WSA_MAXIMUM_WAIT_EVENTS
            fWaitAll指定等待類型:TRUE:當lphEvent數組重所有事件對象同時有信號時返回;
            FALSE:任一事件有信號就返回。
            dwTimeout為等待超時(毫秒)

            fAlertable為指定函數返回時是否執行完成例程

             

            nIndex=WSAWaitForMultipleEvents(…);

            MyEvent=EventArray[Index- WSA_WAIT_EVENT_0];

             

             

            事 件選擇模型也比較簡單,實現起來也不是太復雜,它的基本思想是將每個套接字都和一個WSAEVENT對象對應起來,并且在關聯的時候指定需要關注的哪些網 絡事件。一旦在某個套接字上發生了我們關注的事件(FD_READ和FD_CLOSE),與之相關聯的WSAEVENT對象被Signaled。程序定義 了兩個全局數組,一個套接字數組,一個WSAEVENT對象數組,其大小都是MAXIMUM_WAIT_OBJECTS(64),兩個數組中的元素一一對 應。
            同樣的,這里的程序沒有考慮兩個問題,一是不能無條件的調用accept,因為我們支持的并發連接數有限。解決方法是將套接字按 MAXIMUM_WAIT_OBJECTS分組,每MAXIMUM_WAIT_OBJECTS個套接字一組,每一組分配一個工作者線程;或者采用 WSAAccept代替accept,并回調自己定義的Condition Function。第二個問題是沒有對連接數為0的情形做特殊處理,程序在連接數為0的時候CPU占用率為100%。

             

             1 SOCKET       Socket[WSA_MAXIMUM_WAIT_EVENTS];
             2 WSAEVENT   Event[WSA_MAXINUM_WAIT_EVENTS];
             3 SOCKET    Accept, Listen;
             5 DWORD     EventTotal = 0;
             6 DWORD     Index;
             7 
             8 //Set up a TCP socket for listening on port 5150
             9 Listen = socket(PF_INET,SOCK_STREAM,0);
            10 
            11 InternetAddr.sin_family      = AF_INET;
            12 InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
            13 InternetAddr.sin_port        = htons(5150);
            14 
            15 bind(Listen,(PSOCKADDR) &InternetAddr,sizeof(InternetAddr));
            16 
            17 NewEvent = WSACreateEvent();
            18 
            19 WSAEventSelect(Listen,NewEvnet,FD_ACCEPT|FD_CLOSE);
            20 
            21 listen(Listen,5);
            22 
            23 Socket[EventTotal] = Listen;
            24 Event[EventTotal] = NewEvent;
            25 EventTotal++;
            26 
            27 while (TRUE)
            28 {
            29     //Wait for network events on all sockets
            30     Index = WSAWaitForMultipleEvents(EventTotal,EventArray,FALSE,WSA_INFINITE,FALSE);
            31 
            32     WSAEnumNewWorkEvents(SocketArray[Index-WSA_WAIT_EVENT_0],
            33         EventArray[Index-WSA_WAIT_EVENT_0],
            34         &NetworkEvents);
            35     //Check for FD_ACCEPT messages
            36     if (NetworkEvents.lNetworkEvents & FD_ACCEPT)
            37     {
            38         if (NetworkEvents.iErrorCode[FD_ACCEPT_BIT] !=0)
            39         {
            40             //Error
            41             break;
            42         }
            43         //Accept a new connection and add it to the socket and event lists
            44         Accept = accept(SocketArray[Index-WSA_WAIT_EVENT_0],NULL,NULL);
            45 
            46         //We cannot process more than WSA_MAXIMUM_WAIT_EVENTS sockets ,
            47         //so close the accepted socket
            48         if (EventTotal > WSA_MAXIMUM_WAIT_EVENTS)
            49         {
            50             printf("..");
            51             closesocket (Accept);
            52             break;
            53         }
            54         NewEvent = WSACreateEvent();
            55 
            56         WSAEventSelect(Accept,NewEvent,FD_READ|FD_WRITE|FD_CLOSE);
            57 
            58         Event[EventTotal] = NewEvent;
            59         Socket[EventTotal]= Accept;
            60         EventTotal++;
            61         prinrt("Socket %d connect\n",Accept);
            62     }
            63     //Process FD_READ notification
            64     if (NetworkEvents.lNetwoAD)rkEvents & FD_RE
            65     {
            66         if (NetworkEvents.iErrorCode[FD_READ_BIT !=0])
            67         {
            68             //Error
            69             break;
            70         }
            71 
            72         //Read data from the socket
            73         recv(Socket[Index-WSA_WAIT_EVENT_0],buffer,sizeof(buffer),0);
            74     }
            75     //process FD_WRITE notitication
            76     if (NetworkEvents.lNetworkEvents & FD_WRITE)
            77     {
            78         if (NetworkEvents.iErrorCode[FD_WRITE_BIT] !=0)
            79         {
            80             //Error
            81             break;
            82         }
            83         send(Socket[Index-WSA_WAIT_EVENT_0],buffer,sizeof(buffer),0);
            84     }
            85     if (NetworkEvents.lNetworkEvents & FD_CLOSE)
            86     {
            87         if(NetworkEvents.iErrorCode[FD_CLOSE_BIT] !=0)
            88         {
            89             //Error
            90             break;
            91         }
            92         closesocket (Socket[Index-WSA_WAIT_EVENT_0]);
            93         //Remove socket and associated event from the Socket and Event arrays and
            94         //decrement eventTotal
            95         CompressArrays(Event,Socket,& EventTotal);
            96     }
            97 }

            posted on 2011-08-18 16:08 厚積薄發 閱讀(591) 評論(0)  編輯 收藏 引用 所屬分類: 網絡編程

            導航

            <2025年8月>
            272829303112
            3456789
            10111213141516
            17181920212223
            24252627282930
            31123456

            統計

            常用鏈接

            留言簿

            隨筆分類

            文章分類

            文章檔案

            搜索

            最新評論

            久久精品中文字幕一区| 亚洲AV日韩精品久久久久久久| 2020久久精品国产免费| 久久久久久久综合日本亚洲| 91久久精品视频| 2021国内精品久久久久久影院| 亚洲国产美女精品久久久久∴ | 国产真实乱对白精彩久久| 国产91久久综合| 久久狠狠爱亚洲综合影院| 国产精品美女久久久m| 三级韩国一区久久二区综合| 69国产成人综合久久精品| 久久经典免费视频| 国产成人久久777777| 久久精品国产亚洲AV大全| 亚洲成av人片不卡无码久久| 久久精品国产亚洲77777| 伊人久久大香线蕉亚洲| 久久se精品一区二区影院| 精品精品国产自在久久高清| 久久久这里只有精品加勒比| 久久国产V一级毛多内射| 久久精品这里热有精品| 久久精品水蜜桃av综合天堂| 久久久亚洲精品蜜桃臀| 国产精品一区二区久久精品无码| 精品久久8x国产免费观看| 熟妇人妻久久中文字幕| 无码精品久久久天天影视| 区久久AAA片69亚洲| 中文字幕无码av激情不卡久久| 老司机午夜网站国内精品久久久久久久久 | 亚洲国产精品成人AV无码久久综合影院| 精品精品国产自在久久高清| 精品久久久久久国产| 久久综合九色综合久99| 99久久人人爽亚洲精品美女| 欧美精品一区二区精品久久| 欧美777精品久久久久网| 久久精品?ⅴ无码中文字幕|