Socket封装8

来源:互联网 发布:比较好的拼图软件 编辑:程序博客网 时间:2024/05/16 17:36

#ifndef REQUESTOPERATE_H
#define REQUESTOPERATE_H


// #include <standard library headers>

// #include <other library headers>

// #include "customer headers"
#include "../sock/ClientSocket.h"
#include "DataRequest.h"
#include "../Thread.hpp"


/**
 * description
 */
class RequestOperate
{
public:
    RequestOperate(DataRequest& request, const std::string& serverIP,
        int port, Thread* thread = NULL);
    virtual ~RequestOperate();

public:
    bool Execute();

private:
    void SendData();
    void RecvData();

private:
    static int s_RequestID;

    sock::ClientSocket m_ClientSocket;
    DataRequest& m_DataRequest;
    Thread* mThread;

};


#endif
/////////////////////////////////////////////////////

 

 

// #include <standard library headers>
#include <ctime>
#include <vector>
#include <algorithm>

// #include <other library headers>

// #include "customer headers"
#include "RequestOperate.h"
#include "../SocketHelper.h"


int RequestOperate::s_RequestID = 1;


/**
* description
*/
RequestOperate::RequestOperate(DataRequest& request, const std::string& serverIP,
                               int port, Thread* thread)
: m_ClientSocket(serverIP, port), m_DataRequest(request), mThread(thread)
{
    std::string strHostIP = SocketHelper::GetHostIPAddress();
    m_DataRequest.SetRequestIP(strHostIP);

    unsigned int requestID = s_RequestID++;
    m_DataRequest.SetRequestID(requestID);
}


/**
* description
*/
RequestOperate::~RequestOperate()
{
}


bool RequestOperate::Execute()
{
    try
    {       
        SendData();
       
        if (mThread != NULL && mThread->GetStop() ) { throw sock::SocketException(); }

        RecvData();

        return true;
    }
    catch (...)
    {
        return false;
    }
}


void RequestOperate::SendData()
{
    SLanCommandHeader header;
    std::vector<char> data = m_DataRequest.GetSendData(header);
    assert(data.size() == header.DataLen);

    //header.RequestID = s_RequestID++;
    //header.RequestIP = inet_addr(SocketHelper::GetHostIPAddress().c_str());
    header.SendTime = static_cast<DWORD>(std::time(NULL));

    //send header
    std::vector<char> head = SocketHelper::HostToNet(header);
    assert(head.size() == SLAN_HEADER_LENGTH);
    if (!m_ClientSocket.Send(&head[0], HEADER_LENGTH, SEND_TIMEOUT_SEC, SEND_TIMEOUT_USEC))
    {
        throw sock::SocketException();
    }

    if (data.size() < 0)
    {
        return;
    }

    //send data
    unsigned int sentLen = 0;
    while (sentLen < data.size())
    {
        if (mThread != NULL && mThread->GetStop() ) { throw sock::SocketException(); }

        unsigned int leave = static_cast<DWORD>(data.size()) - sentLen;
        unsigned int len = (leave > sock::MAXSEND) ? sock::MAXSEND : leave;

        if (!m_ClientSocket.Send(&data[sentLen], len, SEND_TIMEOUT_SEC, SEND_TIMEOUT_USEC))
        {
            throw sock::SocketException();
        }
        sentLen += len;
    }
}


void RequestOperate::RecvData()
{
    SLanCommandHeader header;
    std::vector<char> data;
    bool headerOk = false;

    while (true)
    {
        if (mThread != NULL && mThread->GetStop() ) { throw sock::SocketException(); }

        char buf[sock::MAXRECV];
        int nRecvSize = m_ClientSocket.Recv(buf, sock::MAXRECV, RECV_TIMEOUT_SEC, RECV_TIMEOUT_USEC);
        if (nRecvSize <= 0 || nRecvSize > sock::MAXRECV)
        {
            throw sock::SocketException();
        }
        assert(!(nRecvSize <= 0 || nRecvSize > sock::MAXRECV));
        std::copy(&buf[0], &buf[nRecvSize], back_inserter(data));

        if (!headerOk && data.size() >= SLAN_HEADER_LENGTH)
        {
            header = SocketHelper::NetToHostHeader(&data[0]);
            data.erase(data.begin(), data.begin() + SLAN_HEADER_LENGTH);
            data.reserve(header.DataLen);

            headerOk = true;
        }

        if (headerOk && data.size() >= header.DataLen)
        {
            break;
        }
    }

    if (!headerOk || data.size() != header.DataLen)
    {
        throw sock::SocketException();
    }

    if (!m_DataRequest.SetReceiveData(m_ClientSocket.GetSocketAddr(), header, data))
    {
        throw sock::SocketException();
    }
}

/////////////////////