271 lines
5.3 KiB
C++
271 lines
5.3 KiB
C++
#include "StdAfx.h"
|
||
#include "TcpClient.h"
|
||
#include "QrGuide.h"
|
||
#include <process.h>
|
||
|
||
|
||
CTcpClient::CTcpClient()
|
||
{
|
||
WSADATA wsaData;
|
||
WORD wVersionRequested=MAKEWORD(2, 2);
|
||
if( 0 == WSAStartup (wVersionRequested, &wsaData))
|
||
{
|
||
;
|
||
}
|
||
|
||
m_socket = NULL;
|
||
//m_hWnd = NULL;
|
||
m_sPort = 0;
|
||
memset(m_achSendBuf, 0, 1024);
|
||
|
||
m_hReceive = NULL;
|
||
|
||
m_bStart = FALSE;
|
||
|
||
time(&m_lLastNetTime);
|
||
m_lLastConnectTime = 0;
|
||
}
|
||
|
||
CTcpClient::~CTcpClient(void)
|
||
{
|
||
m_bStart = FALSE;
|
||
closesocket(m_socket);
|
||
m_socket = NULL;
|
||
if (WAIT_TIMEOUT == WaitForSingleObject(m_hReceive, 3000))
|
||
{
|
||
//
|
||
ASSERT(FALSE);
|
||
TerminateThread(m_hReceive, 0);
|
||
}
|
||
}
|
||
|
||
|
||
void CTcpClient::UnInit()
|
||
{
|
||
}
|
||
|
||
void CTcpClient::RegisterHwnd(HWND hWnd, PVOID pParent)
|
||
{
|
||
m_hWnd = hWnd;
|
||
m_pParent = pParent;
|
||
}
|
||
|
||
|
||
//初始化网络配置, strConfName 为ini配置文件中的段名
|
||
int CTcpClient::InitNetInfo(CString strConfName)
|
||
{
|
||
CString strConf = theApp.m_strModulePath + "\\config.ini";
|
||
|
||
|
||
char acIp[64] = {0};
|
||
GetPrivateProfileString(strConfName, "IP", "0.0.0.0", acIp, 63, strConf);
|
||
|
||
m_strServerIp = acIp;
|
||
|
||
m_sPort = (short)GetPrivateProfileInt(strConfName, "PORT", 0, strConf);
|
||
|
||
LogOutToFile("[info] 连接服务器:[%s][%s:%d]", strConfName.GetBuffer(), acIp, m_sPort);
|
||
|
||
return 0;
|
||
}
|
||
|
||
//初始化网络配置, strConfName 为ini配置文件中的段名
|
||
int CTcpClient::InitNetInfo(CString strIp, int nPort)
|
||
{
|
||
m_strServerIp = strIp;
|
||
m_sPort = nPort;
|
||
LogOutToFile("[info] 连接服务器:[%s:%d]", strIp.GetBuffer(), nPort);
|
||
return 0;
|
||
}
|
||
|
||
|
||
BOOL CTcpClient::ConnectServer()
|
||
{
|
||
if (NULL != m_socket)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
m_bStart = TRUE;
|
||
m_hReceive = (HANDLE)_beginthreadex(NULL, 0, recvThread, this, 0, NULL);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
int CTcpClient::StopConnect()
|
||
{
|
||
if (NULL == m_socket || NULL == m_hReceive)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
m_bStart = FALSE;
|
||
closesocket(m_socket);
|
||
if (WAIT_TIMEOUT == WaitForSingleObject(m_hReceive, 3000))
|
||
{
|
||
//
|
||
ASSERT(FALSE);
|
||
TerminateThread(m_hReceive, 0);
|
||
m_socket = NULL;
|
||
return -1;
|
||
}
|
||
m_socket = NULL;
|
||
return 0;
|
||
}
|
||
|
||
int CTcpClient::ReConnect()
|
||
{
|
||
if (m_bStart == TRUE)
|
||
{
|
||
StopConnect();
|
||
ConnectServer();
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
void CTcpClient::PostMessage2MainWnd(UINT uMsg, WPARAM wParam, CString strMsg)
|
||
{
|
||
NET_TCP_PACKET* pNetPacket = new NET_TCP_PACKET;
|
||
pNetPacket->pData = new char[strMsg.GetLength() + 1];
|
||
memcpy(pNetPacket->pData, strMsg.GetBuffer(), strMsg.GetLength());
|
||
strMsg.ReleaseBuffer();
|
||
pNetPacket->pData[strMsg.GetLength()] = '\0';
|
||
pNetPacket->lLen = strMsg.GetLength();
|
||
::PostMessage(this->m_hWnd, uMsg, wParam, (LPARAM)pNetPacket);
|
||
}
|
||
|
||
|
||
unsigned int __stdcall recvThread(LPVOID param)
|
||
{
|
||
CTcpClient* pThis = (CTcpClient*)param;
|
||
|
||
if (0 != pThis->m_socket)
|
||
{
|
||
LogOutToFile("网络服务已经启动,禁止多次连接.");
|
||
return 0;
|
||
}
|
||
|
||
pThis->m_lLastConnectTime = 0;
|
||
time(&pThis->m_lLastConnectTime);//连续重连失败60分钟则平台重启
|
||
while (pThis->m_bStart)
|
||
{
|
||
pThis->m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||
|
||
sockaddr_in remote;
|
||
remote.sin_family = AF_INET;
|
||
remote.sin_addr.s_addr = inet_addr(pThis->m_strServerIp.GetBuffer());
|
||
//remote.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||
remote.sin_port = htons(pThis->m_sPort);
|
||
|
||
time(&pThis->m_lLastNetTime);
|
||
if (0 == connect(pThis->m_socket, (sockaddr*)&remote, sizeof(remote)))
|
||
{
|
||
LogOutToFile("网络已连接.");
|
||
pThis->PostMessage2MainWnd(WM_CAM_NETMESSAGE, NET_CAM_CONNECT_OK, "扫码头已连接");
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
CString strMsg;
|
||
strMsg.Format("连接扫码头%s失败,20秒后开始重连[%d].", pThis->m_strServerIp.GetBuffer(), GetLastError());
|
||
LogOutToFile(strMsg);
|
||
pThis->PostMessage2MainWnd(WM_CAM_NETMESSAGE, NET_CAM_DISCONNECT, strMsg);
|
||
}
|
||
closesocket(pThis->m_socket);
|
||
pThis->m_socket = NULL;
|
||
for (int i = 0; i < 200 && TRUE == pThis->m_bStart; i++)
|
||
{
|
||
Sleep(100);
|
||
}
|
||
}
|
||
|
||
pThis->m_lLastConnectTime = 0;
|
||
|
||
//接受数据
|
||
pThis->HandleNdcCMsg();
|
||
|
||
pThis->m_socket = NULL;
|
||
|
||
pThis->PostMessage2MainWnd(WM_CAM_NETMESSAGE, NET_CAM_DISCONNECT, "扫码头已断开");
|
||
|
||
if (FALSE == pThis->m_bStart)
|
||
{
|
||
LogOutToFile("网络服务退出.");
|
||
return 0 ;
|
||
}
|
||
|
||
LogOutToFile("网络连接异常断开,立即开始重连.");
|
||
|
||
//断开后重新连接
|
||
pThis->ConnectServer();
|
||
return 0;
|
||
}
|
||
|
||
int CTcpClient::SendData(char* pData, int lLen)
|
||
{
|
||
|
||
if (NULL == m_socket)
|
||
{
|
||
LogOutToFile("数据发送失败,网络还未连接");
|
||
return -1;
|
||
}
|
||
|
||
int lSend = send(m_socket, pData, lLen, 0);
|
||
return lSend;
|
||
}
|
||
|
||
void CTcpClient::HandleNdcCMsg()
|
||
{
|
||
char acBuffer[10240] = "";
|
||
int nRecvLen = 0;
|
||
int nStateChange = 0;
|
||
|
||
while (m_bStart)
|
||
{
|
||
int lRec = recv(m_socket, acBuffer + nRecvLen, 10240 - nRecvLen, 0);
|
||
|
||
//TRACE("Recv len: %d\n", lRec);
|
||
if (lRec > 0)
|
||
{
|
||
nRecvLen += lRec;
|
||
}
|
||
else
|
||
{
|
||
LogOutToFile("Error: recv ret %d. error code %d", lRec, GetLastError());
|
||
closesocket(m_socket);
|
||
return ;
|
||
}
|
||
|
||
//消息体长度不足
|
||
if (nRecvLen < 21)continue;
|
||
int nMsgLen = 21;
|
||
|
||
|
||
while (true)
|
||
{
|
||
NET_TCP_PACKET* pNetPacket = new NET_TCP_PACKET;
|
||
pNetPacket->pData = new char[nMsgLen + 1];
|
||
memcpy(pNetPacket->pData, acBuffer, nMsgLen);
|
||
pNetPacket->pData[nMsgLen] = '\0';
|
||
pNetPacket->lLen = nMsgLen;
|
||
::PostMessage(this->m_hWnd, WM_CAM_NETMESSAGE, NET_CAM_DATA_MSG, (LPARAM)pNetPacket);
|
||
|
||
//从缓存中去掉已处理的消息
|
||
for (int i = nMsgLen; i < nRecvLen; i++)
|
||
{
|
||
acBuffer[i - nMsgLen] = acBuffer[i];
|
||
}
|
||
nRecvLen -= nMsgLen;
|
||
|
||
//不足一条消息长度
|
||
if (nRecvLen < 21)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|