|
@@ -1,5 +1,5 @@
|
|
|
#include "StdAfx.h"
|
|
|
-#include "IOCPModel.h"
|
|
|
+#include "SATTCPServer.h"
|
|
|
//#include "MainDlg.h"
|
|
|
|
|
|
// 每一个处理器上产生多少个线程(为了最大限度的提升服务器性能,详见配套文档)
|
|
@@ -21,7 +21,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
-CIOCPModel::CIOCPModel(void):
|
|
|
+CSATTCPServer::CSATTCPServer(void):
|
|
|
m_nThreads(0),
|
|
|
m_hShutdownEvent(NULL),
|
|
|
m_hIOCompletionPort(NULL),
|
|
@@ -35,7 +35,7 @@ CIOCPModel::CIOCPModel(void):
|
|
|
}
|
|
|
|
|
|
|
|
|
-CIOCPModel::~CIOCPModel(void)
|
|
|
+CSATTCPServer::~CSATTCPServer(void)
|
|
|
{
|
|
|
// 确保资源彻底释放
|
|
|
this->Stop();
|
|
@@ -49,10 +49,10 @@ CIOCPModel::~CIOCPModel(void)
|
|
|
// 也就是每当完成端口上出现了完成数据包,就将之取出来进行处理的线程
|
|
|
///////////////////////////////////////////////////////////////////
|
|
|
|
|
|
-DWORD WINAPI CIOCPModel::_WorkerThread(LPVOID lpParam)
|
|
|
+DWORD WINAPI CSATTCPServer::_WorkerThread(LPVOID lpParam)
|
|
|
{
|
|
|
THREADPARAMS_WORKER* pParam = (THREADPARAMS_WORKER*)lpParam;
|
|
|
- CIOCPModel* pIOCPModel = (CIOCPModel*)pParam->pIOCPModel;
|
|
|
+ CSATTCPServer* pIOCPModel = (CSATTCPServer*)pParam->pIOCPModel;
|
|
|
int nThreadNo = (int)pParam->nThreadNo;
|
|
|
|
|
|
pIOCPModel->_ShowMessage(_T("工作者线程启动,ID: %d."),nThreadNo);
|
|
@@ -165,7 +165,7 @@ DWORD WINAPI CIOCPModel::_WorkerThread(LPVOID lpParam)
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
// 初始化WinSock 2.2
|
|
|
-bool CIOCPModel::LoadSocketLib()
|
|
|
+bool CSATTCPServer::LoadSocketLib()
|
|
|
{
|
|
|
WSADATA wsaData;
|
|
|
int nResult;
|
|
@@ -182,7 +182,7 @@ bool CIOCPModel::LoadSocketLib()
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
// 启动服务器
|
|
|
-bool CIOCPModel::Start(unsigned int port)
|
|
|
+bool CSATTCPServer::Start(unsigned int port)
|
|
|
{
|
|
|
// 初始化线程互斥量
|
|
|
InitializeCriticalSection(&m_csContextList);
|
|
@@ -221,7 +221,7 @@ bool CIOCPModel::Start(unsigned int port)
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
// 开始发送系统退出消息,退出完成端口和线程资源
|
|
|
-void CIOCPModel::Stop()
|
|
|
+void CSATTCPServer::Stop()
|
|
|
{
|
|
|
if( m_pListenContext!=NULL && m_pListenContext->m_Socket!=INVALID_SOCKET )
|
|
|
{
|
|
@@ -250,7 +250,7 @@ void CIOCPModel::Stop()
|
|
|
|
|
|
////////////////////////////////
|
|
|
// 初始化完成端口
|
|
|
-bool CIOCPModel::_InitializeIOCP()
|
|
|
+bool CSATTCPServer::_InitializeIOCP()
|
|
|
{
|
|
|
// 建立第一个完成端口
|
|
|
m_hIOCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0 );
|
|
@@ -285,7 +285,7 @@ bool CIOCPModel::_InitializeIOCP()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
// 初始化Socket
|
|
|
-bool CIOCPModel::_InitializeListenSocket(unsigned int port)
|
|
|
+bool CSATTCPServer::_InitializeListenSocket(unsigned int port)
|
|
|
{
|
|
|
// AcceptEx 和 GetAcceptExSockaddrs 的GUID,用于导出函数指针
|
|
|
GUID GuidAcceptEx = WSAID_ACCEPTEX;
|
|
@@ -409,7 +409,7 @@ bool CIOCPModel::_InitializeListenSocket(unsigned int port)
|
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
|
// 最后释放掉所有资源
|
|
|
-void CIOCPModel::_DeInitialize()
|
|
|
+void CSATTCPServer::_DeInitialize()
|
|
|
{
|
|
|
// 删除客户端列表的互斥量
|
|
|
DeleteCriticalSection(&m_csContextList);
|
|
@@ -444,7 +444,7 @@ void CIOCPModel::_DeInitialize()
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
|
// 投递Accept请求
|
|
|
-bool CIOCPModel::_PostAccept( PER_IO_CONTEXT* pAcceptIoContext )
|
|
|
+bool CSATTCPServer::_PostAccept( PER_IO_CONTEXT* pAcceptIoContext )
|
|
|
{
|
|
|
ASSERT( INVALID_SOCKET!=m_pListenContext->m_Socket );
|
|
|
|
|
@@ -484,7 +484,7 @@ bool CIOCPModel::_PostAccept( PER_IO_CONTEXT* pAcceptIoContext )
|
|
|
// 总之你要知道,传入的是ListenSocket的Context,我们需要复制一份出来给新连入的Socket用
|
|
|
// 原来的Context还是要在上面继续投递下一个Accept请求
|
|
|
//
|
|
|
-bool CIOCPModel::_DoAccpet( PER_SOCKET_CONTEXT* pSocketContext, PER_IO_CONTEXT* pIoContext )
|
|
|
+bool CSATTCPServer::_DoAccpet( PER_SOCKET_CONTEXT* pSocketContext, PER_IO_CONTEXT* pIoContext )
|
|
|
{
|
|
|
SOCKADDR_IN* ClientAddr = NULL;
|
|
|
SOCKADDR_IN* LocalAddr = NULL;
|
|
@@ -564,7 +564,7 @@ bool CIOCPModel::_DoAccpet( PER_SOCKET_CONTEXT* pSocketContext, PER_IO_CONTEXT*
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
// 投递接收数据请求
|
|
|
-bool CIOCPModel::_PostRecv( PER_IO_CONTEXT* pIoContext )
|
|
|
+bool CSATTCPServer::_PostRecv( PER_IO_CONTEXT* pIoContext )
|
|
|
{
|
|
|
// 初始化变量
|
|
|
DWORD dwFlags = 0;
|
|
@@ -589,7 +589,7 @@ bool CIOCPModel::_PostRecv( PER_IO_CONTEXT* pIoContext )
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
// 在有接收的数据到达的时候,进行处理
|
|
|
-bool CIOCPModel::_DoRecv( PER_SOCKET_CONTEXT* pSocketContext, PER_IO_CONTEXT* pIoContext )
|
|
|
+bool CSATTCPServer::_DoRecv( PER_SOCKET_CONTEXT* pSocketContext, PER_IO_CONTEXT* pIoContext )
|
|
|
{
|
|
|
// 先把上一次的数据显示出现,然后就重置状态,发出下一个Recv请求
|
|
|
SOCKADDR_IN* ClientAddr = &pSocketContext->m_ClientAddr;
|
|
@@ -625,7 +625,7 @@ bool CIOCPModel::_DoRecv( PER_SOCKET_CONTEXT* pSocketContext, PER_IO_CONTEXT* pI
|
|
|
|
|
|
/////////////////////////////////////////////////////
|
|
|
// 将句柄(Socket)绑定到完成端口中
|
|
|
-bool CIOCPModel::_AssociateWithIOCP( PER_SOCKET_CONTEXT *pContext )
|
|
|
+bool CSATTCPServer::_AssociateWithIOCP( PER_SOCKET_CONTEXT *pContext )
|
|
|
{
|
|
|
// 将用于和客户端通信的SOCKET绑定到完成端口中
|
|
|
HANDLE hTemp = CreateIoCompletionPort((HANDLE)pContext->m_Socket, m_hIOCompletionPort, (DWORD)pContext, 0);
|
|
@@ -651,7 +651,7 @@ bool CIOCPModel::_AssociateWithIOCP( PER_SOCKET_CONTEXT *pContext )
|
|
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
|
// 将客户端的相关信息存储到数组中
|
|
|
-void CIOCPModel::_AddToContextList( PER_SOCKET_CONTEXT *pHandleData )
|
|
|
+void CSATTCPServer::_AddToContextList( PER_SOCKET_CONTEXT *pHandleData )
|
|
|
{
|
|
|
EnterCriticalSection(&m_csContextList);
|
|
|
|
|
@@ -662,7 +662,7 @@ void CIOCPModel::_AddToContextList( PER_SOCKET_CONTEXT *pHandleData )
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
// 移除某个特定的Context
|
|
|
-void CIOCPModel::_RemoveContext( PER_SOCKET_CONTEXT *pSocketContext )
|
|
|
+void CSATTCPServer::_RemoveContext( PER_SOCKET_CONTEXT *pSocketContext )
|
|
|
{
|
|
|
EnterCriticalSection(&m_csContextList);
|
|
|
|
|
@@ -681,7 +681,7 @@ void CIOCPModel::_RemoveContext( PER_SOCKET_CONTEXT *pSocketContext )
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
// 清空客户端信息
|
|
|
-void CIOCPModel::_ClearContextList()
|
|
|
+void CSATTCPServer::_ClearContextList()
|
|
|
{
|
|
|
EnterCriticalSection(&m_csContextList);
|
|
|
|
|
@@ -707,7 +707,7 @@ void CIOCPModel::_ClearContextList()
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
|
// 获得本机的IP地址
|
|
|
-CString CIOCPModel::GetLocalIP()
|
|
|
+CString CSATTCPServer::GetLocalIP()
|
|
|
{
|
|
|
// 获得本机主机名
|
|
|
char hostname[MAX_PATH] = {0};
|
|
@@ -731,7 +731,7 @@ CString CIOCPModel::GetLocalIP()
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
|
// 获得本机中处理器的数量
|
|
|
-int CIOCPModel::_GetNoOfProcessors()
|
|
|
+int CSATTCPServer::_GetNoOfProcessors()
|
|
|
{
|
|
|
SYSTEM_INFO si;
|
|
|
|
|
@@ -742,7 +742,7 @@ int CIOCPModel::_GetNoOfProcessors()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
// 在主界面中显示提示信息
|
|
|
-void CIOCPModel::_ShowMessage(const CString szFormat,...) const
|
|
|
+void CSATTCPServer::_ShowMessage(const CString szFormat,...) const
|
|
|
{
|
|
|
// 根据传入的参数格式化字符串
|
|
|
CString strMessage;
|
|
@@ -766,11 +766,11 @@ void CIOCPModel::_ShowMessage(const CString szFormat,...) const
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
-#define PAK_LEN sizeof(ProHeader)
|
|
|
-void CIOCPModel::_RecvProcess(PER_SOCKET_CONTEXT* pSocketContext, PER_IO_CONTEXT* pIoContext)
|
|
|
+#define PAK_LEN sizeof(DataHeader)
|
|
|
+void CSATTCPServer::_RecvProcess(PER_SOCKET_CONTEXT* pSocketContext, PER_IO_CONTEXT* pIoContext)
|
|
|
{
|
|
|
// 小于包头;
|
|
|
- ProHeader* phead = NULL;
|
|
|
+ DataHeader* phead = NULL;
|
|
|
if (pSocketContext->lastData.size() == 0)
|
|
|
{
|
|
|
// 不足包头;
|
|
@@ -781,13 +781,14 @@ void CIOCPModel::_RecvProcess(PER_SOCKET_CONTEXT* pSocketContext, PER_IO_CONTEXT
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- phead = (ProHeader*)pIoContext->m_wsaBuf.buf;
|
|
|
+ // 包头充足;
|
|
|
+ phead = (DataHeader*)pIoContext->m_wsaBuf.buf;
|
|
|
|
|
|
// 完整的包;
|
|
|
if (phead->len == pIoContext->m_Overlapped.InternalHigh)
|
|
|
{
|
|
|
OutputDebugString("A:完整的包;\n");
|
|
|
- _DeviceProc(pIoContext, (Package*)pIoContext->m_wsaBuf.buf);
|
|
|
+ _TaskProcess(pIoContext, (Package*)pIoContext->m_wsaBuf.buf);
|
|
|
}
|
|
|
// 小包;
|
|
|
else if (phead->len > pIoContext->m_Overlapped.InternalHigh)
|
|
@@ -800,7 +801,7 @@ void CIOCPModel::_RecvProcess(PER_SOCKET_CONTEXT* pSocketContext, PER_IO_CONTEXT
|
|
|
{
|
|
|
OutputDebugString("A:超包;\n");
|
|
|
pSocketContext->lastData.append(pIoContext->m_wsaBuf.buf + phead->len, pIoContext->m_Overlapped.InternalHigh - phead->len);
|
|
|
- _DeviceProc(pIoContext, (Package*)pIoContext->m_wsaBuf.buf);
|
|
|
+ _TaskProcess(pIoContext, (Package*)pIoContext->m_wsaBuf.buf);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -809,14 +810,14 @@ void CIOCPModel::_RecvProcess(PER_SOCKET_CONTEXT* pSocketContext, PER_IO_CONTEXT
|
|
|
int lastlen = pIoContext->m_Overlapped.InternalHigh;
|
|
|
if (pSocketContext->lastData.size() >= PAK_LEN)
|
|
|
{
|
|
|
- phead = (ProHeader*)pSocketContext->lastData.data();
|
|
|
+ phead = (DataHeader*)pSocketContext->lastData.data();
|
|
|
if (phead->len <= pSocketContext->lastData.size() + pIoContext->m_Overlapped.InternalHigh)
|
|
|
{
|
|
|
if ( phead->len <= pSocketContext->lastData.size() )
|
|
|
{
|
|
|
OutputDebugString("C:超包;\n");
|
|
|
// 完整包;
|
|
|
- _DeviceProc(pIoContext, (Package*)pSocketContext->lastData.substr(0, phead->len).data());
|
|
|
+ _TaskProcess(pIoContext, (Package*)pSocketContext->lastData.substr(0, phead->len).data());
|
|
|
|
|
|
pSocketContext->lastData = pSocketContext->lastData.substr(phead->len);
|
|
|
pSocketContext->lastData.append(pIoContext->m_wsaBuf.buf, pIoContext->m_Overlapped.InternalHigh);
|
|
@@ -827,7 +828,7 @@ void CIOCPModel::_RecvProcess(PER_SOCKET_CONTEXT* pSocketContext, PER_IO_CONTEXT
|
|
|
lastlen = pSocketContext->lastData.size() + pIoContext->m_Overlapped.InternalHigh - phead->len;
|
|
|
pSocketContext->lastData.append(pIoContext->m_wsaBuf.buf, pIoContext->m_Overlapped.InternalHigh - lastlen);
|
|
|
// 完整包;
|
|
|
- _DeviceProc(pIoContext, (Package*)pSocketContext->lastData.data());
|
|
|
+ _TaskProcess(pIoContext, (Package*)pSocketContext->lastData.data());
|
|
|
// 剩余包;
|
|
|
pSocketContext->lastData.clear();
|
|
|
if (lastlen)
|
|
@@ -854,14 +855,14 @@ void CIOCPModel::_RecvProcess(PER_SOCKET_CONTEXT* pSocketContext, PER_IO_CONTEXT
|
|
|
{
|
|
|
// 拼成完整包头;
|
|
|
pSocketContext->lastData.append(pIoContext->m_wsaBuf.buf, diflen);
|
|
|
- phead = (ProHeader*)pSocketContext->lastData.data();
|
|
|
+ phead = (DataHeader*)pSocketContext->lastData.data();
|
|
|
|
|
|
// 完整包;
|
|
|
if ( phead->len == PAK_LEN + pIoContext->m_Overlapped.InternalHigh - diflen )
|
|
|
{
|
|
|
OutputDebugString("B:完整包;\n");
|
|
|
pSocketContext->lastData.append(pIoContext->m_wsaBuf.buf + diflen, pIoContext->m_Overlapped.InternalHigh - diflen);
|
|
|
- _DeviceProc(pIoContext, (Package*)pSocketContext->lastData.data());
|
|
|
+ _TaskProcess(pIoContext, (Package*)pSocketContext->lastData.data());
|
|
|
pSocketContext->lastData.clear();
|
|
|
}
|
|
|
// 小包;
|
|
@@ -876,7 +877,7 @@ void CIOCPModel::_RecvProcess(PER_SOCKET_CONTEXT* pSocketContext, PER_IO_CONTEXT
|
|
|
OutputDebugString("B:超包;\n");
|
|
|
// 组完成包;
|
|
|
pSocketContext->lastData.append(pIoContext->m_wsaBuf.buf + diflen, phead->len - PAK_LEN);
|
|
|
- _DeviceProc(pIoContext, (Package*)pSocketContext->lastData.data());
|
|
|
+ _TaskProcess(pIoContext, (Package*)pSocketContext->lastData.data());
|
|
|
pSocketContext->lastData.clear();
|
|
|
int last = pIoContext->m_Overlapped.InternalHigh - diflen - phead->len + PAK_LEN;
|
|
|
if (last)
|
|
@@ -889,20 +890,15 @@ void CIOCPModel::_RecvProcess(PER_SOCKET_CONTEXT* pSocketContext, PER_IO_CONTEXT
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void CIOCPModel::_DeviceProc(PER_IO_CONTEXT* pIoContext, Package* pak)
|
|
|
+void CSATTCPServer::_TaskProcess(PER_IO_CONTEXT* pIoContext, Package* pak)
|
|
|
{
|
|
|
- if ( pak->header.version != 0xAA )
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
cJSON* pJson = cJSON_Parse((const char*)&pak->buf);
|
|
|
if ( pJson == NULL )
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- RequesJson reqj;
|
|
|
+ RequestJson reqj;
|
|
|
reqj.device_id = cJSON_GetObjectItem(pJson, "device_id") ? cJSON_GetObjectItem(pJson, "device_id")->valueint : 0;
|
|
|
reqj.device_name = cJSON_GetObjectItem(pJson, "device_name") ? cJSON_GetObjectItem(pJson, "device_name")->valuestring : "";
|
|
|
reqj.device_cmd = cJSON_GetObjectItem(pJson, "device_cmd") ? cJSON_GetObjectItem(pJson, "device_cmd")->valuestring : "";
|
|
@@ -913,7 +909,6 @@ void CIOCPModel::_DeviceProc(PER_IO_CONTEXT* pIoContext, Package* pak)
|
|
|
cJSON_Delete(pJson);
|
|
|
pJson = NULL;
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
@@ -921,7 +916,7 @@ void CIOCPModel::_DeviceProc(PER_IO_CONTEXT* pIoContext, Package* pak)
|
|
|
// 使用的方法是尝试向这个socket发送数据,判断这个socket调用的返回值
|
|
|
// 因为如果客户端网络异常断开(例如客户端崩溃或者拔掉网线等)的时候,服务器端是无法收到客户端断开的通知的
|
|
|
|
|
|
-bool CIOCPModel::_IsSocketAlive(SOCKET s)
|
|
|
+bool CSATTCPServer::_IsSocketAlive(SOCKET s)
|
|
|
{
|
|
|
int nByteSent=send(s,"",0,0);
|
|
|
if (-1 == nByteSent) return false;
|
|
@@ -930,7 +925,7 @@ bool CIOCPModel::_IsSocketAlive(SOCKET s)
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////
|
|
|
// 显示并处理完成端口上的错误
|
|
|
-bool CIOCPModel::HandleError( PER_SOCKET_CONTEXT *pContext,const DWORD& dwErr )
|
|
|
+bool CSATTCPServer::HandleError( PER_SOCKET_CONTEXT *pContext,const DWORD& dwErr )
|
|
|
{
|
|
|
// 如果是超时了,就再继续等吧
|
|
|
if(WAIT_TIMEOUT == dwErr)
|