首页
社区
课程
招聘
[旧帖] [原创]开源iocp-acceptex类 申请个码 0.00雪花
发表于: 2014-2-8 01:25 3904

[旧帖] [原创]开源iocp-acceptex类 申请个码 0.00雪花

2014-2-8 01:25
3904
使用异步acceptex首先投递当前线程数的socket
然后接受到连接以后投递下一个acceptex cmap映射表管理
里面有个ulDialog[2]数组 仿照gh0st远控用来处理窗口id分发消息的
里面的zlib压缩库函数可以直接去掉了,大致就这样,不知道能否申请个码
另外对木马病毒分析编写与网络编程感兴趣的可以pm我,不要装逼党 伸手党 只是纯粹感兴趣
不能做坏事!

h文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/****************************************************************************
*                                                                           *
* IocpServer.h -- socket completion port class                              *
*                                                                           *
* Copyright (c) 2013 by cooling.和谐掉QQ 防止社工牛 All rights reserved.              *
*                                                                           *
****************************************************************************/
 
#pragma once
#include <WinSock2.h>
#include <MSTcpIP.h>
#include <MSWSock.h>
#include <process.h>
#pragma comment(lib, "ws2_32.lib")
 
#define  hot_size 1024
#define  buf_size 4096
#define  unm_size 8192
//////////////////////////////////////////////////////////////////////////
typedef enum _tagIOTYPE
{
    init_flag,
    aept_flag, // AcceptEx
    recv_flag,
    send_flag,
    exit_flag
}IOTYPE, *LP_IOTYPE;
 
typedef struct _PER_SOCKET_CONTEXT
{
    SOCKET        sClientSocket;
    bool          bMainSocket;
    CHAR          szIpString[16];
    unsigned long ulIpAddress;
    unsigned long ulDialog[2];
 
    _PER_SOCKET_CONTEXT()
    {
        ulIpAddress   = 0;
        bMainSocket   = false;
        sClientSocket = INVALID_SOCKET;
        memset(szIpString,0,sizeof(szIpString));
        memset(ulDialog,0,sizeof(ulDialog));
    }
}PER_SOCKET_CONTEXT, *LP_PER_SOCKET_CONTEXT;
 
typedef struct _PER_IO_OPENATION_DATA
{
    OVERLAPPED   Overlapped;
    WSABUF       WsaBuf;
    CHAR         BitBuf[buf_size];
    IOTYPE       IoTYPE;
    SOCKET       sAcceptSocket;
 
    _PER_IO_OPENATION_DATA()
    {
        WsaBuf.buf = BitBuf;
        WsaBuf.len = buf_size;
        IoTYPE     = init_flag;
        memset(BitBuf,0,buf_size);
        memset(&Overlapped,0,sizeof(OVERLAPPED));
    }
 
}PER_IO_OPENATION_DATA, *LP_PER_IO_OPENATION_DATA;
 
// define callback Function
typedef void __stdcall NOTIFYPROC(LP_PER_SOCKET_CONTEXT, PCHAR, ULONG, LPVOID, UINT);
 
class CIocpServer
{
public:
    CIocpServer(void);
    ~CIocpServer(void);
 
public:
 
    bool             Start(NOTIFYPROC *pNotifyProc, void *lpContext, u_short uPort);
    bool             Shutdown();
    bool             DisConnect(SOCKET sclient);
    bool             SendMsg(SOCKET sclient, char* data, u_long ulDataLength, bool bflag = true);
 
protected:
 
    bool             _InitIOCPServer(unsigned short uPort);
    bool             _RunAcceptEx(LP_PER_IO_OPENATION_DATA lpPerIoData = NULL);
    bool             _PostAcceptEx(LP_PER_SOCKET_CONTEXT lpPerStContext = NULL);
    bool             _PostRecvData(LP_PER_SOCKET_CONTEXT lpPerStContext = NULL, LP_PER_IO_OPENATION_DATA lpPerIoData = NULL);
    bool             _RetvalSocketPool(LP_PER_SOCKET_CONTEXT lpPerStContext = NULL, LP_PER_IO_OPENATION_DATA lpPerIoData = NULL, bool bflag = false);
    bool             _DestroySocketPool();
 
    HANDLE           _BindCreateIoCompletionPort(SOCKET hSocket, HANDLE hCompletionPort, ULONG_PTR lpStContext, DWORD dwNumber = 0);
    unsigned int     _GetMswSockFuntion(SOCKET s, GUID &guid, void* &lp);
    unsigned int     _GetProcessOfNumber();
 
private:
 
    bool             m_bStatus;
    DWORD            m_dwFlags;
    DWORD            m_dwSockLen;
    LPVOID           m_lpContext[2];
      
    HANDLE           m_hWorkEvent;
    HANDLE           m_hCompletionPort;
    SOCKET           m_sListenSocket;
    SOCKET           m_uSocketPool[SHRT_MAX]; // socket disconnectex pool /*unsigned int type
    unsigned int     m_uThreads;
    unsigned int     m_uThreadId;
    CRITICAL_SECTION cIocpSection;
 
    NOTIFYPROC        *m_lpNotifyProc;
    LPFN_ACCEPTEX      m_lpfnAcceptEx;
    LPFN_DISCONNECTEX  m_lpfnDisconnectEx;
 
    friend unsigned __stdcall _CheckMemory(void *lpContext);
    friend unsigned __stdcall _WorkerThread(void *lpContext);
    CMap <SOCKET,SOCKET,LP_PER_SOCKET_CONTEXT,LP_PER_SOCKET_CONTEXT&> mapStContext;
};


cpp文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
#include "StdAfx.h"
#include "IocpServer.h"
 
//////////////////////////////////////////////////////////////////////////
CIocpServer::CIocpServer(void)
{
    m_bStatus          = false;
    m_dwFlags          = 0;
    m_dwSockLen        = sizeof(sockaddr_in) + 16;
    m_uThreads         = _GetProcessOfNumber();
    m_uThreadId        = 0;
    m_lpNotifyProc     = NULL;
    m_lpfnAcceptEx     = NULL;
    m_lpfnDisconnectEx = NULL;
    m_sListenSocket    = INVALID_SOCKET;
    m_hWorkEvent       = CreateEvent(NULL,TRUE,FALSE,NULL);
    m_hCompletionPort  = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,NULL,0);
 
    InitializeCriticalSection(&cIocpSection);
    memset(&m_lpContext,0,sizeof(m_lpContext));
    memset(&m_uSocketPool,0,sizeof(m_uSocketPool));
}
 
CIocpServer::~CIocpServer(void)
{
    WSACleanup();
    CloseHandle(m_hWorkEvent);
    DeleteCriticalSection(&cIocpSection);
}
 
unsigned __stdcall _WorkerThread(void *lpContext)
{
    CIocpServer      *pSvr = (CIocpServer*)lpContext;
    HANDLE           hCompletionPort = pSvr->m_hCompletionPort;
 
    LP_PER_IO_OPENATION_DATA lpPerIoData;
    LP_PER_SOCKET_CONTEXT    lpPerStContext;
    unsigned long            ulBytesTransferred;
    InterlockedIncrement((PLONG)&pSvr->m_uThreadId);
    unsigned long            ulThreadId = pSvr->m_uThreadId;
    TRACE("_workerthread start <%d>\n",ulThreadId);
 
    while (WaitForSingleObject(pSvr->m_hWorkEvent,0) != WAIT_OBJECT_0)
    {
        BOOL bRet = GetQueuedCompletionStatus(hCompletionPort,
                                              &ulBytesTransferred,
                                              (PULONG_PTR)&lpPerStContext,
                                              (LPOVERLAPPED*)&lpPerIoData,
                                              INFINITE);
 
        if(ulBytesTransferred == -1 && lpPerStContext == NULL && lpPerIoData == NULL)
        {
            //thread exit
            TRACE("_workerthread exit %d\n",ulThreadId);
            return 0;
        }
 
        if (ulBytesTransferred == 0 && (lpPerIoData->IoTYPE == send_flag || lpPerIoData->IoTYPE == recv_flag))
        {
            BOOL bRemove = FALSE;
            EnterCriticalSection(&pSvr->cIocpSection);
            bRemove = pSvr->mapStContext.RemoveKey(lpPerStContext->sClientSocket);
            LeaveCriticalSection(&pSvr->cIocpSection);
 
            if (bRemove)
            {   /*
                 * notice callback function leave online list.
                 */
                pSvr->m_lpNotifyProc(lpPerStContext, NULL, 0, pSvr->m_lpContext[1],0);
                TRACE("client %d exit",lpPerStContext->sClientSocket);
 
                /* setsockopt linger stop time_wait status */
                linger lingerstruct;
                lingerstruct.l_onoff  = 1;
                lingerstruct.l_linger = 0;
 
                if (setsockopt(lpPerStContext->sClientSocket,SOL_SOCKET,SO_LINGER,(char*)&lingerstruct,sizeof(lingerstruct)) == SOCKET_ERROR)
                {
                    TRACE("SO_LINGER error %d\n",WSAGetLastError());
                }
 
                /* close socket handle free memory */
                closesocket(lpPerStContext->sClientSocket);
                GlobalFree(lpPerStContext);
                GlobalFree(lpPerIoData);
            }
 
            continue;
        }
 
        switch (lpPerIoData->IoTYPE)
        {
        case aept_flag:
            {
                if (!pSvr->m_bStatus)
                {
                    /* free completion per-overlapped-data */
                    closesocket(lpPerIoData->sAcceptSocket);
                    GlobalFree(lpPerIoData);
                    continue;
                }
 
                pSvr->_RunAcceptEx(lpPerIoData);
                pSvr->_PostAcceptEx(lpPerStContext);
            }
            break;
        case recv_flag:
            {
                /* configure zlib uncompress flag */
                if (lpPerStContext->bMainSocket == true)
                {
                    char szRecvData[buf_size * 2]= "";
                    u_long ulRecvLength = sizeof(szRecvData);
                    if(uncompress((Bytef*)szRecvData, &ulRecvLength, (const Bytef*)&lpPerIoData->BitBuf, ulBytesTransferred) == Z_OK)
                    {
                        //如果解压DATA失败 则不调用回调函数去处理数据,只需要投递下一个WSARecv请求
                        pSvr->m_lpNotifyProc(lpPerStContext, szRecvData, ulRecvLength, pSvr->m_lpContext[1],0);
                    }
                    //在此解压DATA失败的消息
                }
                else
                {
                    // 如果不是主SOCKET则不需要解压缩数据
                    pSvr->m_lpNotifyProc(lpPerStContext, lpPerIoData->BitBuf, ulBytesTransferred, pSvr->m_lpContext[1],0);
                }
 
                /* post next recv */
                pSvr->_PostRecvData(lpPerStContext,lpPerIoData);
            }
            break;
        case send_flag:
            {
                GlobalFree(lpPerIoData);
                ulBytesTransferred = 0;
            }
            break;
        default:
            break;
        }
    }
 
    return 0;
}
 
bool CIocpServer::SendMsg(SOCKET sclient, char* data, u_long ulDataLength, bool bflag /* = true */)
{
    if (sclient == INVALID_SOCKET || data == NULL || ulDataLength == 0)
        return false;
 
    //申请单IO数据
    LP_PER_IO_OPENATION_DATA lpPerIoData = (LP_PER_IO_OPENATION_DATA) \
        GlobalAlloc(GPTR,sizeof(PER_IO_OPENATION_DATA));
 
    memset(lpPerIoData->BitBuf,0,buf_size);
    memset(&(lpPerIoData->Overlapped),0,sizeof(OVERLAPPED));
 
    if(bflag == true)
    {
        char szBuf[buf_size * 2];
        u_long compreLen = buf_size * 2;
        compress((Bytef*)szBuf, &compreLen, (const Bytef*)data, ulDataLength);
        memcpy(lpPerIoData->BitBuf, szBuf, compreLen);
    }
    else
    {
        memcpy(lpPerIoData->BitBuf,data,ulDataLength);/* copy send buffer */
    }
 
    lpPerIoData->WsaBuf.buf = lpPerIoData->BitBuf;
    lpPerIoData->WsaBuf.len = ulDataLength;
    lpPerIoData->IoTYPE     = send_flag;
 
    DWORD dwOfBytesSent;
    int nRet = WSASend(sclient,
                       &(lpPerIoData->WsaBuf),
                       1,
                       &dwOfBytesSent,
                       m_dwFlags,
                       &(lpPerIoData->Overlapped),
                       NULL);
 
    if (nRet == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING)
    {
        TRACE("WSASend error at %d\n",WSAGetLastError());
        GlobalFree(lpPerIoData);
        return false;
    }
    else
        return true;
 
    return false;
}
 
bool CIocpServer::Start(NOTIFYPROC *pNotifyProc, void *lpContext, u_short uPort)
{
    if (m_bStatus == true)
        return true;
 
    TRACE("IOCPServer Start...");
 
    if (uPort == 0)
        uPort = 80;
 
    m_bStatus = true;
 
    m_lpContext[1] = lpContext; //this指针
    m_lpNotifyProc = pNotifyProc;
 
    _InitIOCPServer(uPort);
 
    return true;
}
 
bool CIocpServer::Shutdown()
{
    if (m_bStatus == false)
        return 0;
 
    TRACE("IOCPServer Shutdown...");
    m_bStatus = false;
 
    // CancelIo listen socket
    CancelIo((HANDLE)m_sListenSocket);
    LP_PER_SOCKET_CONTEXT lpPerStContext;
    POSITION pi = mapStContext.GetStartPosition();
 
    while (pi)
    {
        SOCKET sClient;
        mapStContext.GetNextAssoc(pi,sClient,lpPerStContext);
        shutdown(lpPerStContext->sClientSocket,0x02);
        CancelIo((HANDLE)lpPerStContext->sClientSocket);
        mapStContext.RemoveKey(sClient);
        lpPerStContext = NULL;
    }
 
    mapStContext.RemoveAll();
 
    for (u_int i = 0; i < m_uThreads; i++)
    {
        PostQueuedCompletionStatus(m_hCompletionPort,-1,NULL,NULL);
        Sleep(10);
    }
 
    // free for listen per-socket-data
    SetEvent(m_hWorkEvent); // set event status
    GlobalFree(m_lpContext[0]);
    closesocket(m_sListenSocket);
    CloseHandle(m_hCompletionPort);
 
    return true;
}
 
bool CIocpServer::DisConnect(SOCKET sclient)
{
    if (m_bStatus)
    {
        EnterCriticalSection(&cIocpSection);
        LP_PER_SOCKET_CONTEXT lpPerFindStContext;
 
        BOOL bLookup = FALSE;
        bLookup = mapStContext.Lookup(sclient,lpPerFindStContext);
        if (bLookup && lpPerFindStContext->sClientSocket == sclient)
        {
            shutdown(lpPerFindStContext->sClientSocket,0x02);
            closesocket(lpPerFindStContext->sClientSocket);
            mapStContext.RemoveKey(sclient);
            lpPerFindStContext = NULL;
        }
 
        LeaveCriticalSection(&cIocpSection);
    }
 
    return true;
}
 
bool CIocpServer::_PostAcceptEx(LP_PER_SOCKET_CONTEXT lpPerStContext)
{
    lpPerStContext->sClientSocket = INVALID_SOCKET;
    lpPerStContext->ulIpAddress   = 0;
    lpPerStContext->bMainSocket   = false;
    memset(lpPerStContext->ulDialog,0,sizeof(lpPerStContext->ulDialog));
    memset(lpPerStContext->szIpString,0,sizeof(lpPerStContext->szIpString));
 
    // for listen socket handle new lpPerIoData memory
    LP_PER_IO_OPENATION_DATA lpPerIoData = (LP_PER_IO_OPENATION_DATA) \
        GlobalAlloc(GPTR,sizeof(PER_IO_OPENATION_DATA));
 
    //_RetvalSocketPool(NULL,lpPerIoData,true);
    //if (lpPerIoData->sAcceptSocket == 0)
    lpPerIoData->sAcceptSocket =  socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if (lpPerIoData->sAcceptSocket == INVALID_SOCKET)
    {
        return false;
    }
 
    lpPerIoData->IoTYPE = aept_flag; // AcceptEx type
 
    DWORD dwBytesOfAcceptEx = 0;
    BOOL bRet = m_lpfnAcceptEx(m_sListenSocket,/* In the listen socket handle post AcceptEx */
                               lpPerIoData->sAcceptSocket,
                               lpPerIoData->BitBuf,
                               0,
                               m_dwSockLen,/* the is sizeof sockaddr_in add 16 bytes */
                               m_dwSockLen,
                               &dwBytesOfAcceptEx,
                               &(lpPerIoData->Overlapped));
 
    if (bRet == FALSE && WSAGetLastError() != WSA_IO_PENDING)
    {
        TRACE("m_lpfnAcceptEx post error at %d\n",WSAGetLastError());
        GlobalFree(lpPerIoData);
        return false;
    }
 
    return true;
}
 
bool CIocpServer::_RunAcceptEx(LP_PER_IO_OPENATION_DATA lpPerIoData /* = NULL */)
{
    // for this single Io new apply single handle memory
    LP_PER_SOCKET_CONTEXT lpPerStContext = (LP_PER_SOCKET_CONTEXT) \
        GlobalAlloc(GPTR,sizeof(PER_SOCKET_CONTEXT));
    lpPerStContext->bMainSocket   = true;
    lpPerStContext->sClientSocket = lpPerIoData->sAcceptSocket; // set update socket accept status
    if(setsockopt(lpPerStContext->sClientSocket,SOL_SOCKET,SO_UPDATE_ACCEPT_CONTEXT,
        (char*)&m_sListenSocket,sizeof(SOCKET)) == SOCKET_ERROR)
    {
        TRACE("error\n");
        return false;
    }
 
    struct sockaddr_in acceptaddr;
    int    addrlen = sizeof(acceptaddr);
    memset(&acceptaddr,0,sizeof(acceptaddr));
    if (getpeername(lpPerStContext->sClientSocket,(sockaddr*)&acceptaddr,&addrlen) == SOCKET_ERROR)
    {
        TRACE("getpeername\n");
        return 0;
    }
 
    /* copy client ip address 16bit */
    lpPerStContext->ulIpAddress = acceptaddr.sin_addr.S_un.S_addr;
    strcpy_s(lpPerStContext->szIpString,inet_ntoa(acceptaddr.sin_addr));
 
    BOOL bKeepAlive   = 1;
    tcp_keepalive t_keepalive;
    t_keepalive.onoff = true;
    t_keepalive.keepalivetime = (1000 * 60) * 3; // 3 minutes
    t_keepalive.keepaliveinterval = 1000 * 10;   // 10ms
 
    if (setsockopt(lpPerStContext->sClientSocket,SOL_SOCKET,SO_KEEPALIVE,(const char*)&bKeepAlive,sizeof(bKeepAlive)) == SOCKET_ERROR)
    {
        TRACE("error\n");
        return false;
    }
 
    // Set TCP KeepAlive
    DWORD dwBytesRetval;
    WSAIoctl(lpPerStContext->sClientSocket,
            SIO_KEEPALIVE_VALS,
            &t_keepalive,
            sizeof(t_keepalive),
            &bKeepAlive,
            sizeof(BOOL),
            &dwBytesRetval,/* if bytes param for null. retval 10014 error id */
            NULL,
            NULL);
 
    // save socket to map
    EnterCriticalSection(&cIocpSection);
    mapStContext.SetAt(lpPerStContext->sClientSocket,lpPerStContext);
    LeaveCriticalSection(&cIocpSection);
     
    // bind Io port
    _BindCreateIoCompletionPort(lpPerStContext->sClientSocket,m_hCompletionPort,(DWORD)lpPerStContext,0);
    _PostRecvData(lpPerStContext,lpPerIoData);
 
    return true;
}
 
bool CIocpServer::_PostRecvData(LP_PER_SOCKET_CONTEXT lpPerStContext /* = NULL */, LP_PER_IO_OPENATION_DATA lpPerIoData /* = NULL */)
{
    memset(lpPerIoData->BitBuf,0,buf_size);
    memset(&(lpPerIoData->Overlapped),0,sizeof(OVERLAPPED));
    lpPerIoData->WsaBuf.buf = lpPerIoData->BitBuf;
    lpPerIoData->WsaBuf.len = buf_size;
    lpPerIoData->IoTYPE     = recv_flag;
 
    DWORD dwBytesRecvd;
    int nRet = WSARecv(lpPerStContext->sClientSocket,
                       &(lpPerIoData->WsaBuf),
                       1,
                       &dwBytesRecvd,
                       &m_dwFlags,
                       &(lpPerIoData->Overlapped),
                       NULL);
 
    if (nRet == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING)
    {
        TRACE("WSARecv error at %d\n",WSAGetLastError());
        GlobalFree(lpPerIoData);
        return false;
    }
    else
        return true;
 
    return false;
}
 
bool CIocpServer::_RetvalSocketPool(LP_PER_SOCKET_CONTEXT lpPerStContext /* = NULL */, LP_PER_IO_OPENATION_DATA lpPerIoData /* = NULL */, bool bflag)
{
    if (lpPerStContext == NULL && lpPerIoData == NULL)
        return false;
 
    EnterCriticalSection(&cIocpSection);
 
    if (bflag)
    {
        for (int nItem = 0; nItem < SHRT_MAX; nItem++)
        {
            if (m_uSocketPool[nItem] != 0)
            {
                if (m_uSocketPool[nItem] == INVALID_SOCKET)
                {
                    closesocket(m_uSocketPool[nItem]);
                    m_uSocketPool[nItem]   = 0;
                    continue;
                }
                lpPerIoData->sAcceptSocket = m_uSocketPool[nItem];
                m_uSocketPool[nItem]       = 0;
                LeaveCriticalSection(&cIocpSection);
                return true;
            }
        }
 
        //TRACE("not find socketpool item.\n");
        lpPerIoData->sAcceptSocket = 0;
        LeaveCriticalSection(&cIocpSection);
        return false;
    }
    else
    {
        for (int nItem = 0; nItem < SHRT_MAX; nItem++)
        {
            if (m_uSocketPool[nItem] == 0)
            {
                m_uSocketPool[nItem] = lpPerStContext->sClientSocket;
                lpPerStContext->sClientSocket = INVALID_SOCKET;
                LeaveCriticalSection(&cIocpSection);
                //TRACE("insert socketpool socket %d.\n",m_uSocketPool[nItem]);
                return true;
            }
        }
    }
 
    LeaveCriticalSection(&cIocpSection);
 
    return false;
}
 
bool CIocpServer::_DestroySocketPool()
{
    linger stlinger;
    stlinger.l_onoff  = 1;
    stlinger.l_linger = 0;
 
    for (int nItem = 0; nItem < SHRT_MAX; nItem++)
    {
        if (m_uSocketPool[nItem] != 0)
        {
            setsockopt(m_uSocketPool[nItem],SOL_SOCKET,SO_LINGER,(char*)&stlinger,sizeof(linger));
            closesocket(m_uSocketPool[nItem]);
        }
    }
 
    return true;
}
 
HANDLE CIocpServer::_BindCreateIoCompletionPort(SOCKET hSocket, HANDLE hCompletionPort, ULONG_PTR lpStContext, DWORD dwNumber)
{
    return CreateIoCompletionPort((HANDLE)hSocket,hCompletionPort,lpStContext,dwNumber);
}
 
unsigned int CIocpServer::_GetProcessOfNumber()
{
    SYSTEM_INFO SystemInfo;
    GetSystemInfo(&SystemInfo);
    return (unsigned int)SystemInfo.dwNumberOfProcessors * 2;
}
 
bool CIocpServer::_InitIOCPServer(unsigned short uPort)
{
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2,2),&wsaData);
 
    // the create overlapped flag listen socket
    m_sListenSocket = WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,0,WSA_FLAG_OVERLAPPED);
    if (m_sListenSocket == INVALID_SOCKET)
    {
        TRACE("m_sListenSocket create error at %d\n",WSAGetLastError());
        return false;
    }
 
    hostent *lphostent;
    char     hostname[hot_size];
    memset(hostname,0,sizeof(hostname));
    if (gethostname(hostname,hot_size) == SOCKET_ERROR)
    {
        TRACE("gethostname error at %d\n",WSAGetLastError());
        return false;
    }
 
    // get lphostent->h_addr_list ip data
    if((lphostent = gethostbyname(hostname)) == NULL)
    {
        TRACE("lphostent returned pointer error at %d\n",WSAGetLastError());
        return false;
    }
 
    // fill sockaddr struct data
    struct sockaddr_in localaddr;
    memset(&localaddr,0,sizeof(localaddr));
    localaddr.sin_family = AF_INET;
    localaddr.sin_port   = htons(uPort);
    localaddr.sin_addr.S_un.S_addr = (*(unsigned long*)lphostent->h_addr);
 
    TRACE("listen server address ip:%s port:%d\n",inet_ntoa(localaddr.sin_addr), ntohs(localaddr.sin_port));
 
    if(bind(m_sListenSocket,(sockaddr*)&localaddr,sizeof(localaddr)) == SOCKET_ERROR)
    {
        TRACE("bind socket error at %d\n",WSAGetLastError());
        return false;
    }
 
    if (listen(m_sListenSocket,SOMAXCONN) == SOCKET_ERROR)
    {
        TRACE("listen socket error at %d\n",WSAGetLastError());
        return false;
    }
 
    // for create _workerthread
    for (u_int i = 0; i < m_uThreads; i++)
    {
        HANDLE hThread = NULL;
        hThread = (HANDLE)_beginthreadex(NULL,NULL,&_WorkerThread,(void*)this,NULL,NULL);
 
        if (hThread == INVALID_HANDLE_VALUE)
        {
            TRACE("thread number error this i = %d\n",i);
            return false;
        }
 
        CloseHandle(hThread);
    }
 
    LP_PER_SOCKET_CONTEXT lpPerStContext = (LP_PER_SOCKET_CONTEXT) \
        GlobalAlloc(GPTR, sizeof(PER_SOCKET_CONTEXT));
    // m_lpContext[0] point m_sListensocket per handle address
    // bind m_slistensocket handle to completion port
    m_lpContext[0] = lpPerStContext;
    _BindCreateIoCompletionPort(m_sListenSocket,m_hCompletionPort,(DWORD)lpPerStContext,0);
 
    DWORD dwBytesIoctl;
    GUID  GuidAcceptEx     = WSAID_ACCEPTEX;
    GUID  GuidDisConnectEx = WSAID_DISCONNECTEX;
 
    // returned acceptex function pointer
    if (WSAIoctl(m_sListenSocket,
        SIO_GET_EXTENSION_FUNCTION_POINTER,
        &GuidAcceptEx,sizeof(GUID),
        &m_lpfnAcceptEx,sizeof(m_lpfnAcceptEx),
        &dwBytesIoctl,NULL,NULL) == SOCKET_ERROR)
    {
        TRACE("return m_lpfnAcceptEx pointer error at %d\n",WSAGetLastError());
        return 1;
    }
 
    // returned disconnectex function pointer
    if (WSAIoctl(m_sListenSocket,
        SIO_GET_EXTENSION_FUNCTION_POINTER,
        &GuidDisConnectEx,sizeof(GUID),
        &m_lpfnDisconnectEx,
        sizeof(m_lpfnDisconnectEx),
        &dwBytesIoctl,NULL,NULL) == SOCKET_ERROR)
    {
        TRACE("return m_lpfnGetAcceptExAddrs error at %d\n",WSAGetLastError());
        return 1;
    }
 
    // 需要把监听端口绑定到完成端口 然后投递多个AcceptEx
    for (u_int i = 0; i < m_uThreads; i++)
        _PostAcceptEx(lpPerStContext);
 
    return true;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费
支持
分享
最新回复 (8)
雪    币: 2
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
一个回复都都没,太蛋疼了。。
2014-2-9 01:28
0
雪    币: 2105
活跃值: (594)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
回复一下。
2014-2-10 09:48
0
雪    币: 35
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
谢谢 很有用!
2014-2-10 10:11
0
雪    币: 25
活跃值: (315)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
m_lpfnDisconnectEx根本就没用
2014-4-9 11:22
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
我来给你回复
2014-4-10 00:35
0
雪    币: 36
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
蛮好 给你增加回复
2014-4-10 18:38
0
雪    币: 25
活跃值: (315)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
socket回收再利用,虽然写了那个扩展,可是根本没调用
2014-4-11 18:38
0
雪    币: 179
活跃值: (31)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
客户端代码呢。。贴出来学习一下。。
2021-3-28 20:27
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册