NetComm-TCPServer
来源:互联网 发布:数据相关法律问题 编辑:程序博客网 时间:2024/05/16 09:57
#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;
}
- NetComm-TCPServer
- tcpServer
- TCPServer
- NetComm-CommDefine
- NetComm-CommuApp
- NetComm-TCPConnect
- tcpserver/client
- tcpserver.c
- TCPserver客户端
- tcpclient tcpserver
- muduo : TcpServer
- handy : TcpServer
- Winsock API TCPServer
- TCPServer 的一般参数
- WIN网络编程-TCPServer
- Poco::TCPServer框架解析
- Qt的tcpserver demo
- POCO中的TCPServer分析
- 交换机中的交换表的自学习
- 对硬盘进行分区和格式化
- 常用数据结构
- NetComm-CommDefine
- NetComm-CommuApp
- NetComm-TCPServer
- 使用matlab对图像进行二值化和灰度化处理
- spark textFile 困惑与解释
- NetComm-TCPConnect
- 文章标题
- 笔记13
- J2EE的13个规范总结
- 以程序员专业的角度告诉你,头条推荐机制具体是怎么样的
- 面试宝典读书笔记