// IOCPS.cpp: implementation of the IOCPS class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "IOCPS.h"
#include <io.h> // _get_osfhandle
#include <algorithm> // find
using namespace std;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IOCPS *iocpserver;
IOCPS::IOCPS()
{
WSADATA wsaData;
m_iWSAInitResult = WSAStartup(MAKEWORD(2,2), &wsaData);
m_sServerVersion = IOCPSERVERVERSION;
m_bServerStarted = FALSE;
m_bShutDown = FALSE;
m_sockListen = NULL;
m_nListenPort = 999;
m_pListenThread = NULL;
m_bAcceptConnections = TRUE;
m_iMaxNumConnections = 1201;
m_NumberOfActiveConnections = 0;
m_bOneIPPerConnection = FALSE;
m_bSendInOrder = FALSE;
m_bReadInOrder = FALSE;
m_iNumberOfPendlingReads = 3;
m_iMaxNumberOfFreeContext = 2;
m_bAcceptJobs = TRUE;
m_nOfWorkers = 2;
// time out
m_flagQueue = WT_EXECUTEDEFAULT;
WT_SET_MAX_THREADPOOL_THREADS(m_flagQueue, 2);
nMaxTimeOut = 3*60*1000; // 3分钟还未收到响应
iocpserver = this;
}
IOCPS::~IOCPS()
{
ShutDown();
if (m_iWSAInitResult == NO_ERROR)
WSACleanup();
}
//////////////////////////////////////////////////////////////////////////
// public
//////////////////////////////////////////////////////////////////////////
BOOL IOCPS::Startup()
{
// Some special cleanup
#if defined SIMPLESECURITY
m_OneIPPerConnectionList.clear();
m_BanIPList.clear();
#endif
TRACERT(m_sServerVersion.c_str());
AppendLog(m_sServerVersion.c_str());
TRACERT("---------------------------------");
AppendLog("---------------------------------");
TRACERT("Starting system.");
AppendLog("Starting system.");
m_NumberOfActiveConnections = 0;
if (m_iWSAInitResult != NO_ERROR)
{
ReportError(m_iWSAInitResult, "WSAStartup()");
AppendLog("Failed to initialize Winsock 2.0.");
return FALSE;
}
else // WinSock初始化成功才能继续
{
TRACERT("Winsock 2.0 successfully loaded.");
AppendLog("Winsock 2.0 successfully loaded.");
}
BOOL bRet = TRUE; // 跟踪初始化的过程
m_bAcceptConnections = TRUE;
if (!m_bServerStarted)
{
m_bShutDown = FALSE;
/*
* When using multiple pending reads (eg m_iNumberOfPendlingReads>1)
* with multiple IOworkers (eg m_iMaxIOWorkers>1), the order of the
* packages are broken, because of IOCP internal design, Furthermore there is no
* Performance gain to have multiple pendling reads if we use more than one IO-worker.
* The throughput is going up because of serveral pendling reads, but is going down because of
* the ordering part.
*/
if (m_iMaxIOWorkers > 1) // we have some sort of bug somewhere..
m_iNumberOfPendlingReads = 1; // 多个i/o dispatcher线程,则初始投递一个WSARecv操作,读完一个再投一个
if (m_iNumberOfPendlingReads <= 0)
m_iNumberOfPendlingReads = 1;
TRACERT("Max number of simultaneous connection permitted: %d", m_iMaxNumConnections);
TRACERT("Number of automatically asynchronous pending reads: %d", m_iNumberOfPendlingReads);
// No need to make in order read or write
if (m_iMaxIOWorkers == 1) // 一个线程(i/o dispatcher)不存在调度乱序问题
{
m_bReadInOrder = FALSE;
m_bSendInOrder = FALSE;
}
// If we have several Pending Reads and Several IO workers. We must read in order.
if (m_iNumberOfPendlingReads>1 && m_iMaxIOWorkers>1)
{
m_bReadInOrder = TRUE;
m_bSendInOrder = TRUE;
}
if (m_bSendInOrder)
{
TRACERT("Send ordering initialized. (Decreases the performance by ~3%)");
AppendLog("Send ordering initialized. (Decreases the performance by ~3%)");
}
if (m_bReadInOrder)
{
TRACERT("Read ordering initialized.(Decreases the performance by ~3%)");
AppendLog("Read ordering initialized.(Decreases the performance by ~3%)");
}
// The map must be empty
m_ContextMap.clear();
// Create the CompletionPort used by IO Worker Threads.
bRet &= CreateCompletionPort();
if (bRet)
{
TRACERT("I/O completion port successfully created.");
AppendLog("I/O completion port successfully created.");
}
// Config the Listner..
if (m_nListenPort > 0)
{
bRet &= SetupListener();
if (bRet)
{
TRACERT("Connection listener thread successfully started.");
AppendLog("Connection listener thread successfully started.");
}
}
// Setup the IOWorkers..
bRet &= SetupIOWorkers();
if (bRet)
{
TRACERT("Successfully started %d i/o dispatcher thread.", m_nIOWorkers);
}
// Start the logical Workers. (SetWorkes can be callen in runtime..).
bRet &= SetWorkers(m_nOfWorkers);
if (bRet)
{
TRACERT("Successfully started %d i/o handler thread.", m_nOfWorkers);
}
// Accept incoming Job.
m_bAcceptJobs = TRUE;
m_bServerStarted = TRUE;
}
if (bRet)
{
if (m_nListenPort > 0)
{
TRACERT("Server successfully started.");
AppendLog("Server successfully started.");
TRACERT("Waiting for clients on %s:%d.", GetLocalIP().c_str(), m_nListenPort);
AppendLog("Waiting for clients on %s:%d.", GetLocalIP().c_str(), m_nListenPort);
}
else // client mode
{
TRACERT("Client successfully started.");
AppendLog("Client successfully started.");
}
}
return bRet; // the intialization result
}
/*
* Start the Client/Server.
*/
BOOL IOCPS::Start(int nPort, int iMaxNumConnections, int iMaxIOWorkers,
int nOfWorkers, int iMaxNumberOfFreeBuffer, int iMaxNumberOfFreeContext,
BOOL bOrderedSend, BOOL bOrderedRead, int iNumberOfPendlingReads)
{
m_bShutDown = FALSE;
m_nListenPort = nPort;
m_iMaxNumConnections = iMaxNumConnections;
m_iMaxIOWorkers = iMaxIOWorkers;
m_nOfWorkers = nOfWorkers;
m_iMaxNumberOfFreeContext = iMaxNumberOfFreeContext;
m_iMaxNumberOfFreeBuffer = iMaxNumberOfFreeBuffer;
m_bReadInOrder = bOrderedRead;
m_bSendInOrder = bOrderedSend;
m_iNumberOfPendlingReads = iNumberOfPendlingReads;
return Startup();
}
BOOL IOCPS::IsStarted()
{
return m_bServerStarted;
}
/*
When you are developing server application you may what to protect your server
against SYN attacks..
The SYN flooding attack protection feature of TCP detects symptoms of SYN flooding
and responds by reducing the time server spends on connection requests that it cannot acknowledge.
Specifically, TCP shortens the required interval between SYN-ACK (connection request acknowledgements) retransmissions.
(TCP retransmits SYN-ACKS when they are not answered.) As a result, the allotted number of retransmissions is consumed quicker
and the unacknowledgeable connection request is discarded faster.
The SYN attack protection is obtained by setting some values in the windows registery before you
start the server. Using this windows XP and Windows NT own protection is easy.
The registry key "SynAttackProtect" causes Transmis
没有合适的资源?快使用搜索试试~ 我知道了~
《A Simple IOCP Server/Client Class》

共53个文件
h:22个
cpp:20个
rc:2个


温馨提示
codeproject 《A Simple IOCP Server/Client Class》 整理修改版
资源推荐
资源详情
资源评论













收起资源包目录


























































共 53 条
- 1

弦苦
- 粉丝: 1854
- 资源: 55
上传资源 快速赚钱
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


安全验证
文档复制为VIP权益,开通VIP直接复制

- 1
- 2
- 3
- 4
- 5
- 6
前往页