<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    <摘錄>詳談高性能UDP服務器的開發

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    上一篇文章我詳細介紹了如何開發一款高性能的TCP服務器的網絡傳輸層.本章我將談談如何開發一個高性能的UDP服務器的網絡層.UDP服務器的網絡層開 發相對與TCP服務器來說要容易和簡單的多,UDP服務器的大致流程為創建一個socket然后將其綁定到完成端口上并投遞一定數量的recv操作.當有 數據到來時從完成隊列中取出數據發送到接收隊列中即可。
      測試結果如下:
        WindowsXP Professional,Intel Core Duo E4600 雙核2.4G , 2G內存。同時30K個用戶和該UDP服務器進行交互其CPU使用率為10%左右,內存占用7M左右。
      下面詳細介紹該服務器的架構及流程:  
    1. 首先介紹服務器的接收和發送緩存UDP_CONTEXT。

     1RFID設備管理軟件    class UDP_CONTEXT : protected NET_CONTEXT
     2RFID設備管理軟件    {
     3RFID設備管理軟件        friend class UdpSer;
     4RFID設備管理軟件    protected:
     5RFID設備管理軟件        IP_ADDR m_RemoteAddr;            //對端地址
     6RFID設備管理軟件
     7RFID設備管理軟件        enum
     8RFID設備管理軟件        {
     9RFID設備管理軟件            HEAP_SIZE = 1024 * 1024 * 5,
    10RFID設備管理軟件            MAX_IDL_DATA = 10000,
    11RFID設備管理軟件        }
    ;
    12RFID設備管理軟件
    13RFID設備管理軟件    public:
    14RFID設備管理軟件        UDP_CONTEXT() {}
    15RFID設備管理軟件        virtual ~UDP_CONTEXT() {}
    16RFID設備管理軟件
    17RFID設備管理軟件        void* operator new(size_t nSize);
    18RFID設備管理軟件        void operator delete(void* p);
    19RFID設備管理軟件
    20RFID設備管理軟件    private:
    21RFID設備管理軟件        static vector<UDP_CONTEXT* > s_IDLQue;
    22RFID設備管理軟件        static CRITICAL_SECTION s_IDLQueLock;
    23RFID設備管理軟件        static HANDLE s_hHeap;    
    24RFID設備管理軟件    }
    ;

    UDP_CONTEXT的實現流程和TCP_CONTEXT的實現流程大致相同,此處就不進行詳細介紹。

    2. UDP_RCV_DATA,當服務器收到客戶端發來的數據時會將數據以UDP_RCV_DATA的形式放入到數據接收隊列中,其聲明如下:

     1RFID設備管理軟件    class DLLENTRY UDP_RCV_DATA
     2RFID設備管理軟件    {
     3RFID設備管理軟件        friend class UdpSer;
     4RFID設備管理軟件    public:
     5RFID設備管理軟件        CHAR* m_pData;                //數據緩沖區
     6RFID設備管理軟件        INT m_nLen;                    //數據的長度
     7RFID設備管理軟件        IP_ADDR m_PeerAddr;            //發送報文的地址
     8RFID設備管理軟件
     9RFID設備管理軟件        UDP_RCV_DATA(const CHAR* szBuf, int nLen, const IP_ADDR& PeerAddr);
    10RFID設備管理軟件        ~UDP_RCV_DATA();
    11RFID設備管理軟件
    12RFID設備管理軟件        void* operator new(size_t nSize);
    13RFID設備管理軟件        void operator delete(void* p);
    14RFID設備管理軟件
    15RFID設備管理軟件        enum
    16RFID設備管理軟件        {
    17RFID設備管理軟件            RCV_HEAP_SIZE = 1024 * 1024 *50,        //s_Heap堆的大小
    18RFID設備管理軟件            DATA_HEAP_SIZE = 100 * 1024* 1024,    //s_DataHeap堆的大小
    19RFID設備管理軟件            MAX_IDL_DATA = 250000,
    20RFID設備管理軟件        }
    ;
    21RFID設備管理軟件
    22RFID設備管理軟件    private:
    23RFID設備管理軟件        static vector<UDP_RCV_DATA* > s_IDLQue;
    24RFID設備管理軟件        static CRITICAL_SECTION s_IDLQueLock;
    25RFID設備管理軟件        static HANDLE s_DataHeap;        //數據緩沖區的堆
    26RFID設備管理軟件        static HANDLE s_Heap;            //RCV_DATA的堆
    27RFID設備管理軟件    }
    ;

    UDP_RCV_DATA的實現和TCP_RCV_DATA大致相同, 此處不在詳細介紹.

    下面將主要介紹UdpSer類, 該類主要用來管理UDP服務.其定義如下:

     1RFID設備管理軟件    class DLLENTRY UdpSer
     2RFID設備管理軟件    {
     3RFID設備管理軟件    public:
     4RFID設備管理軟件        UdpSer();
     5RFID設備管理軟件        ~UdpSer();
     6RFID設備管理軟件
     7RFID設備管理軟件        /************************************************************************
     8RFID設備管理軟件        * Desc : 初始化靜態資源,在申請UDP實例對象之前應先調用該函數, 否則程序無法正常運行
     9RFID設備管理軟件        ************************************************************************/

    10RFID設備管理軟件        static void InitReource();
    11RFID設備管理軟件
    12RFID設備管理軟件        /************************************************************************
    13RFID設備管理軟件        * Desc : 在釋放UDP實例以后, 掉用該函數釋放相關靜態資源
    14RFID設備管理軟件        ************************************************************************/

    15RFID設備管理軟件        static void ReleaseReource();
    16RFID設備管理軟件
    17RFID設備管理軟件        //用指定本地地址和端口進行初始化
    18RFID設備管理軟件        BOOL StartServer(const CHAR* szIp = "0.0.0.0", INT nPort = 0);
    19RFID設備管理軟件
    20RFID設備管理軟件        //從數據隊列的頭部獲取一個接收數據, pCount不為null時返回隊列的長度
    21RFID設備管理軟件        UDP_RCV_DATA* GetRcvData(DWORD* pCount);
    22RFID設備管理軟件
    23RFID設備管理軟件        //向對端發送數據
    24RFID設備管理軟件        BOOL SendData(const IP_ADDR& PeerAddr, const CHAR* szData, INT nLen);
    25RFID設備管理軟件
    26RFID設備管理軟件        /****************************************************
    27RFID設備管理軟件        * Name : CloseServer()
    28RFID設備管理軟件        * Desc : 關閉服務器
    29RFID設備管理軟件        ****************************************************/

    30RFID設備管理軟件        void CloseServer();
    31RFID設備管理軟件
    32RFID設備管理軟件    protected:
    33RFID設備管理軟件        SOCKET m_hSock;
    34RFID設備管理軟件        vector<UDP_RCV_DATA* > m_RcvDataQue;                //接收數據隊列
    35RFID設備管理軟件        CRITICAL_SECTION m_RcvDataLock;                        //訪問m_RcvDataQue的互斥鎖
    36RFID設備管理軟件        long volatile m_bThreadRun;                                //是否允許后臺線程繼續運行
    37RFID設備管理軟件        BOOL m_bSerRun;                                            //服務器是否正在運行
    38RFID設備管理軟件
    39RFID設備管理軟件        HANDLE *m_pThreads;                //線程數組
    40RFID設備管理軟件        HANDLE m_hCompletion;                    //完成端口句柄
    41RFID設備管理軟件
    42RFID設備管理軟件        void ReadCompletion(BOOL bSuccess, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped);
    43RFID設備管理軟件
    44RFID設備管理軟件        /****************************************************
    45RFID設備管理軟件        * Name : WorkThread()
    46RFID設備管理軟件        * Desc : I/O 后臺管理線程
    47RFID設備管理軟件        ****************************************************/

    48RFID設備管理軟件        static UINT WINAPI WorkThread(LPVOID lpParam);
    49RFID設備管理軟件    }
    ;


    1. InitReource() 主要對相關的靜態資源進行初始化.其實大致和TcpServer::InitReource()大致相同.在UdpSer實例使用之前必須調用該函數進行靜態資源的初始化, 否則服務器無法正常使用.

    2.ReleaseReource() 主要對相關靜態資源進行釋放.只有在應用程序結束時才能調用該函數進行靜態資源的釋放.

    3. StartServer() 
    該函數的主要功能啟動一個UDP服務.其大致流程為先創建服務器UDP socket, 將其綁定到完成端口上然后投遞一定數量的recv操作以接收客戶端的數據.其實現如下:

     1RFID設備管理軟件    BOOL UdpSer::StartServer(const CHAR* szIp /* =  */, INT nPort /* = 0 */)
     2RFID設備管理軟件    {
     3RFID設備管理軟件        BOOL bRet = TRUE;
     4RFID設備管理軟件        const int RECV_COUNT = 500;
     5RFID設備管理軟件        WSABUF RcvBuf = { NULL, 0 };
     6RFID設備管理軟件        DWORD dwBytes = 0;
     7RFID設備管理軟件        DWORD dwFlag = 0;
     8RFID設備管理軟件        INT nAddrLen = sizeof(IP_ADDR);
     9RFID設備管理軟件        INT iErrCode = 0;
    10RFID設備管理軟件
    11RFID設備管理軟件        try
    12RFID設備管理軟件        {
    13RFID設備管理軟件            if (m_bSerRun)
    14RFID設備管理軟件            {
    15RFID設備管理軟件                THROW_LINE;
    16RFID設備管理軟件            }

    17RFID設備管理軟件
    18RFID設備管理軟件            m_bSerRun = TRUE;
    19RFID設備管理軟件            m_hSock = WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
    20RFID設備管理軟件            if (INVALID_SOCKET == m_hSock)
    21RFID設備管理軟件            {
    22RFID設備管理軟件                THROW_LINE;
    23RFID設備管理軟件            }

    24RFID設備管理軟件            ULONG ul = 1;
    25RFID設備管理軟件            ioctlsocket(m_hSock, FIONBIO, &ul);
    26RFID設備管理軟件
    27RFID設備管理軟件            //設置為地址重用,優點在于服務器關閉后可以立即啟用
    28RFID設備管理軟件            int nOpt = 1;
    29RFID設備管理軟件            setsockopt(m_hSock, SOL_SOCKET, SO_REUSEADDR, (char*)&nOpt, sizeof(nOpt));
    30RFID設備管理軟件
    31RFID設備管理軟件            //關閉系統緩存,使用自己的緩存以防止數據的復制操作
    32RFID設備管理軟件            INT nZero = 0;
    33RFID設備管理軟件            setsockopt(m_hSock, SOL_SOCKET, SO_SNDBUF, (char*)&nZero, sizeof(nZero));
    34RFID設備管理軟件            setsockopt(m_hSock, SOL_SOCKET, SO_RCVBUF, (CHAR*)&nZero, sizeof(nZero));
    35RFID設備管理軟件
    36RFID設備管理軟件            IP_ADDR addr(szIp, nPort);
    37RFID設備管理軟件            if (SOCKET_ERROR == bind(m_hSock, (sockaddr*)&addr, sizeof(addr)))
    38RFID設備管理軟件            {
    39RFID設備管理軟件                closesocket(m_hSock);
    40RFID設備管理軟件                THROW_LINE;
    41RFID設備管理軟件            }

    42RFID設備管理軟件
    43RFID設備管理軟件            //將SOCKET綁定到完成端口上
    44RFID設備管理軟件            CreateIoCompletionPort((HANDLE)m_hSock, m_hCompletion, 00);
    45RFID設備管理軟件
    46RFID設備管理軟件            //投遞讀操作
    47RFID設備管理軟件            for (int nIndex = 0; nIndex < RECV_COUNT; nIndex++)
    48RFID設備管理軟件            {
    49RFID設備管理軟件                UDP_CONTEXT* pRcvContext = new UDP_CONTEXT();
    50RFID設備管理軟件                if (pRcvContext && pRcvContext->m_pBuf)
    51RFID設備管理軟件                {
    52RFID設備管理軟件                    dwFlag = 0;
    53RFID設備管理軟件                    dwBytes = 0;
    54RFID設備管理軟件                    nAddrLen = sizeof(IP_ADDR);
    55RFID設備管理軟件                    RcvBuf.buf = pRcvContext->m_pBuf;
    56RFID設備管理軟件                    RcvBuf.len = UDP_CONTEXT::S_PAGE_SIZE;
    57RFID設備管理軟件
    58RFID設備管理軟件                    pRcvContext->m_hSock = m_hSock;
    59RFID設備管理軟件                    pRcvContext->m_nOperation = OP_READ;            
    60RFID設備管理軟件                    iErrCode = WSARecvFrom(pRcvContext->m_hSock, &RcvBuf, 1&dwBytes, &dwFlag, (sockaddr*)(&pRcvContext->m_RemoteAddr)
    61RFID設備管理軟件                        , &nAddrLen, &(pRcvContext->m_ol), NULL);
    62RFID設備管理軟件                    if (SOCKET_ERROR == iErrCode && ERROR_IO_PENDING != WSAGetLastError())
    63RFID設備管理軟件                    {
    64RFID設備管理軟件                        delete pRcvContext;
    65RFID設備管理軟件                        pRcvContext = NULL;
    66RFID設備管理軟件                    }

    67RFID設備管理軟件                }

    68RFID設備管理軟件                else
    69RFID設備管理軟件                {
    70RFID設備管理軟件                    delete pRcvContext;
    71RFID設備管理軟件                }

    72RFID設備管理軟件            }

    73RFID設備管理軟件        }

    74RFID設備管理軟件        catch (const long &lErrLine)
    75RFID設備管理軟件        {            
    76RFID設備管理軟件            bRet = FALSE;
    77RFID設備管理軟件            _TRACE("Exp : %s -- %ld ", __FILE__, lErrLine);            
    78RFID設備管理軟件        }

    79RFID設備管理軟件
    80RFID設備管理軟件        return bRet;
    81RFID設備管理軟件    }

    4. GetRcvData(), 從接收隊列中取出一個數據包.

     1RFID設備管理軟件    UDP_RCV_DATA *UdpSer::GetRcvData(DWORD* pCount)
     2RFID設備管理軟件    {
     3RFID設備管理軟件        UDP_RCV_DATA* pRcvData = NULL;
     4RFID設備管理軟件
     5RFID設備管理軟件        EnterCriticalSection(&m_RcvDataLock);
     6RFID設備管理軟件        vector<UDP_RCV_DATA* >::iterator iterRcv = m_RcvDataQue.begin();
     7RFID設備管理軟件        if (iterRcv != m_RcvDataQue.end())
     8RFID設備管理軟件        {
     9RFID設備管理軟件            pRcvData = *iterRcv;
    10RFID設備管理軟件            m_RcvDataQue.erase(iterRcv);
    11RFID設備管理軟件        }

    12RFID設備管理軟件
    13RFID設備管理軟件        if (pCount)
    14RFID設備管理軟件        {
    15RFID設備管理軟件            *pCount = (DWORD)(m_RcvDataQue.size());
    16RFID設備管理軟件        }

    17RFID設備管理軟件        LeaveCriticalSection(&m_RcvDataLock);
    18RFID設備管理軟件
    19RFID設備管理軟件        return pRcvData;
    20RFID設備管理軟件    }


    5. SendData() 發送指定長度的數據包.

     1RFID設備管理軟件    BOOL UdpSer::SendData(const IP_ADDR& PeerAddr, const CHAR* szData, INT nLen)
     2RFID設備管理軟件    {
     3RFID設備管理軟件        BOOL bRet = TRUE;
     4RFID設備管理軟件        try
     5RFID設備管理軟件        {
     6RFID設備管理軟件            if (nLen >= 1500)
     7RFID設備管理軟件            {
     8RFID設備管理軟件                THROW_LINE;
     9RFID設備管理軟件            }

    10RFID設備管理軟件
    11RFID設備管理軟件            UDP_CONTEXT* pSendContext = new UDP_CONTEXT();
    12RFID設備管理軟件            if (pSendContext && pSendContext->m_pBuf)
    13RFID設備管理軟件            {
    14RFID設備管理軟件                pSendContext->m_nOperation = OP_WRITE;
    15RFID設備管理軟件                pSendContext->m_RemoteAddr = PeerAddr;        
    16RFID設備管理軟件
    17RFID設備管理軟件                memcpy(pSendContext->m_pBuf, szData, nLen);
    18RFID設備管理軟件
    19RFID設備管理軟件                WSABUF SendBuf = { NULL, 0 };
    20RFID設備管理軟件                DWORD dwBytes = 0;
    21RFID設備管理軟件                SendBuf.buf = pSendContext->m_pBuf;
    22RFID設備管理軟件                SendBuf.len = nLen;
    23RFID設備管理軟件
    24RFID設備管理軟件                INT iErrCode = WSASendTo(m_hSock, &SendBuf, 1&dwBytes, 0, (sockaddr*)&PeerAddr, sizeof(PeerAddr), &(pSendContext->m_ol), NULL);
    25RFID設備管理軟件                if (SOCKET_ERROR == iErrCode && ERROR_IO_PENDING != WSAGetLastError())
    26RFID設備管理軟件                {
    27RFID設備管理軟件                    delete pSendContext;
    28RFID設備管理軟件                    THROW_LINE;
    29RFID設備管理軟件                }

    30RFID設備管理軟件            }

    31RFID設備管理軟件            else
    32RFID設備管理軟件            {
    33RFID設備管理軟件                delete pSendContext;
    34RFID設備管理軟件                THROW_LINE;
    35RFID設備管理軟件            }

    36RFID設備管理軟件        }

    37RFID設備管理軟件        catch (const long &lErrLine)
    38RFID設備管理軟件        {
    39RFID設備管理軟件            bRet = FALSE;
    40RFID設備管理軟件            _TRACE("Exp : %s -- %ld ", __FILE__, lErrLine);            
    41RFID設備管理軟件        }

    42RFID設備管理軟件
    43RFID設備管理軟件        return bRet;
    44RFID設備管理軟件    }


    6. CloseServer() 關閉服務

    1RFID設備管理軟件    void UdpSer::CloseServer()
    2RFID設備管理軟件    {
    3RFID設備管理軟件        m_bSerRun = FALSE;
    4RFID設備管理軟件        closesocket(m_hSock);
    5RFID設備管理軟件    }


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

     1RFID設備管理軟件    UINT WINAPI UdpSer::WorkThread(LPVOID lpParam)
     2RFID設備管理軟件    {
     3RFID設備管理軟件        UdpSer *pThis = (UdpSer *)lpParam;
     4RFID設備管理軟件        DWORD dwTrans = 0, dwKey = 0;
     5RFID設備管理軟件        LPOVERLAPPED pOl = NULL;
     6RFID設備管理軟件        UDP_CONTEXT *pContext = NULL;
     7RFID設備管理軟件
     8RFID設備管理軟件        while (TRUE)
     9RFID設備管理軟件        {
    10RFID設備管理軟件            BOOL bOk = GetQueuedCompletionStatus(pThis->m_hCompletion, &dwTrans, &dwKey, (LPOVERLAPPED *)&pOl, WSA_INFINITE);
    11RFID設備管理軟件
    12RFID設備管理軟件            pContext = CONTAINING_RECORD(pOl, UDP_CONTEXT, m_ol);
    13RFID設備管理軟件            if (pContext)
    14RFID設備管理軟件            {
    15RFID設備管理軟件                switch (pContext->m_nOperation)
    16RFID設備管理軟件                {
    17RFID設備管理軟件                case OP_READ:
    18RFID設備管理軟件                    pThis->ReadCompletion(bOk, dwTrans, pOl);
    19RFID設備管理軟件                    break;
    20RFID設備管理軟件                case OP_WRITE:
    21RFID設備管理軟件                    delete pContext;
    22RFID設備管理軟件                    pContext = NULL;
    23RFID設備管理軟件                    break;
    24RFID設備管理軟件                }

    25RFID設備管理軟件            }

    26RFID設備管理軟件
    27RFID設備管理軟件            if (FALSE == InterlockedExchangeAdd(&(pThis->m_bThreadRun), 0))
    28RFID設備管理軟件            {
    29RFID設備管理軟件                break;
    30RFID設備管理軟件            }

    31RFID設備管理軟件        }

    32RFID設備管理軟件
    33RFID設備管理軟件        return 0;
    34RFID設備管理軟件    }


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

     1RFID設備管理軟件    void UdpSer::ReadCompletion(BOOL bSuccess, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
     2RFID設備管理軟件    {
     3RFID設備管理軟件        UDP_CONTEXT* pRcvContext = CONTAINING_RECORD(lpOverlapped, UDP_CONTEXT, m_ol);
     4RFID設備管理軟件        WSABUF RcvBuf = { NULL, 0 };
     5RFID設備管理軟件        DWORD dwBytes = 0;
     6RFID設備管理軟件        DWORD dwFlag = 0;
     7RFID設備管理軟件        INT nAddrLen = sizeof(IP_ADDR);
     8RFID設備管理軟件        INT iErrCode = 0;
     9RFID設備管理軟件
    10RFID設備管理軟件        if (TRUE == bSuccess && dwNumberOfBytesTransfered <= UDP_CONTEXT::S_PAGE_SIZE)
    11RFID設備管理軟件        {
    12RFID設備管理軟件#ifdef _XML_NET_
    13RFID設備管理軟件            EnterCriticalSection(&m_RcvDataLock);
    14RFID設備管理軟件
    15RFID設備管理軟件            UDP_RCV_DATA* pRcvData = new UDP_RCV_DATA(pRcvContext->m_pBuf, dwNumberOfBytesTransfered, pRcvContext->m_RemoteAddr);
    16RFID設備管理軟件            if (pRcvData && pRcvData->m_pData)
    17RFID設備管理軟件            {
    18RFID設備管理軟件                m_RcvDataQue.push_back(pRcvData);
    19RFID設備管理軟件            }
        
    20RFID設備管理軟件            else
    21RFID設備管理軟件            {
    22RFID設備管理軟件                delete pRcvData;
    23RFID設備管理軟件            }

    24RFID設備管理軟件
    25RFID設備管理軟件            LeaveCriticalSection(&m_RcvDataLock);
    26RFID設備管理軟件#else
    27RFID設備管理軟件            if (dwNumberOfBytesTransfered >= sizeof(PACKET_HEAD))
    28RFID設備管理軟件            {
    29RFID設備管理軟件                EnterCriticalSection(&m_RcvDataLock);
    30RFID設備管理軟件
    31RFID設備管理軟件                UDP_RCV_DATA* pRcvData = new UDP_RCV_DATA(pRcvContext->m_pBuf, dwNumberOfBytesTransfered, pRcvContext->m_RemoteAddr);
    32RFID設備管理軟件                if (pRcvData && pRcvData->m_pData)
    33RFID設備管理軟件                {
    34RFID設備管理軟件                    m_RcvDataQue.push_back(pRcvData);
    35RFID設備管理軟件                }
        
    36RFID設備管理軟件                else
    37RFID設備管理軟件                {
    38RFID設備管理軟件                    delete pRcvData;
    39RFID設備管理軟件                }

    40RFID設備管理軟件
    41RFID設備管理軟件                LeaveCriticalSection(&m_RcvDataLock);
    42RFID設備管理軟件            }

    43RFID設備管理軟件#endif
    44RFID設備管理軟件
    45RFID設備管理軟件            //投遞下一個接收操作
    46RFID設備管理軟件            RcvBuf.buf = pRcvContext->m_pBuf;
    47RFID設備管理軟件            RcvBuf.len = UDP_CONTEXT::S_PAGE_SIZE;
    48RFID設備管理軟件
    49RFID設備管理軟件            iErrCode = WSARecvFrom(pRcvContext->m_hSock, &RcvBuf, 1&dwBytes, &dwFlag, (sockaddr*)(&pRcvContext->m_RemoteAddr)
    50RFID設備管理軟件                , &nAddrLen, &(pRcvContext->m_ol), NULL);
    51RFID設備管理軟件            if (SOCKET_ERROR == iErrCode && ERROR_IO_PENDING != WSAGetLastError())
    52RFID設備管理軟件            {
    53RFID設備管理軟件                ATLTRACE("\r\n%s -- %ld dwNumberOfBytesTransfered = %ld, LAST_ERR = %ld"
    54RFID設備管理軟件                    , __FILE__, __LINE__, dwNumberOfBytesTransfered, WSAGetLastError());
    55RFID設備管理軟件                delete pRcvContext;
    56RFID設備管理軟件                pRcvContext = NULL;
    57RFID設備管理軟件            }

    58RFID設備管理軟件        }

    59RFID設備管理軟件        else
    60RFID設備管理軟件        {
    61RFID設備管理軟件            delete pRcvContext;
    62RFID設備管理軟件        }

    63RFID設備管理軟件    }
    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全