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

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

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

h文件
/****************************************************************************
*                                                                           *
* 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文件
#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直播授课

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