SokcetClient VC++6.0

// SokcetClient.cpp: implementation of the SokcetClient class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SokcetClient.h"
#include <iostream>
#include <Ws2tcpip.h>
#include "StringHelper.h"
#include "LoginResponse.h"
#include "HeartBeatRequest.h"
#include <string.h>
#include <stdio.h>
#include <Windows.h>
#include <map>
#include <cctype>
#include <algorithm>
#include "MyDefine.h"
#include "MD5.h"
#include <functional>
#include "StringHelper.h"
#include "JsonHelper.h"
#include <process.h>
#include <list>

using namespace std;

static bool IsCloseSocket = false;
static SOCKET m_nLocalSocket;
static HANDLE  reciveHandel;
static HANDLE  heartbeatHandel;
static string IP;
static int Port;
static string ClientNo;
static string ClientName;
static string Key;
static string ParkingNo;
static string ParkingName;
static IPaySDKAPI* paySDKAPI;
static int nRet = SOCKET_ERROR;

typedef list<string> ListString;
static ListString listJson;

SokcetClient::SokcetClient()
{
    m_nLocalSocket = -1;
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        std::cout << "Socket版本加载失败" << std::endl;
    }
}


SokcetClient::~SokcetClient()
{
    closeSocket();
}

void SokcetClient::closeSocket()
{
    IsCloseSocket = true;
    if (m_nLocalSocket != -1){
        closesocket(m_nLocalSocket);    //关闭socket连接
    }
    m_nLocalSocket = -1;
    CloseHandle(reciveHandel);
    CloseHandle(heartbeatHandel);
    WSACleanup();    //终止ws2_32.lib的使用
    
}




DWORD _stdcall SokcetClient::Myrecv(LPVOID lpParameter)
{
    
    int rs = -1;
    int resultRecv = -1;
    fd_set rfds;
    char m_message[1024];
    int size = sizeof(m_message);
    
    while(nRet == SOCKET_ERROR)
    {    
        sockaddr_in m_nServeraddr;
        memset(&m_nServeraddr, 0, sizeof(m_nServeraddr));
        m_nServeraddr.sin_family = AF_INET;
        m_nServeraddr.sin_port = htons(Port);
        m_nServeraddr.sin_addr.s_addr = inet_addr(IP.c_str());    
        nRet = connect(m_nLocalSocket, (sockaddr*)&m_nServeraddr, sizeof(m_nServeraddr));
        if (nRet == SOCKET_ERROR)
        {
            Sleep(3000);
        }
    }
    while (false == IsCloseSocket)
    {
        
        memset(m_message, '', size);
        FD_ZERO(&rfds);
        FD_SET(m_nLocalSocket, &rfds);
        struct timeval tv;
        tv.tv_sec = 1;
        tv.tv_usec = 0;
        rs = select(m_nLocalSocket, &rfds, NULL, NULL, &tv);
        if (rs > 0) 
        {
            resultRecv = recv(m_nLocalSocket, m_message, size, 0);
            
            if (resultRecv > 0)
            {
                //LoginResponse loginResponse;
                
                //输出消息
                paySDKAPI->receive(m_message);
                
                memset(m_message, '', size);
                
            }
            else
            {
                //这几种错误码,认为连接是正常的,继续接收
                if ((resultRecv < 0) && (errno == EAGAIN || errno == EINTR))
                {
                    continue;//继续接收数据
                }
                else
                {
                    m_nLocalSocket = -1;
                    CloseHandle(reciveHandel);
                    CloseHandle(heartbeatHandel);
    
                    m_nLocalSocket = socket(AF_INET, SOCK_STREAM , IPPROTO_TCP);
                    if (m_nLocalSocket != INVALID_SOCKET)
                    {
                        int nRet = SOCKET_ERROR;    
                    }
                    if (m_nLocalSocket != -1)
                    {
                        sockaddr_in m_nServeraddr;
                        memset(&m_nServeraddr, 0, sizeof(m_nServeraddr));
                        m_nServeraddr.sin_family = AF_INET;
                        m_nServeraddr.sin_port = htons(Port);
                        m_nServeraddr.sin_addr.s_addr = inet_addr(IP.c_str());    
                        nRet = connect(m_nLocalSocket, (sockaddr*)&m_nServeraddr, sizeof(m_nServeraddr));
                    }
                    if (nRet == SOCKET_ERROR)
                    {
                        Sleep(2000);
                    }
                }    
            }
        }
        else if (0 == rs )
        {
            if(listJson.size() > 0 && m_nLocalSocket != -1 && nRet != SOCKET_ERROR)
            {    
                string data = listJson.front();
                int size = strlen(data.c_str());
                listJson.pop_front();
                send(m_nLocalSocket, data.c_str(), size, 0);    
            }
        }
        
    }
    return 0;
}    

DWORD _stdcall SokcetClient::MyHeartBeat(LPVOID lpParameter)
{
    while (nRet == SOCKET_ERROR)
    {    
        Sleep(10000);
    }
    while (false == IsCloseSocket)
    {
        Sleep(10*1000);
        if (m_nLocalSocket != -1)
        {
            outputMessage(StringHelper::GBKToUTF8("发送心跳>>>>>>").c_str());
            HeartBeatRequest heartBeatRequest;
            heartBeatRequest.bizCode = "B1005";
            heartBeatRequest.clientName = StringHelper::GBKToUTF8("中心服务器");
            heartBeatRequest.clientNo = "1";
            heartBeatRequest.parkingNo = "1000000184";
            heartBeatRequest.reqNo = "1";
            heartBeatRequest.sign = "";

            map<std::string, std::string> myMap;
            myMap.insert(map<string,string>::value_type("bizCode",heartBeatRequest.bizCode));
            myMap.insert(map<string,string>::value_type("clientName",heartBeatRequest.clientName));
            myMap.insert(map<string,string>::value_type("clientNo",heartBeatRequest.clientNo));
            myMap.insert(map<string,string>::value_type("parkingNo",heartBeatRequest.parkingNo));
            myMap.insert(map<string,string>::value_type("reqNo",heartBeatRequest.reqNo));
            myMap.insert(map<string,string>::value_type("sign",heartBeatRequest.sign));

            map<string, string>::iterator iter;
            string str = "";
            string key = "";
            for (iter = myMap.begin(); iter != myMap.end(); ++iter) {
                if (!(*iter).second.empty() && (*iter).second.length() > 0) {
                    key = (*iter).first;
                    transform(key.begin(), key.end(), key.begin(), tolower);
                    str = str + key + "=" + (*iter).second + "&";
                }
            }

            str = str + "key=909276b944077b0b2123ac89f69d1016";

            MD5 md5;
            md5.update(str);
            heartBeatRequest.sign = md5.toString();
            transform(heartBeatRequest.sign.begin(), heartBeatRequest.sign.end(), heartBeatRequest.sign.begin(), toupper);
            if(myMap.count("sign") != 0){    
                myMap.erase("sign");
            }
            myMap.insert(map<string,string>::value_type("sign",heartBeatRequest.sign));

            string json2 = JsonHelper::map2jsonstr(myMap);
            json2= json2+"
";
            std::cout << json2 << endl;
            if (m_nLocalSocket != -1)
            {
                if(listJson.size() < 10)
                {
                    listJson.insert(listJson.begin(),json2);
                }
            }

        }
    }
    return 0;
}



bool SokcetClient::ConnectSocket(IPaySDKAPI* iPaySDKAPI,string ip, int prot,string clientNo,string clientName,string parkingNo, string key)
{
    paySDKAPI = iPaySDKAPI;
    IsCloseSocket = false;
    IP = ip;
    Port = prot;
    if (m_nLocalSocket == -1)
    {    

        m_nLocalSocket = socket(AF_INET, SOCK_STREAM , IPPROTO_TCP);
        if (m_nLocalSocket != INVALID_SOCKET)
        {
            outputMessage(StringHelper::GBKToUTF8("客服端socket创建成功").c_str());

        }
        
    }

    reciveHandel = CreateThread(NULL,0,Myrecv,NULL,0,NULL);
    heartbeatHandel = CreateThread(NULL,0,MyHeartBeat,NULL,0,NULL);
    return true;

}


void SokcetClient::Mysend(const char* buffer)
{
    if(listJson.size() < 10)
    {
        listJson.insert(listJson.begin(),buffer);
    }
}

void SokcetClient::outputMessage(const char * outstr)
{
    std::cout << outstr << std::endl;
}
原文地址:https://www.cnblogs.com/zclaude/p/11643940.html