#ifndef RESPONSEOPERATE_H
#define RESPONSEOPERATE_H
// #include <standard library headers>
// #include <other library headers>
#include <tchar.h>
// #include "customer headers"
#include "ServerSocket.h"
#include "DataResponse.h"
#include "Thread.hpp"
/**
* description
*/
class ResponseOperate
{
public:
ResponseOperate(const sock::ServerSocket& sock, Thread* thread = NULL);
virtual ~ResponseOperate();
public:
bool Execute();
protected:
virtual DataResponse* CreateResponse(const CommandHeader& header) = 0;
private:
void RecvData();
void SendData();
protected:
const sock::ServerSocket& m_ServerSocket;
DataResponse* m_DataResponse;
Thread* mThread;
private:
};
#endif
// #include <standard library headers>
#include <ctime>
#include <vector>
#include <algorithm>
// #include <other library headers>
// #include "customer headers"
#include "ResponseOperate.h"
#include "SocketHelper.h"
/**
* description
*/
ResponseOperate::ResponseOperate(const sock::ServerSocket& sock, Thread* thread)
: m_ServerSocket(sock), mThread(thread)
{
m_DataResponse = NULL;
}
/**
* description
*/
ResponseOperate::~ResponseOperate()
{
delete m_DataResponse;
m_DataResponse = NULL;
}
bool ResponseOperate::Execute()
{
try
{
RecvData();
if (mThread != NULL && mThread->GetStop() ) { throw sock::SocketException(); }
SendData();
return true;
}
catch (...)
{
return false;
}
}
void ResponseOperate::RecvData()
{
CommandHeader 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_ServerSocket.Recv(buf, sock::MAXRECV, RECV_TIMEOUT_SEC, RECV_TIMEOUT_USEC);
if (nRecvSize <= 0 || nRecvSize > sock::MAXRECV)
{
throw sock::SocketException();
}
//std::copy(&buf[0], &buf[nRecvSize], back_inserter(data));
assert(!(nRecvSize <= 0 || nRecvSize > sock::MAXRECV));
data.insert(data.end(), &buf[0], &buf[nRecvSize]);
if (!headerOk && data.size() >= SLAN_HEADER_LENGTH)
{
header = SocketHelper::NetToHostHeader(&data[0]);
data.erase(data.begin(), data.begin() + HEADER_LENGTH);
data.reserve(header.DataLen);
headerOk = true;
}
if (headerOk && data.size() >= header.DataLen)
{
break;
}
}
if (!headerOk || data.size() != header.DataLen)
{
throw sock::SocketException();
}
assert (m_DataResponse == NULL);
m_DataResponse = CreateResponse(header);
if (m_DataResponse == NULL)
{
throw sock::SocketException();
}
if (!m_DataResponse->SetReceiveData(m_ServerSocket.GetSocketAddr(), header, data))
{
throw sock::SocketException();
}
}
void ResponseOperate::SendData()
{
SLanCommandHeader header;
const std::vector<char>& data = m_DataResponse->GetSendData(header);
assert(data.size() == header.DataLen);
header.SendTime = static_cast<DWORD>(std::time(NULL));
//send header
std::vector<char> head = SocketHelper::HostToNet(header);
assert(head.size() == HEADER_LENGTH);
if (!m_ServerSocket.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 = (DWORD)data.size() - sentLen;
unsigned int len = (leave > sock::MAXSEND) ? sock::MAXSEND : leave;
if (!m_ServerSocket.Send(&data[sentLen], len, SEND_TIMEOUT_SEC, SEND_TIMEOUT_USEC))
{
throw sock::SocketException();
}
sentLen += len;
}
}