NetComm-TCPServer

来源:互联网 发布:数据相关法律问题 编辑:程序博客网 时间:2024/05/16 09:57
#pragma once
#include <map>
#include <list>
#include "tcpconnect.h"


class CTCPServer :
  public CTCPConnect
{
public:
  CTCPServer(void);
  ~CTCPServer(void);


  friend unsigned __stdcall StartServerRecv(void* pArguments);
  friend unsigned __stdcall StartListen(void* pArguments);


public:
  bool Start(std::string& strIP, unsigned short& siPort, TCPCONNECT::BLOCKING_MODE& enMode, bool bReconnect = false, int iTimeout = 10);


  bool Stop(bool bEnforce = false);


  bool StopConnected(TCPCONNECT::CONNECT_INFO& refConnectInfo);


  bool SendData(TCPCONNECT::CONNECT_INFO& refConnectInfo, char* pszSendBuf, int iSendBufLen);


private:
  /*
  * Desc: 
  *     创建服务侦听环境
  * Pram:
  *     strListenIP    决定在哪个IP上侦听
  *     siListenPort   决定在哪个Port上侦听 
  *     enMode         决定通讯的阻塞模式
  *         
  * Retr:
  *     SOCKET         通讯侦听SOCKET句柄
  */
  SOCKET CreateListenEnvironment(std::string &strListenIP, short& siListenPort, TCPCONNECT::BLOCKING_MODE& enMode);


  /*
  * Desc: 
  *     准备接受客户端的接入
  * Pram:
  *         
  * Retr:
  *     SOCKET         通讯侦听SOCKET句柄
  */
  HANDLE PrepareAcceptConnect();


  /*
  * Desc: 
  *     创建处理客户端接入线程
  * Pram:
  *
  * Retr:
  *     HANDLE     成功返回处理线程句柄
  */
  HANDLE CreateClientDealThreads();


  /*
  * Desc: 
  *     往处理客户端接入线程中投递客户端连接信息
  * Pram:
  *     sClientSocket 客户端通讯SOCKET句柄
  *     addrClient    通讯客户端地址信息
  * Retr:
  *     bool          成功递交客户端连接信息, 递交连接信息失败
  */
  bool PutInClientConnect(SOCKET& sClientSocket, SOCKADDR_IN& addrClient);
    
  /*
  * Desc: 
  *     断开某客户端的连接
  * Pram:
  *     iClientSocket   客户接入SOCKET句柄
  * Retr:
  *     void
  */
  void DeletClientConnect(int& iClientSocket);


  /*
  * Desc: 
  *     以阻塞方式接收数据
  * Pram:
  *     stConnectDetailInfo   客户端详细信息,见CLIENT_DETAIL_INFO定义
  * Retr:
  *     bool                  处理成功:true;处理失败:false
  */
  bool DealBlockingRecv(TCPCONNECT::CLIENT_DETAIL_INFO& stConnectDetailInfo);
  
  /*
  * Desc: 
  *     以非阻塞方式接收数据
  * Pram:
  *     stConnectDetailInfo   客户端详细信息,见CLIENT_DETAIL_INFO定义
  * Retr:
  *     bool                  处理成功:true;处理失败:false
  */
  bool DealUnBlockingRecv(TCPCONNECT::CLIENT_DETAIL_INFO& stConnectDetailInfo);
   
  /*
  * Desc: 
  *     处理接收到的数据缓冲区
  * Pram:
  *     stConnectDetailInfo   客户端详细信息,见CLIENT_DETAIL_INFO定义
  * Retr:
  *     bool                  处理成功:true;处理失败:false
  */
  bool DealWithRecvBuffer(TCPCONNECT::CLIENT_DETAIL_INFO& stConnectDetailInfo);


  /*
  * Desc: 
  *     以阻塞方式发送数据
  * Pram:
  *     sClient         SOCKET 连接句柄
  *     pszNetPackage   网络报文
  *     iNetPackageLen  网络报文长度
  * Retr:
  *     bool            发送成功:true; 发送失败:false
  */
  bool SendDataByBlocking(SOCKET sClient, char* pszNetPackage, int iNetPackageLen);


  /*
  * Desc: 
  *     以非阻塞方式发送数据
  * Pram:
  *     sClient         SOCKET 连接句柄
  *     pszNetPackage   网络报文
  *     iNetPackageLen  网络报文长度
  * Retr:
  *     bool            发送成功:true; 发送失败:false
  */
  bool SendDataByUnBlocking(SOCKET sClient, char* pszNetPackage, int iNetPackageLen);
   
  /*
  * Desc: 
  *     退出侦听线程
  * Pram:
  *     
  * Retr:
  *     void
  */
  void QuitListenThread(bool bEnforce);
   
  /*
  * Desc: 
  *     退出客户接入连接线程
  * Pram:
  *     
  * Retr:
  *     void
  */
  void QuitRecvClientThread(bool bEnforce);
  


private:
  SOCKET        m_sListen;                    // 连接SOCKET侦听句柄
  std::string   m_strServerIP;
  short int     m_siServerPort;
  int           m_iListenTimeout;             // 侦听超时
  TCPCONNECT::BLOCKING_MODE m_enBlockingMode; // 阻塞模式


  HANDLE        m_hListenThread;              // 侦听线程句柄
  HANDLE        m_hDealWithClientRecv;        // 接收客户端数据处理线程         【该线程优化使用线程池来做!!(每个客户连接占用一个线程不可取)】
  bool          m_bQuitClientRecvThread;      // 决定退出接收客户端数据处理线程 【与m_hDealWithClientRecv配置使用】
  
  mylib::CMyCriticalSection                      m_csClients;   // 客户端连接信息同步锁
  std::list<int>                                 m_listClients; // 客户端连接句柄集
  std::map<int, TCPCONNECT::CLIENT_DETAIL_INFO>  m_mapClients;  // 客户端连接信息集合

};

//#include "Stdafx.h"
#include "TCPServer.h"
#include <iostream>
#include <process.h>
#include <algorithm>




CTCPServer::CTCPServer(void)
:m_sListen(INVALID_SOCKET)
,m_hListenThread(INVALID_HANDLE_VALUE)
,m_hDealWithClientRecv(INVALID_HANDLE_VALUE)
,m_bQuitClientRecvThread(false)
{
}




CTCPServer::~CTCPServer(void)
{
}




bool CTCPServer::Start(std::string& strIP, unsigned short& siPort, TCPCONNECT::BLOCKING_MODE& enMode,  bool bReconnect, int iTimeout)
{
bool bReturn = false;
m_strServerIP = strIP;
m_siServerPort = siPort;
m_iListenTimeout = iTimeout;
m_enBlockingMode = TCPCONNECT::BLOCKING_MODE::MODE_UNBLOCKING /*enMode*/; // 由于服务端接收客户端数据是以线程任务执行的,为不阻塞线程的运行强制设置为非阻塞模式 


TCPCONNECT::CONNECT_INFO stListenInfo;


m_sListen = CreateListenEnvironment(m_strServerIP, m_siServerPort, m_enBlockingMode);//监听端口
if (m_sListen == INVALID_SOCKET) 
{
//std::cout << "创建客户端环境失败" << std::endl;
}
else 
{
stListenInfo.iSocketHandle = m_sListen;
m_hListenThread = PrepareAcceptConnect();//创建接收连接线程
if(m_hListenThread == INVALID_HANDLE_VALUE) 
{
closesocket(m_sListen);
m_sListen = INVALID_SOCKET;
//DestroyNetEnvironment();
m_pclCommuApplication->NetEvent(stListenInfo, (int)TCPCONNECT::LISTEN_FAILD_EVENT);
std::cout << "服务端侦听失败,IP:" << m_strServerIP << " PORT:"<<m_siServerPort << std::endl;
}
else 
{
bool bOptval = true;
setsockopt(m_sListen, IPPROTO_TCP, TCP_NODELAY, (char*)&bOptval, sizeof(bOptval));//设置socket属性
m_pclCommuApplication->NetEvent(stListenInfo, (int)TCPCONNECT::LISTEN_SUCCESS_EVENT);
//std::cout << "服务端侦听进行中,IP:" << m_strServerIP << " PORT:"<<m_siServerPort << std::endl;


m_hDealWithClientRecv = INVALID_HANDLE_VALUE;
m_hDealWithClientRecv = CreateClientDealThreads();
if (m_hDealWithClientRecv == INVALID_HANDLE_VALUE)
{
//std::cout << "创建处理客户端接入线程失败!" << std::endl;
}
else
{
//std::cout << "创建处理客户端接入线程成功!" << std::endl;
}
}
}




return bReturn;
}


bool CTCPServer::Stop(bool bEnforce)
{
bool bReturn = true;


QuitListenThread(bEnforce);//退出监听线程


m_bQuitClientRecvThread = false;




std::map<int, TCPCONNECT::CLIENT_DETAIL_INFO>::iterator iter = m_mapClients.begin();
for (; iter != m_mapClients.end(); iter++) 
{
closesocket(iter->first);
}
QuitRecvClientThread(bEnforce);//退出接收线程


iter = m_mapClients.begin();
for (; iter != m_mapClients.end(); iter++)
{
delete[] iter->second.pszRecvBuf;
}


{
mylib::CCriticalSectionGuard lockGuard(m_csClients);
m_mapClients.clear();
m_listClients.clear();
}




//DestroyNetEnvironment();




return bReturn;
}


bool CTCPServer::StopConnected(TCPCONNECT::CONNECT_INFO& refConnectInfo)
{
bool bReturn = true;


DeletClientConnect(refConnectInfo.iSocketHandle);//删除某个连接


return bReturn;
}


void CTCPServer::DeletClientConnect(int& iClientSocket)
{
mylib::CCriticalSectionGuard lockGuard(m_csClients);
std::list<int>::iterator iterList = std::find(m_listClients.begin(), m_listClients.end(), iClientSocket);
if (iterList != m_listClients.end())
{
m_listClients.erase(iterList);
}


std::map<int, TCPCONNECT::CLIENT_DETAIL_INFO>::iterator iterMap = m_mapClients.find(iClientSocket);
if (iterMap != m_mapClients.end()) 
{
closesocket(iterMap->first);
delete[] iterMap->second.pszRecvBuf;
m_mapClients.erase(iterMap->first);
}
}


bool CTCPServer::SendData(TCPCONNECT::CONNECT_INFO& refConnectInfo, char* pszSendBuf, int iSendBufLen)
{
bool bReturn = false;


//将输入的数据发送过去
//先组网络包增
char* pszNetPackage = NULL;
int   iNetPackageLen = 0;
if (m_pclCommuAnalyzer->PackNetPackage(pszSendBuf, iSendBufLen, pszNetPackage, iNetPackageLen) == false) //组包
{
//std::cout << "组包失败:( " << pszNetPackage << ")" << std::endl;
}
else
{
if (m_enBlockingMode == TCPCONNECT::MODE_BLOCKING) 
{
bReturn = SendDataByBlocking(refConnectInfo.iSocketHandle, pszNetPackage, iNetPackageLen);
}
else 
{
bReturn = SendDataByUnBlocking(refConnectInfo.iSocketHandle, pszNetPackage, iNetPackageLen);
}
if(bReturn) 
{
//std::cout << "send 发送数据成功" << std::endl;
delete[] pszNetPackage;
}
else
{
//std::cout << "send 发送数据成功" << std::endl;
bReturn = true;
}
}


return bReturn;
}


void CTCPServer::QuitListenThread(bool bEnforce)
{
if (m_hListenThread != INVALID_HANDLE_VALUE)
{
closesocket(m_sListen);
m_sListen = INVALID_SOCKET;
if (bEnforce) //强制退出线程
{
TerminateThread(m_hListenThread, 0);
}
else //无限等待线程退出
{
WaitForSingleObject(m_hListenThread, INFINITE);
}
m_hListenThread = INVALID_HANDLE_VALUE;
}
}


void CTCPServer::QuitRecvClientThread(bool bEnforce)
{
if (m_hDealWithClientRecv != INVALID_HANDLE_VALUE)
{
m_bQuitClientRecvThread = true;
if (m_hDealWithClientRecv != INVALID_HANDLE_VALUE) 
{
if (bEnforce) 
{
TerminateThread(m_hDealWithClientRecv, 0);
}
else 
{
WaitForSingleObject(m_hDealWithClientRecv, INFINITE);
}
m_hDealWithClientRecv = INVALID_HANDLE_VALUE;
}
}
}


SOCKET CTCPServer::CreateListenEnvironment(std::string &strListenIP, short& siListenPort, TCPCONNECT::BLOCKING_MODE& enMode)
{
SOCKADDR_IN    addrListen;
SOCKET sListen = INVALID_SOCKET;


sListen = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP);
if (sListen == INVALID_SOCKET) 
{
//std::cout << "socket 创建失败: " << WSAGetLastError() << std::endl;
}
else 
{
addrListen.sin_family = AF_INET;
addrListen.sin_addr.S_un.S_addr = inet_addr(strListenIP.c_str());
addrListen.sin_port = htons(siListenPort);
if(SOCKET_ERROR == bind(sListen, (const sockaddr* )&addrListen, sizeof(addrListen)))
{
//std::cout << "bind 失败: " << WSAGetLastError() << std::endl;
closesocket(sListen);
sListen = INVALID_SOCKET;
}
else 
{
if (listen(sListen, 5) == SOCKET_ERROR) 
{
//std::cout << "listen 失败: " << WSAGetLastError() << std::endl;
closesocket( sListen );
sListen = INVALID_SOCKET;
}
else
{
DWORD dwMode = enMode;
if (SOCKET_ERROR == ioctlsocket( sListen, FIONBIO, &dwMode )) 
{
//std::cout << "ioctlsocket 失败: " << WSAGetLastError() << std::endl;
closesocket( sListen );
sListen = INVALID_SOCKET;
}
}
}
}


return sListen;
}


HANDLE CTCPServer::PrepareAcceptConnect()
{
HANDLE hThread = INVALID_HANDLE_VALUE;
unsigned uiThreadID;


hThread = (HANDLE)_beginthreadex(NULL, 0, StartListen, this, 0, &uiThreadID);


return hThread;
}


HANDLE CTCPServer::CreateClientDealThreads()
{
HANDLE hThread = INVALID_HANDLE_VALUE;
unsigned uiThreadID = 0; 


hThread = (HANDLE)_beginthreadex(NULL, 0, StartServerRecv, this, 0, &uiThreadID);
if (hThread != INVALID_HANDLE_VALUE) 
{
}
return hThread;
}


bool CTCPServer::PutInClientConnect(SOCKET& sClientSocket, SOCKADDR_IN& addrClient)
{
bool bReturn = false;


TCPCONNECT::CLIENT_DETAIL_INFO stConnectDetailInfo;//连接信息
stConnectDetailInfo.stConnectInfo.iSocketHandle = sClientSocket;
sprintf_s(stConnectDetailInfo.stConnectInfo.szLocalIp, "%s", m_strServerIP.c_str());
stConnectDetailInfo.stConnectInfo.siLocalPort = m_siServerPort;
sprintf_s(stConnectDetailInfo.stConnectInfo.szConnectIP, "%s", inet_ntoa(addrClient.sin_addr));
stConnectDetailInfo.stConnectInfo.siConnectPort = ntohs(addrClient.sin_port);
stConnectDetailInfo.pclTcpConnect = this;
stConnectDetailInfo.iRecvBufferSize = GetRecvBufferSize();
stConnectDetailInfo.pszRecvBuf = new char[stConnectDetailInfo.iRecvBufferSize];
if (stConnectDetailInfo.pszRecvBuf == NULL)
{
//std::cout << "分配内存失败,所需大小:" << stConnectDetailInfo.iRecvBufferSize << std::endl;
}
else 
{
memset(stConnectDetailInfo.pszRecvBuf, 0x00, stConnectDetailInfo.iRecvBufferSize);


mylib::CCriticalSectionGuard lockGuard(m_csClients);
if (m_mapClients.find(sClientSocket) != m_mapClients.end()) 
{
//std::cout << "出现严重问题,投递客户端时其SOCKET连接句柄重复" << std::endl;
delete[] stConnectDetailInfo.pszRecvBuf;

else 
{
m_mapClients[sClientSocket] = stConnectDetailInfo;
m_listClients.push_back(sClientSocket);


m_pclCommuApplication->NetEvent((*(TCPCONNECT::CONNECT_INFO*)&stConnectDetailInfo), TCPCONNECT::CONNECT_GET_IN_EVENT);
bReturn = true;
}
}


return bReturn;
}


unsigned __stdcall StartListen(void* pArguments)
{
CTCPServer* pThis = ((CTCPServer*)pArguments);


SOCKET         sClient;
SOCKADDR_IN    addrClient;
int            addrClientLen = sizeof(addrClient);


fd_set fdRead;
timeval tv={0, 100};


while(true) 
{
FD_ZERO(&fdRead);
FD_SET(pThis->m_sListen, &fdRead); 
int iRes = select( 0, &fdRead, NULL, NULL, &tv );
if(iRes == 0) 
{
//std::cout << "SELECT 接受连接超时ms :" << tv.tv_sec*1000 + tv.tv_usec / 1000 << std::endl;
continue; //超时继续监听
}
else if( iRes < 0 ) 
{
//std::cout << "select 接受连接失败: " << WSAGetLastError() << std::endl;
break;
}
else 
{
if( FD_ISSET( pThis->m_sListen, &fdRead) ) 
{
sClient = accept(pThis->m_sListen, (sockaddr*)&addrClient, &addrClientLen);
//std::cout << "侦听到客户端的 SOCKET 连接句柄:" << sClient << std::endl;
if(sClient == WSAEWOULDBLOCK) 
{
//std::cout << "非阻塞模式设定 accept调用不正确" << std::endl;
continue;
}
else if(sClient == INVALID_SOCKET) 
{
//std::cout << "accept调用失败" << std::endl;
continue;
}
else 
{
if(pThis->PutInClientConnect(sClient, addrClient)) //递交客户端信息
{


//std::cout << "SOCKET句柄:" << sClient << " 递交客户端接收信息成功,IP:" << inet_ntoa(addrClient.sin_addr) << ", Port:" << ntohs(addrClient.sin_port) << std::endl;
}
else 
{
//std::cout << "SOCKET句柄:" << sClient << " 递交客户端接收信息失败,IP:" << inet_ntoa(addrClient.sin_addr) << ", Port:" << ntohs(addrClient.sin_port) << std::endl;
closesocket(sClient);
}
}
}
else 
{
//std::cout << "调用SD_ISSET(...)发生未知错误" << std::endl;
break;
}
}
}


//std::cout << "退出侦听线程" << std::endl;
_endthreadex(0);
return 0;
}


unsigned __stdcall StartServerRecv(void* pArguments)
{
CTCPServer* pThis = ((CTCPServer*)pArguments);


TCPCONNECT::CLIENT_DETAIL_INFO stConnectDetailInfo;


bool bFindJob = false;


bool bDealSuccess = true;
while(!pThis->m_bQuitClientRecvThread)
{
int iClientSocket = -1;
{
mylib::CCriticalSectionGuard lockGuard(pThis->m_csClients);
std::list<int>::iterator iter = pThis->m_listClients.begin();
if (iter == pThis->m_listClients.end())
{
bFindJob = false;
}
else 
{
bFindJob = true;
iClientSocket = *iter;
pThis->m_listClients.erase(iter);
}
}


if (bFindJob == false)
{
Sleep(100);
continue;
}


stConnectDetailInfo = pThis->m_mapClients[iClientSocket];


if (pThis->m_enBlockingMode == TCPCONNECT::MODE_BLOCKING)
{
bDealSuccess = pThis->DealBlockingRecv(stConnectDetailInfo);
}
else 
{
bDealSuccess =  pThis->DealUnBlockingRecv(stConnectDetailInfo);
}


{
mylib::CCriticalSectionGuard lockGuard(pThis->m_csClients);
if (bDealSuccess == false) 
{
pThis->DeletClientConnect(stConnectDetailInfo.stConnectInfo.iSocketHandle);
pThis->m_pclCommuApplication->NetEvent(stConnectDetailInfo.stConnectInfo, TCPCONNECT::CONNECT_QUIT_EVENT);

else 
{
pThis->m_listClients.push_back(stConnectDetailInfo.stConnectInfo.iSocketHandle);
}
}
}


//std::cout << "退出服务端接入处理线程" << std::endl;
_endthreadex(0);
return 0;
}


bool CTCPServer::DealBlockingRecv(TCPCONNECT::CLIENT_DETAIL_INFO& stConnectDetailInfo)
{
bool bReturn = false;
//阻塞接收数据 
while(true) 
{
int iRecv = recv(stConnectDetailInfo.stConnectInfo.iSocketHandle, stConnectDetailInfo.pszRecvBuf + stConnectDetailInfo.iRcvSum, stConnectDetailInfo.iRecvBufferSize - stConnectDetailInfo.iRcvSum, 0);
if (iRecv < 0 
|| (iRecv == 0 && (stConnectDetailInfo.iRecvBufferSize - stConnectDetailInfo.iRcvSum != 0))) 
{
((CTCPServer*)stConnectDetailInfo.pclTcpConnect)->m_pclCommuApplication->NetEvent((*(TCPCONNECT::CONNECT_INFO*)&stConnectDetailInfo), (int)TCPCONNECT::CONNECT_BREAKED_EVENT);
//std::cout << "recv 接收数据失败, ERROR =  " << WSAGetLastError() << std::endl;
break;
}
else 
{
////std::cout << "recv 接收数据:" << szRecvBuf + iRcvSum << std::endl;
stConnectDetailInfo.iRcvSum += iRecv;
bReturn = DealWithRecvBuffer(stConnectDetailInfo);
if (bReturn == false) 
{
break;
}
}
}


return bReturn;
}
//非阻塞接收
bool CTCPServer::DealUnBlockingRecv(TCPCONNECT::CLIENT_DETAIL_INFO& stConnectDetailInfo)
{
bool bReturn = false;


//  int iRcvSum = 0;
fd_set fdRead;
timeval tv={1, 0};


while(true) 
{
FD_ZERO(&fdRead);
FD_SET(stConnectDetailInfo.stConnectInfo.iSocketHandle, &fdRead);
int iRes = select(0, &fdRead, NULL, NULL, &tv );


if(iRes == 0) 
{
//std::cout << "SELECT 服务端接收数据超时ms :" << tv.tv_sec*1000 + tv.tv_usec / 1000 << std::endl;
bReturn = true;
break;
}
else if( iRes < 0 ) 
{
//std::cout << "select 接收数据失败: " << WSAGetLastError() << std::endl;
m_pclCommuApplication->NetEvent((*(TCPCONNECT::CONNECT_INFO*)&stConnectDetailInfo), (int)TCPCONNECT::CONNECT_BREAKED_EVENT);
break;
}
else 
{
if(FD_ISSET(stConnectDetailInfo.stConnectInfo.iSocketHandle, &fdRead)) 
{
int iRecv = 0;
do 
{
iRecv = recv(stConnectDetailInfo.stConnectInfo.iSocketHandle, stConnectDetailInfo.pszRecvBuf + stConnectDetailInfo.iRcvSum, stConnectDetailInfo.iRecvBufferSize - stConnectDetailInfo.iRcvSum, 0);
if (iRecv == 0 && (stConnectDetailInfo.iRecvBufferSize- stConnectDetailInfo.iRcvSum != 0))
{
FD_CLR(stConnectDetailInfo.stConnectInfo.iSocketHandle, &fdRead);


//            g_clRuntimeMsg.ThrowRuntimeMsg(RUNTIME_MSG_NORMAL, 0x11111111, "客户端断开" );
closesocket(stConnectDetailInfo.stConnectInfo.iSocketHandle);
break;
}
if (iRecv < 0) 
{
if (WSAGetLastError() != 10035) 
{
//std::cout << "recv 接收数据失败, ERROR =  " << WSAGetLastError() << std::endl;
closesocket(stConnectDetailInfo.stConnectInfo.iSocketHandle);
}
}
else 
{
//            g_clRuntimeMsg.ThrowRuntimeMsg(RUNTIME_MSG_NORMAL, 0x11111111, "接收到客户端数据%s", stConnectDetailInfo.pszRecvBuf );
stConnectDetailInfo.iRcvSum += iRecv;
// 处理已经接收到的缓冲区数据
bReturn = DealWithRecvBuffer(stConnectDetailInfo);
if (bReturn == false) 
{
break;
}
}
} while (iRecv > 0); 
if (bReturn = false) 
{
break;
}
}
}
}


return bReturn;
}
//解析回报数据
bool CTCPServer::DealWithRecvBuffer(TCPCONNECT::CLIENT_DETAIL_INFO& stConnectDetailInfo)
{
bool bReturn = true;


int iNetPackageLen = 0;
char* pszPackage = NULL;
int iPackageLen = 0;
int iSkipLen = 0;
int iHeadLen = 0;
int iTailLen = 0;
int iIsHave  = 0;
CCommuAnalyzer* pclAnalyzer = ((CTCPServer*)stConnectDetailInfo.pclTcpConnect)->m_pclCommuAnalyzer;
CCommuApplication* pclApp   = ((CTCPServer*)stConnectDetailInfo.pclTcpConnect)->m_pclCommuApplication;
while(true)
{
pszPackage = NULL;  
iPackageLen = 0;
iSkipLen = 0;
iHeadLen = 0;
iTailLen = 0;
iIsHave = pclAnalyzer->IsExistDirtyData(stConnectDetailInfo.pszRecvBuf, stConnectDetailInfo.iRcvSum, iSkipLen);
if (iSkipLen > 0)
{
memcpy(stConnectDetailInfo.pszRecvBuf, stConnectDetailInfo.pszRecvBuf + iSkipLen, stConnectDetailInfo.iRcvSum - iSkipLen);
memset(stConnectDetailInfo.pszRecvBuf + stConnectDetailInfo.iRcvSum - iSkipLen, 0x00, iSkipLen);
stConnectDetailInfo.iRcvSum -= iSkipLen;
}
if (iIsHave == -2)
{
//      closesocket(stNetParam.sSocket);
bReturn = false;
break;
}


if (pclAnalyzer->IsHasFullPackage(stConnectDetailInfo.pszRecvBuf, stConnectDetailInfo.iRcvSum)) 
{
if(pclAnalyzer->UnpackNetPackage(stConnectDetailInfo.pszRecvBuf, stConnectDetailInfo.iRcvSum, pszPackage, iPackageLen, iHeadLen, iTailLen) == true) 
{
TCPCONNECT::CONNECT_INFO stConnectInfo;
memcpy(&stConnectInfo, &stConnectDetailInfo, sizeof(stConnectInfo));
pclApp->FromNet(stConnectInfo, pszPackage, iPackageLen);
iNetPackageLen = iPackageLen + iHeadLen + iTailLen;
memcpy(stConnectDetailInfo.pszRecvBuf, stConnectDetailInfo.pszRecvBuf + iNetPackageLen, stConnectDetailInfo.iRcvSum - iNetPackageLen);
memset(stConnectDetailInfo.pszRecvBuf + stConnectDetailInfo.iRcvSum - iNetPackageLen, 0x00, iNetPackageLen);
stConnectDetailInfo.iRcvSum -= iNetPackageLen;
}
}
else 
{
break;
}
continue; 
}


return bReturn;
}


bool CTCPServer::SendDataByBlocking(SOCKET sClient, char* pszNetPackage, int iNetPackageLen)
{
bool bReturn = false;
int iIndex = 0;
int iNeedSendLen = iNetPackageLen;
while(iNeedSendLen > 0) 
{
int iSend = send(sClient, pszNetPackage + iIndex, iNeedSendLen, 0);
if(iSend < 0) 
{
//std::cout << "send 发送数据失败, 客户端已经关闭 " << WSAGetLastError() << std::endl;
//            closesocket(sessionID.sClientSocket);
break;
}
iNeedSendLen  -= iSend;
iIndex += iSend; 
}
if (iNeedSendLen == 0) 
{
bReturn = false;
}


return bReturn;
}


bool CTCPServer::SendDataByUnBlocking(SOCKET sClient, char* pszNetPackage, int iNetPackageLen)
{
bool bReturn = false;
int iIndex = 0;
int iNeedSendLen = iNetPackageLen;


while(iNeedSendLen > 0) 
{
__ReSend:
int iSend = send(sClient, pszNetPackage + iIndex, iNeedSendLen, 0);
if(iSend < 0) 
{
//std::cout << "send 发送数据失败,服务端已经关闭 " << WSAGetLastError() << "iSend = " << iSend << std::endl;
int iLastError = WSAGetLastError();
if ( iLastError == 10035)
{
Sleep(100);
goto __ReSend;

else 
{
//std::cout << "输出特殊错误码-------------------------:" << WSAGetLastError() <<std::endl;
break;
}
}


iNeedSendLen  -= iSend;
iIndex += iSend; 
}


if (iNeedSendLen == 0)
{
bReturn = false;
}


return bReturn;
}



原创粉丝点击