添加 TcpClient.cpp
This commit is contained in:
parent
ccd0c1b26c
commit
fe48390ef7
269
TcpClient.cpp
Normal file
269
TcpClient.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user