Blob Blame Raw


#include "ttcpip.h"
#include "tconvert.h"

#ifdef _WIN32
#include <Winsock2.h>
#else
#include <errno.h> /* obligatory includes */
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <netdb.h>
#endif

#ifndef _WIN32
#define SOCKET_ERROR -1
#endif

//------------------------------------------------------------------------------

TTcpIpClient::TTcpIpClient()
{
#ifdef _WIN32
	WSADATA wsaData;
	WORD wVersionRequested = MAKEWORD(1, 1);
	int irc = WSAStartup(wVersionRequested, &wsaData);
#endif
}

//------------------------------------------------------------------------------

TTcpIpClient::~TTcpIpClient()
{
#ifdef _WIN32
	WSACleanup();
#endif
}

//------------------------------------------------------------------------------

int TTcpIpClient::connect(const QString &hostName, const QString &addrStr, int port, int &sock)
{
/*
  if (!addrStr.empty())
  {
    unsigned long ipAddr = inet_addr(addrStr.c_str());
  }
*/
#if QT_VERSION >= 0x050500
	struct hostent *he = gethostbyname(hostName.toUtf8());
#else
	struct hostent *he = gethostbyname(hostName.toAscii());
#endif
	if (!he) {
#ifdef _WIN32
		int err = WSAGetLastError();
#else
#endif
		return HOST_UNKNOWN;
	}

	int socket_id = socket(AF_INET, SOCK_STREAM, 0);

	struct sockaddr_in addr;
	memset((char *)&addr, 0, sizeof addr);
	addr.sin_family = he->h_addrtype;
	addr.sin_port = htons(port);
	memcpy((char *)&(addr.sin_addr), he->h_addr, he->h_length);

	int rcConnect = ::connect(socket_id, (struct sockaddr *)&(addr), sizeof addr);
	if (rcConnect == SOCKET_ERROR) {
		sock = -1;

#ifdef _WIN32
		int err = WSAGetLastError();
		switch (err) {
		case WSAECONNREFUSED:
			err = CONNECTION_REFUSED;
			break;
		case WSAETIMEDOUT:
			err = CONNECTION_TIMEDOUT;
			break;
		default:
			err = CONNECTION_FAILED;
			break;
		}

		closesocket(socket_id);
		return err;
#else
		close(socket_id);
		return CONNECTION_FAILED;
#endif
	}

	sock = socket_id;
	return OK;
}

/*
int TTcpIpClient::connect(const std::string &hostName, const std::string &addrStr, int port, int &sock)
{
  struct hostent *he = gethostbyname (hostName.c_str());
  if (!he)
  {
#ifdef _WIN32
    int err = WSAGetLastError();
#else
#endif
    return HOST_UNKNOWN;
  }

  int socket_id = socket (AF_INET, SOCK_STREAM,0);

  struct sockaddr_in addr;
  memset((char*)&addr, 0, sizeof addr);
  addr.sin_family = he->h_addrtype;
  addr.sin_port = htons(port);
  memcpy((char *)&(addr.sin_addr), he->h_addr, he->h_length);

  int rcConnect = ::connect (socket_id, (struct sockaddr *)&(addr), sizeof addr);
  if (rcConnect == SOCKET_ERROR)
  {
    sock = -1;
#ifdef _WIN32
    int err = WSAGetLastError();
    switch (err)
    {
     case WSAECONNREFUSED:
        return CONNECTION_REFUSED;
     case WSAETIMEDOUT:
        return CONNECTION_TIMEDOUT;
     default:
        return CONNECTION_FAILED;
    }
#else
    return CONNECTION_FAILED;
#endif
  }

  sock = socket_id;
  return OK;
}
*/

//------------------------------------------------------------------------------

int TTcpIpClient::disconnect(int sock)
{
#ifdef _WIN32
	closesocket(sock);
#else
	close(sock);
#endif

	return OK;
}

//------------------------------------------------------------------------------

int TTcpIpClient::send(int sock, const QString &data)
{
	std::string dataUtf8 = data.toStdString();

	QString header("#$#THS01.00");
	header += QString::number((int)dataUtf8.size());
	header += "#$#THE";

	std::string packet = header.toStdString() + dataUtf8;

	//  string packet = data;;

	int nLeft = packet.size();
	int idx = 0;
	while (nLeft > 0) {
#ifdef _WIN32
		int ret = ::send(sock, packet.c_str() + idx, nLeft, 0);
#else
		int ret = write(sock, packet.c_str() + idx, nLeft);
#endif

		if (ret == SOCKET_ERROR) {
// Error
#ifdef _WIN32
			int err = WSAGetLastError();
#else
#endif
			return SEND_FAILED;
		}
		nLeft -= ret;
		idx += ret;
	}

	shutdown(sock, 1);
	return OK;
}

//------------------------------------------------------------------------------

int readData(int sock, QString &data)
{
	int cnt = 0;
	char buff[1024];
	memset(buff, 0, sizeof(buff));

#ifdef _WIN32
	if ((cnt = recv(sock, buff, sizeof(buff), 0)) < 0) {
		int err = WSAGetLastError();
		// GESTIRE L'ERRORE SPECIFICO
		return -1;
	}
#else
	if ((cnt = read(sock, buff, sizeof(buff))) < 0) {
		printf("socket read failure %d\n", errno);
		perror("network server");
		close(sock);
		return -1;
	}
#endif

	if (cnt == 0)
		return 0;

	std::string aa(buff);
	int x1 = aa.find("#$#THS01.00");
	x1 += sizeof("#$#THS01.00") - 1;
	int x2 = aa.find("#$#THE");

	std::string ssize;
	for (int i = x1; i < x2; ++i)
		ssize.push_back(buff[i]);

	int size = toInt(ssize);

	data = QString(buff + x2 + sizeof("#$#THE") - 1);
	size -= data.size();

	while (size > 0) {
		memset(buff, 0, sizeof(buff));

#ifdef _WIN32
		if ((cnt = recv(sock, buff, sizeof(buff), 0)) < 0) {
			int err = WSAGetLastError();
			// GESTIRE L'ERRORE SPECIFICO
			return -1;
		}
#else
		if ((cnt = read(sock, buff, sizeof(buff))) < 0) {
			printf("socket read failure %d\n", errno);
			perror("network server");
			close(sock);
			return -1;
		}
#endif
		else if (cnt == 0) {
			break; // break out of loop
		} else if (cnt < (int)sizeof(buff)) {
			data += QString(buff);
			//break;  // break out of loop
		} else {
			data += QString(buff);
		}

		size -= cnt;
	}

	if (data.size() < size)
		return -1;

	return 0;
}

#if 0

int readData(int sock, string &data)
{
  int cnt = 0;
  char buff[1024];

  do
  {
    memset (buff,0,sizeof(buff));

#ifdef _WIN32
    if (( cnt = recv(sock, buff, sizeof(buff), 0)) < 0 )
    {
      int err = WSAGetLastError();
      // GESTIRE L'ERRORE SPECIFICO
      return -1;
    }
#else
    if (( cnt = read (sock, buff, sizeof(buff))) < 0 )
    {
      printf("socket read failure %d\n", errno);
      perror("network server");
      close(sock);
      return -1;
    }
#endif
    else
    if (cnt == 0)
      break;  // break out of loop

    data += string(buff);
  }
  while (cnt != 0);  // do loop condition

  return 0;
}

#endif

//#define PRIMA

#ifdef PRIMA

int readData(int sock, string &data)
{
	int cnt = 0;
	char buff[1024];

	do {
		memset(buff, 0, sizeof(buff));

#ifdef _WIN32
		if ((cnt = recv(sock, buff, sizeof(buff), 0)) < 0) {
			int err = WSAGetLastError();
			// GESTIRE L'ERRORE SPECIFICO
			return -1;
		}
#else
		if ((cnt = read(sock, buff, sizeof(buff))) < 0) {
			printf("socket read failure %d\n", errno);
			perror("network server");
			close(sock);
			return -1;
		}
#endif
		else if (cnt == 0) {
			break; // break out of loop
		} else if (cnt < sizeof(buff)) {
			data += string(buff);
			//break;  // break out of loop
		} else {
			data += string(buff);
		}
	} while (cnt != 0); // do loop condition

	return 0;
}

#endif

//------------------------------------------------------------------------------

int TTcpIpClient::send(int sock, const QString &data, QString &reply)
{
	if (data.size() > 0) {
		int ret = send(sock, data);
		if (ret == 0)
			ret = readData(sock, reply);
		return ret;
	}

	return OK;
}

/*
int TTcpIpClient::send(int sock, const std::string &data, string &reply)
{
  int ret = send(sock, data);
  if (ret == 0)
    ret = readData(sock, reply);
  return ret;
}
*/