• <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>
            蝸牛的家
            男兒當自強
            posts - 48,  comments - 21,  trackbacks - 0
             1#pragma once
             2
             3#include <afxmt.h>
             4#include <map>
             5
             6using namespace std;
             7
             8#define MAX_PENDING_CONNECTIONS        20
             9#define MAX_WSAEVENT_NUMS            64
            10
            11class CEventSocket
            12{
            13public:
            14    CEventSocket(void);
            15    virtual ~CEventSocket(void);
            16
            17    virtual void RecvDataNotidy(UINT64 fromAddr, char *pData, int nDataSize) {}
            18    virtual void CloseNotidy(UINT64 fromAddr) {}
            19
            20    BOOL ConnectTo(long ip, int port, int sockType = SOCK_STREAM, int protocol = IPPROTO_TCP);
            21
            22    BOOL ListenOn(int port, int sockType = SOCK_STREAM, int protocol = IPPROTO_TCP);
            23    void Stop();
            24    int SendData(UINT64 toAddr, char *pData, int nDataSize);
            25
            26    void ClosePeer(UINT64 peerAddr);
            27protected:
            28    static DWORD WINAPI WkThread(LPVOID lParam);
            29
            30private:
            31    int m_nEventTotal;
            32    HANDLE m_hWkThread;
            33    HANDLE m_hStopEvent;
            34    CCriticalSection cs;
            35    map<UINT64, int> m_ClientList;
            36    WSAEVENT m_EventArray[MAX_WSAEVENT_NUMS];
            37    SOCKET m_SockArray[MAX_WSAEVENT_NUMS];
            38}
            ;


            實現文件

              1#include "StdAfx.h"
              2#include "EventSocket.h"
              3
              4CEventSocket::CEventSocket(void)
              5{
              6    WSADATA wsaData;
              7    if( (WSAStartup(MAKEWORD(2,2), &wsaData)) != 0 ) 
              8        TRACE(_T("WSAStartup Failed"));
              9    
             10    m_hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
             11    m_nEventTotal = 0;
             12    m_hWkThread = NULL;
             13}

             14
             15CEventSocket::~CEventSocket(void)
             16{
             17    Stop();
             18    WSACleanup();
             19    CloseHandle(m_hStopEvent);
             20}

             21
             22BOOL CEventSocket::ConnectTo(long ip, int port, int sockType, int protocol)
             23{
             24    SOCKADDR_IN skAddr;
             25
             26    skAddr.sin_family = AF_INET;
             27    skAddr.sin_addr.s_addr = ip;
             28    skAddr.sin_port = htons(port);
             29
             30    SOCKET sk = WSASocket(AF_INET, sockType, protocol, NULL, 0, WSA_FLAG_OVERLAPPED);
             31
             32    if (sk == INVALID_SOCKET)
             33    {
             34        TRACE(_T("WSASocket Failed"));
             35        return FALSE;
             36    }

             37    
             38    //1.先將socket設為非堵塞
             39    unsigned long lBlocked = 1;
             40    ioctlsocket(sk,FIONBIO ,&lBlocked);
             41    //2.設置連接超時
             42    struct timeval Timeout = {1,0};
             43    fd_set writefds;
             44    FD_ZERO(&writefds);
             45    FD_SET(sk,&writefds);
             46
             47    connect(sk,(const sockaddr*)&skAddr,sizeof(sockaddr_in));
             48    select(1,  NULL,&writefds, NULL, &Timeout);
             49    //3.將socket設為堵塞
             50    lBlocked = 0;
             51    ioctlsocket(sk, FIONBIO ,&lBlocked);
             52    if ( ! FD_ISSET(sk,&writefds))
             53    {
             54        closesocket(sk);
             55        return FALSE;
             56    }

             57
             58    if (m_nEventTotal >= MAX_WSAEVENT_NUMS)
             59    {
             60        TRACE(_T("Too many Events"));
             61        closesocket(sk);
             62        return FALSE;
             63    }

             64
             65    WSAEVENT wsaEvent = WSACreateEvent();
             66
             67    if (wsaEvent == INVALID_HANDLE_VALUE)
             68    {
             69        closesocket(sk);
             70        TRACE(_T("CreateEvent Failed"));
             71        return FALSE;
             72    }

             73
             74    if (WSAEventSelect(sk, wsaEvent, FD_READ|FD_WRITE|FD_CLOSE) != 0)
             75    {
             76        TRACE(_T("WSAEventSelect Failed"));
             77        closesocket(sk);
             78        CloseHandle(wsaEvent);
             79        return FALSE;
             80    }

             81    
             82    UINT64 fromAddr = (UINT64)skAddr.sin_addr.S_un.S_addr << 32 | ntohs(skAddr.sin_port);
             83    
             84    cs.Lock();
             85    m_ClientList[fromAddr] = m_nEventTotal;
             86    m_EventArray[m_nEventTotal] = wsaEvent;
             87    m_SockArray[m_nEventTotal] = sk;
             88    ++m_nEventTotal;
             89    cs.Unlock();
             90
             91    if (m_hWkThread == NULL)
             92    {
             93        DWORD dwThreadID;
             94        m_hWkThread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WkThread, this0&dwThreadID);
             95
             96        if (m_hWkThread == INVALID_HANDLE_VALUE)
             97        {
             98            TRACE(_T("WSAEventSelect Failed"));
             99            closesocket(sk);
            100            CloseHandle(wsaEvent);
            101            return FALSE;
            102        }

            103    }

            104
            105    return TRUE;
            106}

            107
            108
            109BOOL CEventSocket::ListenOn(int port, int sockType, int protocol)
            110{
            111    SOCKADDR_IN skAddr;
            112
            113    skAddr.sin_family = AF_INET;
            114    skAddr.sin_addr.s_addr = ADDR_ANY;
            115    skAddr.sin_port = htons(port);
            116
            117    SOCKET sk = WSASocket(AF_INET, sockType, protocol, NULL, 0, WSA_FLAG_OVERLAPPED);
            118
            119    if (sk == INVALID_SOCKET)
            120    {
            121        TRACE(_T("WSASocket Failed"));
            122        return FALSE;
            123    }

            124
            125    if( bind(sk, (PSOCKADDR)&skAddr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR ) 
            126    {
            127        TRACE(_T("Server Soket Bind Failed"));
            128        closesocket(sk);
            129        return FALSE;
            130    }

            131
            132    if(listen(sk, MAX_PENDING_CONNECTIONS) == SOCKET_ERROR ) 
            133    {
            134        TRACE(_T("Server Socket Listen Failed"));
            135        closesocket(sk);
            136        return FALSE;
            137    }

            138
            139    WSAEVENT wsaEvent = WSACreateEvent();
            140
            141    if (wsaEvent == INVALID_HANDLE_VALUE)
            142    {
            143        closesocket(sk);
            144        TRACE(_T("CreateEvent Failed"));
            145        return FALSE;
            146    }

            147
            148    if (WSAEventSelect(sk, wsaEvent, FD_ACCEPT|FD_CLOSE) != 0)
            149    {
            150        TRACE(_T("WSAEventSelect Failed"));
            151        closesocket(sk);
            152        CloseHandle(wsaEvent);
            153        return FALSE;
            154    }

            155
            156    cs.Lock();
            157    m_EventArray[m_nEventTotal] = wsaEvent;
            158    m_SockArray[m_nEventTotal] = sk;
            159    ++m_nEventTotal;
            160    cs.Unlock();
            161    
            162    if (m_hWkThread == NULL)
            163    {
            164        DWORD dwThreadID;
            165        m_hWkThread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WkThread, this0&dwThreadID);
            166        if (m_hWkThread == INVALID_HANDLE_VALUE)
            167        {
            168            TRACE(_T("WSAEventSelect Failed"));
            169            closesocket(sk);
            170            CloseHandle(wsaEvent);
            171            return FALSE;
            172        }

            173    }

            174
            175    return TRUE;
            176}

            177
            178
            179DWORD WINAPI CEventSocket::WkThread(LPVOID lParam)
            180{
            181    CEventSocket * pThis = reinterpret_cast<CEventSocket *>(lParam);
            182    ASSERT(NULL != pThis);
            183
            184    while (WaitForSingleObject(pThis->m_hStopEvent, 0== WSA_WAIT_TIMEOUT)
            185    {
            186        int nIndex = ::WSAWaitForMultipleEvents(pThis->m_nEventTotal, pThis->m_EventArray,
            187            FALSE, 500, FALSE);
            188
            189        if (nIndex == WSA_WAIT_TIMEOUT)
            190            continue;
            191
            192        if (nIndex != WSA_WAIT_FAILED)
            193        {
            194            nIndex -= WSA_WAIT_EVENT_0;
            195            WSANETWORKEVENTS netEvent;
            196
            197            WSAEnumNetworkEvents(pThis->m_SockArray[nIndex], pThis->m_EventArray[nIndex], &netEvent);
            198            WSAResetEvent(pThis->m_EventArray[nIndex]);
            199
            200            if (netEvent.lNetworkEvents&FD_ACCEPT && netEvent.iErrorCode[FD_ACCEPT_BIT] == 0)
            201            {
            202                if (pThis->m_nEventTotal >= MAX_WSAEVENT_NUMS)
            203                {
            204                    TRACE(_T("Too many Events"));
            205                    continue;
            206                }

            207
            208                WSAEVENT wsaEvent = WSACreateEvent();
            209                SOCKET sk = accept(pThis->m_SockArray[nIndex], NULL, NULL);
            210                WSAEventSelect(sk, wsaEvent, FD_READ|FD_WRITE|FD_CLOSE);
            211
            212                sockaddr_in skAddr = {0};
            213                int addrLen = sizeof(sockaddr_in);
            214                ::getsockname (sk,(sockaddr*)&skAddr,&addrLen);
            215                UINT64 fromAddr = (UINT64) skAddr.sin_addr.S_un.S_addr << 32 | ntohs(skAddr.sin_port);
            216                
            217                pThis->cs.Lock();
            218                pThis->m_ClientList[fromAddr] = pThis->m_nEventTotal;
            219                pThis->m_EventArray[pThis->m_nEventTotal] = wsaEvent;
            220                pThis->m_SockArray[pThis->m_nEventTotal] = sk;
            221                ++pThis->m_nEventTotal;
            222                pThis->cs.Unlock();
            223            }

            224            else if (netEvent.lNetworkEvents&FD_READ &&    netEvent.iErrorCode[FD_READ_BIT] == 0)
            225            {
            226                char buffer[2048= {0};
            227                int nDataSize = recv(pThis->m_SockArray[nIndex], buffer, 20480);
            228
            229                sockaddr_in skAddr = {0};
            230                int addrLen = sizeof(sockaddr_in);
            231
            232                ::getsockname (pThis->m_SockArray[nIndex],(sockaddr*)&skAddr,&addrLen);
            233                UINT64 fromAddr = (UINT64) skAddr.sin_addr.S_un.S_addr << 32 | ntohs(skAddr.sin_port);
            234
            235                pThis->RecvDataNotidy(fromAddr, buffer, nDataSize);
            236            }

            237            else if (netEvent.lNetworkEvents&FD_CLOSE && netEvent.iErrorCode[FD_CLOSE_BIT] == 0)
            238            {
            239                sockaddr_in skAddr = {0};
            240                int addrLen = sizeof(sockaddr_in);
            241
            242                ::getsockname (pThis->m_SockArray[nIndex],(sockaddr*)&skAddr,&addrLen);
            243                UINT64 fromAddr = (UINT64) skAddr.sin_addr.S_un.S_addr << 32 | ntohs(skAddr.sin_port);
            244
            245                pThis->CloseNotidy(fromAddr);
            246                
            247                pThis->cs.Lock();
            248                closesocket(pThis->m_SockArray[nIndex]);
            249                WSACloseEvent(pThis->m_EventArray[nIndex]);
            250                for (int i = nIndex; i < pThis->m_nEventTotal; i++)
            251                {
            252                    pThis->m_SockArray[i] = pThis->m_SockArray[i+1];
            253                    pThis->m_EventArray[i] = pThis->m_EventArray[i+1];
            254                }

            255                pThis->m_SockArray[pThis->m_nEventTotal] = NULL;
            256                pThis->m_EventArray[pThis->m_nEventTotal] = NULL;
            257                -- pThis->m_nEventTotal;
            258                map<UINT64, int>::iterator iterIdx = pThis->m_ClientList.find(fromAddr);
            259                if (iterIdx != pThis->m_ClientList.end())
            260                    pThis->m_ClientList.erase(iterIdx);
            261                pThis->cs.Unlock();
            262
            263            }

            264        }

            265    }

            266
            267    return 0;
            268}

            269
            270void CEventSocket::Stop()
            271{
            272    if (m_hWkThread == NULL)
            273        return;
            274
            275    SetEvent(m_hStopEvent);
            276    ::WaitForSingleObject(m_hWkThread, INFINITE);
            277    ResetEvent(m_hStopEvent);
            278    CloseHandle(m_hWkThread);
            279    m_hWkThread = NULL;
            280    
            281    for (int i = 0; i < m_nEventTotal; i++)
            282    {
            283        closesocket(m_SockArray[i]);
            284        m_SockArray[i] = NULL;
            285        WSACloseEvent(m_EventArray[i]);
            286        m_EventArray[i] = NULL;
            287    }

            288
            289    m_ClientList.clear();
            290}

            291
            292void CEventSocket::ClosePeer(UINT64 peerAddr)
            293{
            294
            295    cs.Lock();
            296    map<UINT64, int>::iterator iterIdx = m_ClientList.find(peerAddr);
            297    if (iterIdx != m_ClientList.end())
            298    {
            299        int nIndex = iterIdx->second;
            300        closesocket(m_SockArray[nIndex]);
            301        WSACloseEvent(m_EventArray[nIndex]);
            302        for (int i = nIndex; i < m_nEventTotal; i++)
            303        {
            304            m_SockArray[i] = m_SockArray[i+1];
            305            m_EventArray[i] = m_EventArray[i+1];
            306        }

            307        m_SockArray[m_nEventTotal] = NULL;
            308        m_EventArray[m_nEventTotal] = NULL;
            309        m_ClientList.erase(iterIdx);
            310        -- m_nEventTotal;
            311    }

            312    cs.Unlock();
            313}

            314
            315
            316int CEventSocket::SendData(UINT64 toAddr, char *pData, int nDataSize)
            317{
            318    map<UINT64, int>::iterator iterIdx = m_ClientList.find(toAddr);
            319
            320    if (iterIdx != m_ClientList.end() && m_SockArray[iterIdx->second] != NULL)
            321    {
            322        return send(m_SockArray[iterIdx->second], pData, nDataSize, 0);
            323    }

            324
            325    return  -1;
            326}
            posted on 2008-12-23 13:12 黑色天使 閱讀(583) 評論(0)  編輯 收藏 引用 所屬分類: C\C++

            <2008年8月>
            272829303112
            3456789
            10111213141516
            17181920212223
            24252627282930
            31123456

            常用鏈接

            留言簿(2)

            隨筆分類

            隨筆檔案

            文章檔案

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            四虎影视久久久免费观看| 国产—久久香蕉国产线看观看| 久久无码国产| 亚洲va中文字幕无码久久不卡| 亚洲午夜久久久影院| 久久亚洲精品中文字幕三区| 久久er国产精品免费观看8| 久久99久久99精品免视看动漫| 亚洲精品无码久久久久| 久久久国产精品福利免费| 青青久久精品国产免费看| 69SEX久久精品国产麻豆| 欧美精品一区二区久久| 久久精品www| 久久人人爽人人爽人人AV东京热| 久久国产V一级毛多内射| 无码AV波多野结衣久久| 久久久久亚洲AV成人网| 久久99国产精品一区二区| 一本色道久久HEZYO无码| 人妻中文久久久久| 久久夜色精品国产亚洲| 国产精品一久久香蕉国产线看观看| 麻豆国内精品久久久久久| 国产福利电影一区二区三区久久老子无码午夜伦不 | 欧美粉嫩小泬久久久久久久| 久久亚洲精精品中文字幕| 精品伊人久久久| 欧美激情精品久久久久久久| 精品久久久久国产免费| 久久精品男人影院| 国产精品9999久久久久| 久久久亚洲欧洲日产国码二区| 97视频久久久| 亚洲国产欧洲综合997久久| 色老头网站久久网| 久久久久久精品久久久久| 久久狠狠爱亚洲综合影院| 亚洲综合日韩久久成人AV| 色综合久久中文字幕无码| 精品国产乱码久久久久久呢|