• <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>

            無我

            讓內心永遠燃燒著偉大的光明的精神之火!
            靈活的思考,嚴謹的實現
            豪邁的氣魄、頑強的意志和周全的思考

            【轉】完成端口例子

            本文轉載來自CSDN博客

            http://blog.csdn.net/nicholasmaxwell/archive/2006/05/18/744467.aspxhttp://blog.csdn.net/nicholasmaxwell/archive/2006/05/18/744464.aspx

             另外一篇值得參考的《完成端口I/O模型編寫心得!》http://blog.csdn.net/jasonm2008/archive/2009/08/14/4441514.aspx#

             

            #include "stdafx.h"

            #include 
            <iostream.h>

            #include 

            #include 

            #include 


            #define PORT 5150

            #define DATA_BUFSIZE 8192


            typedef 
            struct 

            {

              OVERLAPPED OVerlapped;

              WSABUF DATABuf;

              CHAR Buffer[DATA_BUFSIZE];

              DWORD BytesSend,BytesRecv;

            }PER_IO_OPERATION_DATA, 
            *LPPER_IO_OPERATION_DATA;


            typedef 
            struct 

             {

              SOCKET Socket;

            }PER_HANDLE_DATA,
            *LPPER_HANDLE_DATA;



            DWORD WINAPI ServerWorkerThread(LPVOID ComlpetionPortID);



            int main(int argc, char* argv[])


            {

                   SOCKADDR_IN InternetAddr;

              SOCKET Listen,Accept;

              HANDLE CompetionPort;

              SYSTEM_INFO SystenInfo;

              LPPER_HANDLE_DATA PerHandleData;

              LPPER_IO_OPERATION_DATA PerIOData;

              
            int i;

              DWORD RecvBytes;

              DWORD Flags;

              DWORD ThreadID;

              WSADATA wsadata;

              DWORD Ret;

              

              
            if (Ret = WSAStartup(0x2020,&wsadata) != 0)

              {

                printf(
            "WSAStartup failed with error %d\n",Ret);

                
            return 0;

              }



               
            //打開一個空的完成端口

              
            if ((CompetionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0)) == NULL)

              {

                printf(
            "CreateIoCompletionPort failed with error %d\n",GetLastError());

                
            return 0;

              }

              

              GetSystemInfo(
            &SystenInfo);

               

              
            // 開啟cpu個數的2倍個的線程

              
            for (i=0; i < SystenInfo.dwNumberOfProcessors*2; i++)

              {

                HANDLE ThreadHandle;

                
            //創建服務器工作線程,并且向線程傳送完成端口

                
            if ((ThreadHandle = CreateThread(NULL,0,ServerWorkerThread,CompetionPort,0,&ThreadID)) == NULL)

                {

                  printf(
            "CreateThread failed with error %d\n" ,GetLastError());

                  
            return 0;

                }

                CloseHandle(ThreadHandle);

              }

              

              
            //打開一個服務器socket

              
            if ((Listen = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)

              {

                printf(
            "WSASocket() failed with error %d\n", WSAGetLastError());

                
            return 0;

              } 



              InternetAddr.sin_family 
            = AF_INET;

              InternetAddr.sin_addr.S_un.S_addr 
            = htonl(INADDR_ANY);

              InternetAddr.sin_port 
            = htons(PORT);

              

              
            if (bind(Listen,(LPSOCKADDR)&InternetAddr,sizeof(InternetAddr)) == SOCKET_ERROR)

              {

                printf(
            "bind failed with error %d\n",WSAGetLastError());

                
            return 0;

              }


              
            if (listen(Listen,5== SOCKET_ERROR)

              {

                printf(
            "listen failed with error %d\n",WSAGetLastError());

                
            return 0;

              }


              
            //接收連接并且分發給完成端口

              
            while (TRUE)

              {

                
            if ((Accept = WSAAccept(Listen,NULL,NULL,NULL,0)) == SOCKET_ERROR)

                {

                  printf(
            "WSAAccept failed with error %d\n",WSAGetLastError());

                  
            return 0;

                }


                
            //創建與套接字相關的套接字信息結構

                
            if ((PerHandleData = (LPPER_HANDLE_DATA)GlobalAlloc(GPTR,sizeof(PER_HANDLE_DATA))) == NULL)

                {

                  printf(
            "GlobalAlloc failed with error %d\n",GetLastError());

                  
            return 0;

                }

                

                
            // Associate the accepted socket with the original completion port.

                printf(
            "Socket number %d connected\n",Accept);

                PerHandleData
            ->Socket = Accept;//結構中存入接收的套接字

                

                
            //與我們的創建的那個完成端口關聯起來,將關鍵項也與指定的一個完成端口關聯

                
            if ((CreateIoCompletionPort((HANDLE)Accept,CompetionPort,(DWORD)PerHandleData,0)) == NULL)

                {

                  printf(
            "CreateIoCompletionPort failed with error%d\n",GetLastError());

                  
            return 0;

                } 


                
            // 創建同下面的WSARecv調用相關的IO套接字信息結構體

                
            if ((PerIOData = (LPPER_IO_OPERATION_DATA)GlobalAlloc(GPTR,sizeof(PER_IO_OPERATION_DATA))) = NULL)

                {

                  printf(
            "GlobalAloc failed with error %d\n",GetLastError());

                  
            return 0;

                }

                ZeroMemory(
            &(PerIOData->OVerlapped),sizeof(OVERLAPPED));

                PerIOData
            ->BytesRecv = 0;

                PerIOData
            ->BytesSend = 0;

                PerIOData
            ->DATABuf.len = DATA_BUFSIZE;

                PerIOData
            ->DATABuf.buf = PerIOData->Buffer;

                Flags 
            = 0;


                
            if (WSARecv(Accept,&(PerIOData->DATABuf),1,&RecvBytes,&Flags,&(PerIOData->OVerlapped),NULL) == SOCKET_ERROR)

                {

                 
            if (WSAGetLastError() != ERROR_IO_PENDING)

                 {

                   printf(
            "WSARecv() failed with error %d\n",WSAGetLastError());

                   
            return 0;

                 }

                }

              }

              
            return 0;

            }


             

            工作者線程

             

            //工作線程 

            DWORD WINAPI ServerWorkerThread(LPVOID ComlpetionPortID) 



              HANDLE ComplectionPort 
            = (HANDLE) ComlpetionPortID; 

              DWORD BytesTransferred; 

              LPOVERLAPPED Overlapped; 

              LPPER_HANDLE_DATA PerHandleData; 

              LPPER_IO_OPERATION_DATA PerIOData; 

              DWORD SendBytes,RecvBytes; 

              DWORD Flags; 

              

              
            while (TRUE) 

              { 

                
            if (GetQueuedCompletionStatus(ComplectionPort,&BytesTransferred,(LPDWORD)&PerHandleData,(LPOVERLAPPED*)&PerIOData,INFINITE) == 0

                { 

                  printf(
            "GetQueuedCompletionStatus failed with error%d\n",GetLastError()); 

                  
            return 0

                } 


                
            //首先檢查套接字上是否發生錯誤,如果發生了則關閉套接字并且清除同套節字相關的SOCKET_INFORATION 結構體 

                
            if (BytesTransferred == 0

                { 

                  printf(
            "Closing Socket %d\n",PerHandleData->Socket); 

                  
            if (closesocket(PerHandleData->Socket) == SOCKET_ERROR) 

                  { 

                    printf(
            "closesocket failed with error %d\n",WSAGetLastError()); 

                    
            return 0

                  } 

                  GlobalFree(PerHandleData); 

                  GlobalFree(PerIOData); 

                  
            continue

                } 


                
            //檢查BytesRecv域是否等于0,如果是,說明WSARecv調用剛剛完成,可以用從己完成的WSARecv調用返回的BytesTransferred值更新BytesRecv域 

                
            if (PerIOData->BytesRecv == 0

                { 

                  PerIOData
            ->BytesRecv = BytesTransferred; 

                  PerIOData
            ->BytesSend = 0

                } 

                
            else 

                { 

                  PerIOData
            ->BytesRecv +=BytesTransferred; 

                } 


                
            // 

                
            if (PerIOData->BytesRecv > PerIOData->BytesSend) 



                   
            //發布另一個WSASend()請求,因為WSASendi 不能確保發送了請的所有字節,繼續WSASend調用直至發送完所有收到的字節 

                  ZeroMemory(
            &(PerIOData->OVerlapped),sizeof(OVERLAPPED)); 

                  PerIOData
            ->DATABuf.buf = PerIOData->Buffer + PerIOData->BytesSend; 

                  PerIOData
            ->DATABuf.len = PerIOData->BytesRecv - PerIOData->BytesSend; 

                  

                  
            if (WSASend(PerHandleData->Socket,&(PerIOData->DATABuf),1,&SendBytes,0,&(PerIOData->OVerlapped),NULL) ==SOCKET_ERROR ) 

                  { 

                    
            if (WSAGetLastError() != ERROR_IO_PENDING) 

                    { 

                      printf(
            "WSASend() fialed with error %d\n",WSAGetLastError()); 

                      
            return 0

                    } 

                  } 

                } 

                
            else 

                { 

                  PerIOData
            ->BytesRecv = 0

                  
            //Now that is no more bytes to send post another WSARecv() request 

                  
            //現在己經發送完成 

                  Flags 
            = 0

                  ZeroMemory(
            &(PerIOData->OVerlapped),sizeof(OVERLAPPED)); 

                  PerIOData
            ->DATABuf.buf = PerIOData->Buffer; 

                  PerIOData
            ->DATABuf.len = DATA_BUFSIZE; 

                  
            if (WSARecv(PerHandleData->Socket,&(PerIOData->DATABuf),1,&RecvBytes,&Flags,&(PerIOData->OVerlapped),NULL) == SOCKET_ERROR) 

                  { 

                    
            if (WSAGetLastError() != ERROR_IO_PENDING) 

                    { 

                      printf(
            "WSARecv() failed with error %d\n",WSAGetLastError()); 

                      
            return 0

                    } 

                  } 

                } 

              } 

              


             

            posted on 2011-04-21 13:49 Tim 閱讀(1302) 評論(0)  編輯 收藏 引用 所屬分類: 計算機網絡

            <2011年4月>
            272829303112
            3456789
            10111213141516
            17181920212223
            24252627282930
            1234567

            導航

            統計

            公告

            本博客原創文章,歡迎轉載和交流。不過請注明以下信息:
            作者:TimWu
            郵箱:timfly@yeah.net
            來源:www.shnenglu.com/Tim
            感謝您對我的支持!

            留言簿(9)

            隨筆分類(173)

            IT

            Life

            搜索

            積分與排名

            最新隨筆

            最新評論

            閱讀排行榜

            国产精品久久久久久久久久影院 | 国产精品免费看久久久 | 久久九色综合九色99伊人| 欧美精品丝袜久久久中文字幕 | 777午夜精品久久av蜜臀| 久久精品国产亚洲AV香蕉| 亚洲国产精品久久久久婷婷老年 | 国产精品成人无码久久久久久 | 狠狠色丁香久久婷婷综合图片| 无码超乳爆乳中文字幕久久| 国产成人精品久久亚洲| 国产A级毛片久久久精品毛片| 久久综合综合久久狠狠狠97色88| 开心久久婷婷综合中文字幕| 国产精品久久久久…| 久久久久99这里有精品10| 99久久夜色精品国产网站| 亚洲国产精品无码久久| 久久久久亚洲AV成人网人人网站 | 国色天香久久久久久久小说 | 久久这里只有精品首页| 色综合久久久久久久久五月| 国产成人综合久久精品红| 国产成人精品久久亚洲高清不卡 | 伊人久久综合成人网| 伊人色综合久久天天网| 久久国产成人午夜aⅴ影院| 国产一区二区精品久久| 久久婷婷成人综合色综合| 久久人人爽人人爽人人片av麻烦 | 国产午夜精品理论片久久| 久久99热国产这有精品| 久久99精品久久久久久hb无码 | 久久午夜福利电影| 久久国产美女免费观看精品| 国内精品久久久久久久影视麻豆| 久久国产精品成人免费| 亚洲欧美精品伊人久久| 成人亚洲欧美久久久久| 久久久精品久久久久特色影视| 久久亚洲国产精品123区|