且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

<摘录>详谈高性能UDP服务器的开发

更新时间:2022-09-16 19:46:49

上一篇文章我详细介绍了如何开发一款高性能的TCP服务器的网络传输层.本章我将谈谈如何开发一个高性能的UDP服务器的网络层.UDP服务器的网络层开 发相对与TCP服务器来说要容易和简单的多,UDP服务器的大致流程为创建一个socket然后将其绑定到完成端口上并投递一定数量的recv操作.当有 数据到来时从完成队列中取出数据发送到接收队列中即可。
  测试结果如下:
    WindowsXP Professional,Intel Core Duo E4600 双核2.4G , 2G内存。同时30K个用户和该UDP服务器进行交互其CPU使用率为10%左右,内存占用7M左右。
  下面详细介绍该服务器的架构及流程:  
1. 首先介绍服务器的接收和发送缓存UDP_CONTEXT。

 1<摘录>详谈高性能UDP服务器的开发    class UDP_CONTEXT : protected NET_CONTEXT
 2<摘录>详谈高性能UDP服务器的开发    {
 3<摘录>详谈高性能UDP服务器的开发        friend class UdpSer;
 4<摘录>详谈高性能UDP服务器的开发    protected:
 5<摘录>详谈高性能UDP服务器的开发        IP_ADDR m_RemoteAddr;            //对端地址
 6<摘录>详谈高性能UDP服务器的开发
 7<摘录>详谈高性能UDP服务器的开发        enum
 8<摘录>详谈高性能UDP服务器的开发        {
 9<摘录>详谈高性能UDP服务器的开发            HEAP_SIZE = 1024 * 1024 * 5,
10<摘录>详谈高性能UDP服务器的开发            MAX_IDL_DATA = 10000,
11<摘录>详谈高性能UDP服务器的开发        }
;
12<摘录>详谈高性能UDP服务器的开发
13<摘录>详谈高性能UDP服务器的开发    public:
14<摘录>详谈高性能UDP服务器的开发        UDP_CONTEXT() {}
15<摘录>详谈高性能UDP服务器的开发        virtual ~UDP_CONTEXT() {}
16<摘录>详谈高性能UDP服务器的开发
17<摘录>详谈高性能UDP服务器的开发        void* operator new(size_t nSize);
18<摘录>详谈高性能UDP服务器的开发        void operator delete(void* p);
19<摘录>详谈高性能UDP服务器的开发
20<摘录>详谈高性能UDP服务器的开发    private:
21<摘录>详谈高性能UDP服务器的开发        static vector<UDP_CONTEXT* > s_IDLQue;
22<摘录>详谈高性能UDP服务器的开发        static CRITICAL_SECTION s_IDLQueLock;
23<摘录>详谈高性能UDP服务器的开发        static HANDLE s_hHeap;    
24<摘录>详谈高性能UDP服务器的开发    }
;

UDP_CONTEXT的实现流程和TCP_CONTEXT的实现流程大致相同,此处就不进行详细介绍。

2. UDP_RCV_DATA,当服务器收到客户端发来的数据时会将数据以UDP_RCV_DATA的形式放入到数据接收队列中,其声明如下:

 1<摘录>详谈高性能UDP服务器的开发    class DLLENTRY UDP_RCV_DATA
 2<摘录>详谈高性能UDP服务器的开发    {
 3<摘录>详谈高性能UDP服务器的开发        friend class UdpSer;
 4<摘录>详谈高性能UDP服务器的开发    public:
 5<摘录>详谈高性能UDP服务器的开发        CHAR* m_pData;                //数据缓冲区
 6<摘录>详谈高性能UDP服务器的开发        INT m_nLen;                    //数据的长度
 7<摘录>详谈高性能UDP服务器的开发        IP_ADDR m_PeerAddr;            //发送报文的地址
 8<摘录>详谈高性能UDP服务器的开发
 9<摘录>详谈高性能UDP服务器的开发        UDP_RCV_DATA(const CHAR* szBuf, int nLen, const IP_ADDR& PeerAddr);
10<摘录>详谈高性能UDP服务器的开发        ~UDP_RCV_DATA();
11<摘录>详谈高性能UDP服务器的开发
12<摘录>详谈高性能UDP服务器的开发        void* operator new(size_t nSize);
13<摘录>详谈高性能UDP服务器的开发        void operator delete(void* p);
14<摘录>详谈高性能UDP服务器的开发
15<摘录>详谈高性能UDP服务器的开发        enum
16<摘录>详谈高性能UDP服务器的开发        {
17<摘录>详谈高性能UDP服务器的开发            RCV_HEAP_SIZE = 1024 * 1024 *50,        //s_Heap堆的大小
18<摘录>详谈高性能UDP服务器的开发            DATA_HEAP_SIZE = 100 * 1024* 1024,    //s_DataHeap堆的大小
19<摘录>详谈高性能UDP服务器的开发            MAX_IDL_DATA = 250000,
20<摘录>详谈高性能UDP服务器的开发        }
;
21<摘录>详谈高性能UDP服务器的开发
22<摘录>详谈高性能UDP服务器的开发    private:
23<摘录>详谈高性能UDP服务器的开发        static vector<UDP_RCV_DATA* > s_IDLQue;
24<摘录>详谈高性能UDP服务器的开发        static CRITICAL_SECTION s_IDLQueLock;
25<摘录>详谈高性能UDP服务器的开发        static HANDLE s_DataHeap;        //数据缓冲区的堆
26<摘录>详谈高性能UDP服务器的开发        static HANDLE s_Heap;            //RCV_DATA的堆
27<摘录>详谈高性能UDP服务器的开发    }
;

UDP_RCV_DATA的实现和TCP_RCV_DATA大致相同, 此处不在详细介绍.

下面将主要介绍UdpSer类, 该类主要用来管理UDP服务.其定义如下:

 1<摘录>详谈高性能UDP服务器的开发    class DLLENTRY UdpSer
 2<摘录>详谈高性能UDP服务器的开发    {
 3<摘录>详谈高性能UDP服务器的开发    public:
 4<摘录>详谈高性能UDP服务器的开发        UdpSer();
 5<摘录>详谈高性能UDP服务器的开发        ~UdpSer();
 6<摘录>详谈高性能UDP服务器的开发
 7<摘录>详谈高性能UDP服务器的开发        /************************************************************************
 8<摘录>详谈高性能UDP服务器的开发        * Desc : 初始化静态资源,在申请UDP实例对象之前应先调用该函数, 否则程序无法正常运行
 9<摘录>详谈高性能UDP服务器的开发        ************************************************************************/

10<摘录>详谈高性能UDP服务器的开发        static void InitReource();
11<摘录>详谈高性能UDP服务器的开发
12<摘录>详谈高性能UDP服务器的开发        /************************************************************************
13<摘录>详谈高性能UDP服务器的开发        * Desc : 在释放UDP实例以后, 掉用该函数释放相关静态资源
14<摘录>详谈高性能UDP服务器的开发        ************************************************************************/

15<摘录>详谈高性能UDP服务器的开发        static void ReleaseReource();
16<摘录>详谈高性能UDP服务器的开发
17<摘录>详谈高性能UDP服务器的开发        //用指定本地地址和端口进行初始化
18<摘录>详谈高性能UDP服务器的开发        BOOL StartServer(const CHAR* szIp = "0.0.0.0", INT nPort = 0);
19<摘录>详谈高性能UDP服务器的开发
20<摘录>详谈高性能UDP服务器的开发        //从数据队列的头部获取一个接收数据, pCount不为null时返回队列的长度
21<摘录>详谈高性能UDP服务器的开发        UDP_RCV_DATA* GetRcvData(DWORD* pCount);
22<摘录>详谈高性能UDP服务器的开发
23<摘录>详谈高性能UDP服务器的开发        //向对端发送数据
24<摘录>详谈高性能UDP服务器的开发        BOOL SendData(const IP_ADDR& PeerAddr, const CHAR* szData, INT nLen);
25<摘录>详谈高性能UDP服务器的开发
26<摘录>详谈高性能UDP服务器的开发        /****************************************************
27<摘录>详谈高性能UDP服务器的开发        * Name : CloseServer()
28<摘录>详谈高性能UDP服务器的开发        * Desc : 关闭服务器
29<摘录>详谈高性能UDP服务器的开发        ****************************************************/

30<摘录>详谈高性能UDP服务器的开发        void CloseServer();
31<摘录>详谈高性能UDP服务器的开发
32<摘录>详谈高性能UDP服务器的开发    protected:
33<摘录>详谈高性能UDP服务器的开发        SOCKET m_hSock;
34<摘录>详谈高性能UDP服务器的开发        vector<UDP_RCV_DATA* > m_RcvDataQue;                //接收数据队列
35<摘录>详谈高性能UDP服务器的开发        CRITICAL_SECTION m_RcvDataLock;                        //访问m_RcvDataQue的互斥锁
36<摘录>详谈高性能UDP服务器的开发        long volatile m_bThreadRun;                                //是否允许后台线程继续运行
37<摘录>详谈高性能UDP服务器的开发        BOOL m_bSerRun;                                            //服务器是否正在运行
38<摘录>详谈高性能UDP服务器的开发
39<摘录>详谈高性能UDP服务器的开发        HANDLE *m_pThreads;                //线程数组
40<摘录>详谈高性能UDP服务器的开发        HANDLE m_hCompletion;                    //完成端口句柄
41<摘录>详谈高性能UDP服务器的开发
42<摘录>详谈高性能UDP服务器的开发        void ReadCompletion(BOOL bSuccess, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped);
43<摘录>详谈高性能UDP服务器的开发
44<摘录>详谈高性能UDP服务器的开发        /****************************************************
45<摘录>详谈高性能UDP服务器的开发        * Name : WorkThread()
46<摘录>详谈高性能UDP服务器的开发        * Desc : I/O 后台管理线程
47<摘录>详谈高性能UDP服务器的开发        ****************************************************/

48<摘录>详谈高性能UDP服务器的开发        static UINT WINAPI WorkThread(LPVOID lpParam);
49<摘录>详谈高性能UDP服务器的开发    }
;


1. InitReource() 主要对相关的静态资源进行初始化.其实大致和TcpServer::InitReource()大致相同.在UdpSer实例使用之前必须调用该函数进行静态资源的初始化, 否则服务器无法正常使用.

2.ReleaseReource() 主要对相关静态资源进行释放.只有在应用程序结束时才能调用该函数进行静态资源的释放.

3. StartServer() 
该函数的主要功能启动一个UDP服务.其大致流程为先创建服务器UDP socket, 将其绑定到完成端口上然后投递一定数量的recv操作以接收客户端的数据.其实现如下:

 1<摘录>详谈高性能UDP服务器的开发    BOOL UdpSer::StartServer(const CHAR* szIp /* =  */, INT nPort /* = 0 */)
 2<摘录>详谈高性能UDP服务器的开发    {
 3<摘录>详谈高性能UDP服务器的开发        BOOL bRet = TRUE;
 4<摘录>详谈高性能UDP服务器的开发        const int RECV_COUNT = 500;
 5<摘录>详谈高性能UDP服务器的开发        WSABUF RcvBuf = { NULL, 0 };
 6<摘录>详谈高性能UDP服务器的开发        DWORD dwBytes = 0;
 7<摘录>详谈高性能UDP服务器的开发        DWORD dwFlag = 0;
 8<摘录>详谈高性能UDP服务器的开发        INT nAddrLen = sizeof(IP_ADDR);
 9<摘录>详谈高性能UDP服务器的开发        INT iErrCode = 0;
10<摘录>详谈高性能UDP服务器的开发
11<摘录>详谈高性能UDP服务器的开发        try
12<摘录>详谈高性能UDP服务器的开发        {
13<摘录>详谈高性能UDP服务器的开发            if (m_bSerRun)
14<摘录>详谈高性能UDP服务器的开发            {
15<摘录>详谈高性能UDP服务器的开发                THROW_LINE;
16<摘录>详谈高性能UDP服务器的开发            }

17<摘录>详谈高性能UDP服务器的开发
18<摘录>详谈高性能UDP服务器的开发            m_bSerRun = TRUE;
19<摘录>详谈高性能UDP服务器的开发            m_hSock = WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
20<摘录>详谈高性能UDP服务器的开发            if (INVALID_SOCKET == m_hSock)
21<摘录>详谈高性能UDP服务器的开发            {
22<摘录>详谈高性能UDP服务器的开发                THROW_LINE;
23<摘录>详谈高性能UDP服务器的开发            }

24<摘录>详谈高性能UDP服务器的开发            ULONG ul = 1;
25<摘录>详谈高性能UDP服务器的开发            ioctlsocket(m_hSock, FIONBIO, &ul);
26<摘录>详谈高性能UDP服务器的开发
27<摘录>详谈高性能UDP服务器的开发            //设置为地址重用,优点在于服务器关闭后可以立即启用
28<摘录>详谈高性能UDP服务器的开发            int nOpt = 1;
29<摘录>详谈高性能UDP服务器的开发            setsockopt(m_hSock, SOL_SOCKET, SO_REUSEADDR, (char*)&nOpt, sizeof(nOpt));
30<摘录>详谈高性能UDP服务器的开发
31<摘录>详谈高性能UDP服务器的开发            //关闭系统缓存,使用自己的缓存以防止数据的复制操作
32<摘录>详谈高性能UDP服务器的开发            INT nZero = 0;
33<摘录>详谈高性能UDP服务器的开发            setsockopt(m_hSock, SOL_SOCKET, SO_SNDBUF, (char*)&nZero, sizeof(nZero));
34<摘录>详谈高性能UDP服务器的开发            setsockopt(m_hSock, SOL_SOCKET, SO_RCVBUF, (CHAR*)&nZero, sizeof(nZero));
35<摘录>详谈高性能UDP服务器的开发
36<摘录>详谈高性能UDP服务器的开发            IP_ADDR addr(szIp, nPort);
37<摘录>详谈高性能UDP服务器的开发            if (SOCKET_ERROR == bind(m_hSock, (sockaddr*)&addr, sizeof(addr)))
38<摘录>详谈高性能UDP服务器的开发            {
39<摘录>详谈高性能UDP服务器的开发                closesocket(m_hSock);
40<摘录>详谈高性能UDP服务器的开发                THROW_LINE;
41<摘录>详谈高性能UDP服务器的开发            }

42<摘录>详谈高性能UDP服务器的开发
43<摘录>详谈高性能UDP服务器的开发            //将SOCKET绑定到完成端口上
44<摘录>详谈高性能UDP服务器的开发            CreateIoCompletionPort((HANDLE)m_hSock, m_hCompletion, 00);
45<摘录>详谈高性能UDP服务器的开发
46<摘录>详谈高性能UDP服务器的开发            //投递读操作
47<摘录>详谈高性能UDP服务器的开发            for (int nIndex = 0; nIndex < RECV_COUNT; nIndex++)
48<摘录>详谈高性能UDP服务器的开发            {
49<摘录>详谈高性能UDP服务器的开发                UDP_CONTEXT* pRcvContext = new UDP_CONTEXT();
50<摘录>详谈高性能UDP服务器的开发                if (pRcvContext && pRcvContext->m_pBuf)
51<摘录>详谈高性能UDP服务器的开发                {
52<摘录>详谈高性能UDP服务器的开发                    dwFlag = 0;
53<摘录>详谈高性能UDP服务器的开发                    dwBytes = 0;
54<摘录>详谈高性能UDP服务器的开发                    nAddrLen = sizeof(IP_ADDR);
55<摘录>详谈高性能UDP服务器的开发                    RcvBuf.buf = pRcvContext->m_pBuf;
56<摘录>详谈高性能UDP服务器的开发                    RcvBuf.len = UDP_CONTEXT::S_PAGE_SIZE;
57<摘录>详谈高性能UDP服务器的开发
58<摘录>详谈高性能UDP服务器的开发                    pRcvContext->m_hSock = m_hSock;
59<摘录>详谈高性能UDP服务器的开发                    pRcvContext->m_nOperation = OP_READ;            
60<摘录>详谈高性能UDP服务器的开发                    iErrCode = WSARecvFrom(pRcvContext->m_hSock, &RcvBuf, 1&dwBytes, &dwFlag, (sockaddr*)(&pRcvContext->m_RemoteAddr)
61<摘录>详谈高性能UDP服务器的开发                        , &nAddrLen, &(pRcvContext->m_ol), NULL);
62<摘录>详谈高性能UDP服务器的开发                    if (SOCKET_ERROR == iErrCode && ERROR_IO_PENDING != WSAGetLastError())
63<摘录>详谈高性能UDP服务器的开发                    {
64<摘录>详谈高性能UDP服务器的开发                        delete pRcvContext;
65<摘录>详谈高性能UDP服务器的开发                        pRcvContext = NULL;
66<摘录>详谈高性能UDP服务器的开发                    }

67<摘录>详谈高性能UDP服务器的开发                }

68<摘录>详谈高性能UDP服务器的开发                else
69<摘录>详谈高性能UDP服务器的开发                {
70<摘录>详谈高性能UDP服务器的开发                    delete pRcvContext;
71<摘录>详谈高性能UDP服务器的开发                }

72<摘录>详谈高性能UDP服务器的开发            }

73<摘录>详谈高性能UDP服务器的开发        }

74<摘录>详谈高性能UDP服务器的开发        catch (const long &lErrLine)
75<摘录>详谈高性能UDP服务器的开发        {            
76<摘录>详谈高性能UDP服务器的开发            bRet = FALSE;
77<摘录>详谈高性能UDP服务器的开发            _TRACE("Exp : %s -- %ld ", __FILE__, lErrLine);            
78<摘录>详谈高性能UDP服务器的开发        }

79<摘录>详谈高性能UDP服务器的开发
80<摘录>详谈高性能UDP服务器的开发        return bRet;
81<摘录>详谈高性能UDP服务器的开发    }

4. GetRcvData(), 从接收队列中取出一个数据包.

 1<摘录>详谈高性能UDP服务器的开发    UDP_RCV_DATA *UdpSer::GetRcvData(DWORD* pCount)
 2<摘录>详谈高性能UDP服务器的开发    {
 3<摘录>详谈高性能UDP服务器的开发        UDP_RCV_DATA* pRcvData = NULL;
 4<摘录>详谈高性能UDP服务器的开发
 5<摘录>详谈高性能UDP服务器的开发        EnterCriticalSection(&m_RcvDataLock);
 6<摘录>详谈高性能UDP服务器的开发        vector<UDP_RCV_DATA* >::iterator iterRcv = m_RcvDataQue.begin();
 7<摘录>详谈高性能UDP服务器的开发        if (iterRcv != m_RcvDataQue.end())
 8<摘录>详谈高性能UDP服务器的开发        {
 9<摘录>详谈高性能UDP服务器的开发            pRcvData = *iterRcv;
10<摘录>详谈高性能UDP服务器的开发            m_RcvDataQue.erase(iterRcv);
11<摘录>详谈高性能UDP服务器的开发        }

12<摘录>详谈高性能UDP服务器的开发
13<摘录>详谈高性能UDP服务器的开发        if (pCount)
14<摘录>详谈高性能UDP服务器的开发        {
15<摘录>详谈高性能UDP服务器的开发            *pCount = (DWORD)(m_RcvDataQue.size());
16<摘录>详谈高性能UDP服务器的开发        }

17<摘录>详谈高性能UDP服务器的开发        LeaveCriticalSection(&m_RcvDataLock);
18<摘录>详谈高性能UDP服务器的开发
19<摘录>详谈高性能UDP服务器的开发        return pRcvData;
20<摘录>详谈高性能UDP服务器的开发    }


5. SendData() 发送指定长度的数据包.

 1<摘录>详谈高性能UDP服务器的开发    BOOL UdpSer::SendData(const IP_ADDR& PeerAddr, const CHAR* szData, INT nLen)
 2<摘录>详谈高性能UDP服务器的开发    {
 3<摘录>详谈高性能UDP服务器的开发        BOOL bRet = TRUE;
 4<摘录>详谈高性能UDP服务器的开发        try
 5<摘录>详谈高性能UDP服务器的开发        {
 6<摘录>详谈高性能UDP服务器的开发            if (nLen >= 1500)
 7<摘录>详谈高性能UDP服务器的开发            {
 8<摘录>详谈高性能UDP服务器的开发                THROW_LINE;
 9<摘录>详谈高性能UDP服务器的开发            }

10<摘录>详谈高性能UDP服务器的开发
11<摘录>详谈高性能UDP服务器的开发            UDP_CONTEXT* pSendContext = new UDP_CONTEXT();
12<摘录>详谈高性能UDP服务器的开发            if (pSendContext && pSendContext->m_pBuf)
13<摘录>详谈高性能UDP服务器的开发            {
14<摘录>详谈高性能UDP服务器的开发                pSendContext->m_nOperation = OP_WRITE;
15<摘录>详谈高性能UDP服务器的开发                pSendContext->m_RemoteAddr = PeerAddr;        
16<摘录>详谈高性能UDP服务器的开发
17<摘录>详谈高性能UDP服务器的开发                memcpy(pSendContext->m_pBuf, szData, nLen);
18<摘录>详谈高性能UDP服务器的开发
19<摘录>详谈高性能UDP服务器的开发                WSABUF SendBuf = { NULL, 0 };
20<摘录>详谈高性能UDP服务器的开发                DWORD dwBytes = 0;
21<摘录>详谈高性能UDP服务器的开发                SendBuf.buf = pSendContext->m_pBuf;
22<摘录>详谈高性能UDP服务器的开发                SendBuf.len = nLen;
23<摘录>详谈高性能UDP服务器的开发
24<摘录>详谈高性能UDP服务器的开发                INT iErrCode = WSASendTo(m_hSock, &SendBuf, 1&dwBytes, 0, (sockaddr*)&PeerAddr, sizeof(PeerAddr), &(pSendContext->m_ol), NULL);
25<摘录>详谈高性能UDP服务器的开发                if (SOCKET_ERROR == iErrCode && ERROR_IO_PENDING != WSAGetLastError())
26<摘录>详谈高性能UDP服务器的开发                {
27<摘录>详谈高性能UDP服务器的开发                    delete pSendContext;
28<摘录>详谈高性能UDP服务器的开发                    THROW_LINE;
29<摘录>详谈高性能UDP服务器的开发                }

30<摘录>详谈高性能UDP服务器的开发            }

31<摘录>详谈高性能UDP服务器的开发            else
32<摘录>详谈高性能UDP服务器的开发            {
33<摘录>详谈高性能UDP服务器的开发                delete pSendContext;
34<摘录>详谈高性能UDP服务器的开发                THROW_LINE;
35<摘录>详谈高性能UDP服务器的开发            }

36<摘录>详谈高性能UDP服务器的开发        }

37<摘录>详谈高性能UDP服务器的开发        catch (const long &lErrLine)
38<摘录>详谈高性能UDP服务器的开发        {
39<摘录>详谈高性能UDP服务器的开发            bRet = FALSE;
40<摘录>详谈高性能UDP服务器的开发            _TRACE("Exp : %s -- %ld ", __FILE__, lErrLine);            
41<摘录>详谈高性能UDP服务器的开发        }

42<摘录>详谈高性能UDP服务器的开发
43<摘录>详谈高性能UDP服务器的开发        return bRet;
44<摘录>详谈高性能UDP服务器的开发    }


6. CloseServer() 关闭服务

1<摘录>详谈高性能UDP服务器的开发    void UdpSer::CloseServer()
2<摘录>详谈高性能UDP服务器的开发    {
3<摘录>详谈高性能UDP服务器的开发        m_bSerRun = FALSE;
4<摘录>详谈高性能UDP服务器的开发        closesocket(m_hSock);
5<摘录>详谈高性能UDP服务器的开发    }


7. WorkThread() 在完成端口上工作的后台线程

 1<摘录>详谈高性能UDP服务器的开发    UINT WINAPI UdpSer::WorkThread(LPVOID lpParam)
 2<摘录>详谈高性能UDP服务器的开发    {
 3<摘录>详谈高性能UDP服务器的开发        UdpSer *pThis = (UdpSer *)lpParam;
 4<摘录>详谈高性能UDP服务器的开发        DWORD dwTrans = 0, dwKey = 0;
 5<摘录>详谈高性能UDP服务器的开发        LPOVERLAPPED pOl = NULL;
 6<摘录>详谈高性能UDP服务器的开发        UDP_CONTEXT *pContext = NULL;
 7<摘录>详谈高性能UDP服务器的开发
 8<摘录>详谈高性能UDP服务器的开发        while (TRUE)
 9<摘录>详谈高性能UDP服务器的开发        {
10<摘录>详谈高性能UDP服务器的开发            BOOL bOk = GetQueuedCompletionStatus(pThis->m_hCompletion, &dwTrans, &dwKey, (LPOVERLAPPED *)&pOl, WSA_INFINITE);
11<摘录>详谈高性能UDP服务器的开发
12<摘录>详谈高性能UDP服务器的开发            pContext = CONTAINING_RECORD(pOl, UDP_CONTEXT, m_ol);
13<摘录>详谈高性能UDP服务器的开发            if (pContext)
14<摘录>详谈高性能UDP服务器的开发            {
15<摘录>详谈高性能UDP服务器的开发                switch (pContext->m_nOperation)
16<摘录>详谈高性能UDP服务器的开发                {
17<摘录>详谈高性能UDP服务器的开发                case OP_READ:
18<摘录>详谈高性能UDP服务器的开发                    pThis->ReadCompletion(bOk, dwTrans, pOl);
19<摘录>详谈高性能UDP服务器的开发                    break;
20<摘录>详谈高性能UDP服务器的开发                case OP_WRITE:
21<摘录>详谈高性能UDP服务器的开发                    delete pContext;
22<摘录>详谈高性能UDP服务器的开发                    pContext = NULL;
23<摘录>详谈高性能UDP服务器的开发                    break;
24<摘录>详谈高性能UDP服务器的开发                }

25<摘录>详谈高性能UDP服务器的开发            }

26<摘录>详谈高性能UDP服务器的开发
27<摘录>详谈高性能UDP服务器的开发            if (FALSE == InterlockedExchangeAdd(&(pThis->m_bThreadRun), 0))
28<摘录>详谈高性能UDP服务器的开发            {
29<摘录>详谈高性能UDP服务器的开发                break;
30<摘录>详谈高性能UDP服务器的开发            }

31<摘录>详谈高性能UDP服务器的开发        }

32<摘录>详谈高性能UDP服务器的开发
33<摘录>详谈高性能UDP服务器的开发        return 0;
34<摘录>详谈高性能UDP服务器的开发    }


8.ReadCompletion(), 接收操作完成后的回调函数

 1<摘录>详谈高性能UDP服务器的开发    void UdpSer::ReadCompletion(BOOL bSuccess, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
 2<摘录>详谈高性能UDP服务器的开发    {
 3<摘录>详谈高性能UDP服务器的开发        UDP_CONTEXT* pRcvContext = CONTAINING_RECORD(lpOverlapped, UDP_CONTEXT, m_ol);
 4<摘录>详谈高性能UDP服务器的开发        WSABUF RcvBuf = { NULL, 0 };
 5<摘录>详谈高性能UDP服务器的开发        DWORD dwBytes = 0;
 6<摘录>详谈高性能UDP服务器的开发        DWORD dwFlag = 0;
 7<摘录>详谈高性能UDP服务器的开发        INT nAddrLen = sizeof(IP_ADDR);
 8<摘录>详谈高性能UDP服务器的开发        INT iErrCode = 0;
 9<摘录>详谈高性能UDP服务器的开发
10<摘录>详谈高性能UDP服务器的开发        if (TRUE == bSuccess && dwNumberOfBytesTransfered <= UDP_CONTEXT::S_PAGE_SIZE)
11<摘录>详谈高性能UDP服务器的开发        {
12<摘录>详谈高性能UDP服务器的开发#ifdef _XML_NET_
13<摘录>详谈高性能UDP服务器的开发            EnterCriticalSection(&m_RcvDataLock);
14<摘录>详谈高性能UDP服务器的开发
15<摘录>详谈高性能UDP服务器的开发            UDP_RCV_DATA* pRcvData = new UDP_RCV_DATA(pRcvContext->m_pBuf, dwNumberOfBytesTransfered, pRcvContext->m_RemoteAddr);
16<摘录>详谈高性能UDP服务器的开发            if (pRcvData && pRcvData->m_pData)
17<摘录>详谈高性能UDP服务器的开发            {
18<摘录>详谈高性能UDP服务器的开发                m_RcvDataQue.push_back(pRcvData);
19<摘录>详谈高性能UDP服务器的开发            }
    
20<摘录>详谈高性能UDP服务器的开发            else
21<摘录>详谈高性能UDP服务器的开发            {
22<摘录>详谈高性能UDP服务器的开发                delete pRcvData;
23<摘录>详谈高性能UDP服务器的开发            }

24<摘录>详谈高性能UDP服务器的开发
25<摘录>详谈高性能UDP服务器的开发            LeaveCriticalSection(&m_RcvDataLock);
26<摘录>详谈高性能UDP服务器的开发#else
27<摘录>详谈高性能UDP服务器的开发            if (dwNumberOfBytesTransfered >= sizeof(PACKET_HEAD))
28<摘录>详谈高性能UDP服务器的开发            {
29<摘录>详谈高性能UDP服务器的开发                EnterCriticalSection(&m_RcvDataLock);
30<摘录>详谈高性能UDP服务器的开发
31<摘录>详谈高性能UDP服务器的开发                UDP_RCV_DATA* pRcvData = new UDP_RCV_DATA(pRcvContext->m_pBuf, dwNumberOfBytesTransfered, pRcvContext->m_RemoteAddr);
32<摘录>详谈高性能UDP服务器的开发                if (pRcvData && pRcvData->m_pData)
33<摘录>详谈高性能UDP服务器的开发                {
34<摘录>详谈高性能UDP服务器的开发                    m_RcvDataQue.push_back(pRcvData);
35<摘录>详谈高性能UDP服务器的开发                }
    
36<摘录>详谈高性能UDP服务器的开发                else
37<摘录>详谈高性能UDP服务器的开发                {
38<摘录>详谈高性能UDP服务器的开发                    delete pRcvData;
39<摘录>详谈高性能UDP服务器的开发                }

40<摘录>详谈高性能UDP服务器的开发
41<摘录>详谈高性能UDP服务器的开发                LeaveCriticalSection(&m_RcvDataLock);
42<摘录>详谈高性能UDP服务器的开发            }

43<摘录>详谈高性能UDP服务器的开发#endif
44<摘录>详谈高性能UDP服务器的开发
45<摘录>详谈高性能UDP服务器的开发            //投递下一个接收操作
46<摘录>详谈高性能UDP服务器的开发            RcvBuf.buf = pRcvContext->m_pBuf;
47<摘录>详谈高性能UDP服务器的开发            RcvBuf.len = UDP_CONTEXT::S_PAGE_SIZE;
48<摘录>详谈高性能UDP服务器的开发
49<摘录>详谈高性能UDP服务器的开发            iErrCode = WSARecvFrom(pRcvContext->m_hSock, &RcvBuf, 1&dwBytes, &dwFlag, (sockaddr*)(&pRcvContext->m_RemoteAddr)
50<摘录>详谈高性能UDP服务器的开发                , &nAddrLen, &(pRcvContext->m_ol), NULL);
51<摘录>详谈高性能UDP服务器的开发            if (SOCKET_ERROR == iErrCode && ERROR_IO_PENDING != WSAGetLastError())
52<摘录>详谈高性能UDP服务器的开发            {
53<摘录>详谈高性能UDP服务器的开发                ATLTRACE("\r\n%s -- %ld dwNumberOfBytesTransfered = %ld, LAST_ERR = %ld"
54<摘录>详谈高性能UDP服务器的开发                    , __FILE__, __LINE__, dwNumberOfBytesTransfered, WSAGetLastError());
55<摘录>详谈高性能UDP服务器的开发                delete pRcvContext;
56<摘录>详谈高性能UDP服务器的开发                pRcvContext = NULL;
57<摘录>详谈高性能UDP服务器的开发            }

58<摘录>详谈高性能UDP服务器的开发        }

59<摘录>详谈高性能UDP服务器的开发        else
60<摘录>详谈高性能UDP服务器的开发        {
61<摘录>详谈高性能UDP服务器的开发            delete pRcvContext;
62<摘录>详谈高性能UDP服务器的开发        }

63<摘录>详谈高性能UDP服务器的开发    }