• <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模型,但最主要的區(qū)別是網(wǎng)絡(luò)事件發(fā)生時會被發(fā)送到一個事件對象句柄,而不是發(fā)送到一個窗口。這樣可能更加的好,對于服務(wù)器端的程序來說。

            使用步驟如下:

            a、 創(chuàng)建事件對象來接收網(wǎng)絡(luò)事件:

            WSAEVENT WSACreateEvent( void );

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

             

            b、將事件對象與套接字關(guān)聯(lián),同時注冊事件,使事件對象的工作狀態(tài)從未傳信轉(zhuǎn)變未已傳信。

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

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

             

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

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

             

            d、等待網(wǎng)絡(luò)事件來觸發(fā)事件句柄的工作狀態(tài):

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

            fAlertable為指定函數(shù)返回時是否執(zhí)行完成例程

             

            nIndex=WSAWaitForMultipleEvents(…);

            MyEvent=EventArray[Index- WSA_WAIT_EVENT_0];

             

             

            事 件選擇模型也比較簡單,實現(xiàn)起來也不是太復(fù)雜,它的基本思想是將每個套接字都和一個WSAEVENT對象對應(yīng)起來,并且在關(guān)聯(lián)的時候指定需要關(guān)注的哪些網(wǎng) 絡(luò)事件。一旦在某個套接字上發(fā)生了我們關(guān)注的事件(FD_READ和FD_CLOSE),與之相關(guān)聯(lián)的WSAEVENT對象被Signaled。程序定義 了兩個全局?jǐn)?shù)組,一個套接字?jǐn)?shù)組,一個WSAEVENT對象數(shù)組,其大小都是MAXIMUM_WAIT_OBJECTS(64),兩個數(shù)組中的元素一一對 應(yīng)。
            同樣的,這里的程序沒有考慮兩個問題,一是不能無條件的調(diào)用accept,因為我們支持的并發(fā)連接數(shù)有限。解決方法是將套接字按 MAXIMUM_WAIT_OBJECTS分組,每MAXIMUM_WAIT_OBJECTS個套接字一組,每一組分配一個工作者線程;或者采用 WSAAccept代替accept,并回調(diào)自己定義的Condition Function。第二個問題是沒有對連接數(shù)為0的情形做特殊處理,程序在連接數(shù)為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 厚積薄發(fā) 閱讀(576) 評論(0)  編輯 收藏 引用 所屬分類: 網(wǎng)絡(luò)編程

            導(dǎo)航

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

            統(tǒng)計

            常用鏈接

            留言簿

            隨筆分類

            文章分類

            文章檔案

            搜索

            最新評論

            国产精品九九久久免费视频 | 青青久久精品国产免费看| 欧美久久一区二区三区| 久久91精品国产91| 久久国产亚洲精品麻豆| 久久国产劲爆AV内射—百度| 日韩精品久久久久久免费| 久久se精品一区精品二区国产| 亚洲精品乱码久久久久久蜜桃不卡 | 武侠古典久久婷婷狼人伊人| 精品久久久久成人码免费动漫| 久久综合精品国产二区无码| 99久久国产综合精品五月天喷水| 东京热TOKYO综合久久精品| 久久久高清免费视频| 国产巨作麻豆欧美亚洲综合久久| 亚洲色欲久久久久综合网| 亚洲精品WWW久久久久久| 国产Av激情久久无码天堂| 欧美久久久久久精选9999| 热久久国产欧美一区二区精品| 日韩精品无码久久久久久| 精品国产乱码久久久久软件| 99久久精品免费观看国产| 色婷婷综合久久久久中文 | 久久精品九九亚洲精品| 日产精品99久久久久久| 伊人久久成人成综合网222| 久久99精品国产麻豆蜜芽| 精品无码久久久久国产| 一本久道久久综合狠狠爱| …久久精品99久久香蕉国产| 久久国产高清字幕中文| 97久久天天综合色天天综合色hd| 久久久久久曰本AV免费免费| 伊人精品久久久久7777| 久久久久久久波多野结衣高潮| 久久这里有精品视频| 久久婷婷午色综合夜啪| 久久亚洲sm情趣捆绑调教| 精品国产乱码久久久久久呢|