添加 TcpClient.cpp

This commit is contained in:
TY 2025-06-25 13:11:32 +08:00
parent ccd0c1b26c
commit fe48390ef7

269
TcpClient.cpp Normal file
View File

@ -0,0 +1,269 @@
#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;
}
}
}
}