添加 TcpClient.cpp
This commit is contained in:
		
							
								
								
									
										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;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user