#include "TcpClient.h"
#include <vector>
using namespace jy;
using namespace std;
namespace jy {
TcpClient* TcpClient::instance_ = new TcpClient();
TcpClient::TcpClient() :threadPool_("TcpThreadPool"), sock(-1), port(0), address("")
{
threadPool_.start(kNumThreads);
}
TcpClient::~TcpClient() {}
bool TcpClient::setup(const string& address, const int port, string& errorBuf)
{
cout << "address:" << address << " port:" << port << endl;
cout << "sock: " << sock << endl;
if (sock == -1)
{
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1)
{
cout << "Could not create socket" << endl;
errorBuf = "Could not create socket";
}
}
if (inet_addr(address.c_str()) == -1)
{
struct hostent *he;
struct in_addr **addr_list;
if ((he = gethostbyname(address.c_str())) == NULL)
{
herror("get host by name");
cout << "Failed to resolve hostname\n";
errorBuf = "Failed to resolve hostname\n";
return false;
}
addr_list = (struct in_addr **) he->h_addr_list;
for (int i = 0; addr_list[i] != NULL; i++)
{
server.sin_addr = *addr_list[i];
break;
}
}
else
{
server.sin_addr.s_addr = inet_addr(address.c_str());
}
server.sin_family = AF_INET;
server.sin_port = htons(port);
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0)
{
perror("connect failed. Error");
errorBuf = "connect failed. Error";
return false;
}
return true;
}
bool TcpClient::sendData(const string& data, string& errorBuf)
{
if (sock != -1)
{
if (send(sock, data.c_str(), strlen(data.c_str()), 0) < 0)
{
cout << "Send failed : " << data << endl;
return false;
}
}
else
return false;
return true;
}
bool TcpClient::sendCommand(const std::string address, const int port, const std::string& cmd) {
string eb;
setup(address, port, eb);
sendData(cmd, eb);
}
string TcpClient::receive(int size)
{
char buffer[size];
memset(&buffer[0], 0, sizeof(buffer));
string reply;
int count = recv(sock, buffer, size, 0);
cout << "read data " << count << " byte" << endl;
if (count < 0)
{
cout << "receive failed!" << endl;
return nullptr;
}
buffer[size - 1] = '\0';
reply = buffer;
exit();
return reply;
}
string TcpClient::readData(int size)
{
char buffer[size];
memset(&buffer[0], 0, sizeof(buffer));
string reply;
int readCount = 0;
int leftSize = size;
do {
readCount = recv(sock, buffer + size - leftSize, size, 0);
leftSize -= readCount;
cout << "leftSize��" << leftSize << " readCount: " << readCount << endl;
} while (readCount > 0);
buffer[size - leftSize + 1] = '\0';
//int readSize1 = recv(sock, buffer, size, 0);
////usleep(10);
//int readSize2 = recv(sock, buffer+readSize1, size-readSize1, 0);
////usleep(10);
//int readSize3 = recv(sock, buffer + readSize1+ readSize2, size - readSize1- readSize2, 0);
//cout << "readSize1:" << readSize1 << endl;
//cout << "readSize2:" << readSize2 << endl;
//cout << "readSize3:" << readSize3 << endl;
//buffer[readSize1+readSize2+readSize3+1] = '\0';
reply = buffer;
//cout << reply << endl;
exit();
return reply;
}
void TcpClient::processResponse(const RequestTcpPtr& request, ResponseTcpPtr& response) {
vector<string> responseDataVec;
vector<string> requestDataVec = request->getRequestData();
cout << requestDataVec.front() << endl;
string errorBuf;
for (auto iter = requestDataVec.begin(); iter != requestDataVec.end(); iter++) {
bool ok = setup(request->getUrl(), request->getPort(), errorBuf);
if (ok)
{
response->setSucceed(true);
//cout << "sendrequest: " << *iter << endl;
if (!sendData(*iter, errorBuf)) {
response->setErrorBuffer(errorBuf);
};
//string tmpstr = receive();
//cout << "response str: " << tmpstr << endl;
//responseDataVec.push_back(tmpstr);
responseDataVec.push_back(readData());
}
else
{
response->setSucceed(false);
response->setErrorBuffer(errorBuf);
}
}
response->setResponseData(responseDataVec);
auto callback = request->getCallback();
callback(request, response);
}
void TcpClient::sendTcpRequest(const RequestTcpPtr& request) {
ResponseTcpPtr response = std::make_shared<TcpResponse>();
threadPool_.run(std::bind(&TcpClient::processResponse, this, request, response));
}
void TcpClient::sendTcpRequestImmediate(const RequestTcpPtr& request)
{
ResponseTcpPtr response = std::make_shared<TcpResponse>();
auto t = std::thread(std::bind(&TcpClient::processResponse, this, request, response));
t.join();
//t.detach();
}
void TcpClient::exit()
{
close(sock);
sock = -1;
port = 0;
address = "";
}
}