• <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 厚積薄發 閱讀(576) 評論(0)  編輯 收藏 引用 所屬分類: 網絡編程

            導航

            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            統計

            常用鏈接

            留言簿

            隨筆分類

            文章分類

            文章檔案

            搜索

            最新評論

            狠狠色丁香久久婷婷综合| 日本道色综合久久影院| 国产精品久久久久蜜芽| 久久久久久精品久久久久| 亚洲国产精品高清久久久| 夜夜亚洲天天久久| 欧美久久久久久精选9999| 区久久AAA片69亚洲| 久久久久国产精品| 三级三级久久三级久久| 久久美女人爽女人爽| 久久人人爽人人爽人人片AV高清 | 久久夜色撩人精品国产| 超级97碰碰碰碰久久久久最新| 99久久99久久精品免费看蜜桃| 久久久中文字幕日本| 国产精品久久久久久搜索| 久久精品中文字幕一区| 久久福利片| 精品久久久无码中文字幕天天| 久久精品国产第一区二区三区| 青青草原综合久久大伊人导航 | 伊人伊成久久人综合网777| 69国产成人综合久久精品| 久久久久久综合网天天| 久久人人爽人人爽人人片AV东京热| 久久Av无码精品人妻系列| 国内精品久久久久影院薰衣草 | 久久久久久久久波多野高潮| 精品久久久久久无码中文野结衣| 久久精品国产亚洲av麻豆小说 | 亚洲精品99久久久久中文字幕| 精品一区二区久久| 国产精品久久影院| 久久久久亚洲av无码专区导航| 久久精品国产日本波多野结衣| 精品久久久久久无码不卡| 一级女性全黄久久生活片免费 | 久久免费视频一区| 久久久久婷婷| 一本久久a久久精品综合香蕉|