Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "ttcpip.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
#include <winsock2.h></winsock2.h>
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#include <errno.h> /* obligatory includes */</errno.h>
Toshihiro Shimizu 890ddd
#include <signal.h></signal.h>
Toshihiro Shimizu 890ddd
#include <stdio.h></stdio.h>
Toshihiro Shimizu 890ddd
#include <unistd.h></unistd.h>
Toshihiro Shimizu 890ddd
#include <sys types.h=""></sys>
Toshihiro Shimizu 890ddd
#include <sys socket.h=""></sys>
Toshihiro Shimizu 890ddd
#include <sys wait.h=""></sys>
Toshihiro Shimizu 890ddd
#include <netinet in.h=""></netinet>
Toshihiro Shimizu 890ddd
#include <netdb.h></netdb.h>
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tthreadmessage.h"
Toshihiro Shimizu 890ddd
#include "tthread.h"
Shinya Kitaoka 9f5a1b
#ifndef _WIN32
Toshihiro Shimizu 890ddd
#define SOCKET_ERROR -1
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <string></string>
Toshihiro Shimizu 890ddd
using namespace std;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define MAXHOSTNAME 1024
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int establish(unsigned short portnum, int &sock);
Toshihiro Shimizu 890ddd
int get_connection(int s);
Toshihiro Shimizu 890ddd
void fireman(int);
Toshihiro Shimizu 890ddd
void do_something(int);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool Sthutdown = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//#define TRACE
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class TTcpIpServerImp
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	TTcpIpServerImp(int port) : m_port(port), m_s(-1), m_server(0) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int readData(int sock, QString &data);
Toshihiro Shimizu 890ddd
	void onReceive(int sock, const QString &data);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int m_s; // socket id
Toshihiro Shimizu 890ddd
	int m_port;
Toshihiro Shimizu 890ddd
	TTcpIpServer *m_server; // back pointer
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TThread::Mutex m_mutex;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TTcpIpServerImp::readData(int sock, QString &data)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int cnt = 0;
Toshihiro Shimizu 890ddd
	char buff[1025];
Toshihiro Shimizu 890ddd
	memset(buff, 0, sizeof(buff));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
	if ((cnt = recv(sock, buff, sizeof(buff) - 1, 0)) < 0) {
Toshihiro Shimizu 890ddd
		int err = WSAGetLastError();
Toshihiro Shimizu 890ddd
		// GESTIRE L'ERRORE SPECIFICO
Toshihiro Shimizu 890ddd
		return -1;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
	if ((cnt = read(sock, buff, sizeof(buff) - 1)) < 0) {
Toshihiro Shimizu 890ddd
		printf("socket read failure %d\n", errno);
Toshihiro Shimizu 890ddd
		perror("network server");
Toshihiro Shimizu 890ddd
		close(sock);
Toshihiro Shimizu 890ddd
		return -1;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (cnt == 0)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef TRACE
Toshihiro Shimizu 890ddd
	cout << buff << endl
Toshihiro Shimizu 890ddd
		 << endl;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	string aa(buff);
Toshihiro Shimizu 890ddd
	int x1 = aa.find("#$#THS01.00");
Toshihiro Shimizu 890ddd
	x1 += sizeof("#$#THS01.00") - 1;
Toshihiro Shimizu 890ddd
	int x2 = aa.find("#$#THE");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	string ssize;
Toshihiro Shimizu 890ddd
	for (int i = x1; i < x2; ++i)
Toshihiro Shimizu 890ddd
		ssize.push_back(buff[i]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int dataSize = toInt(ssize);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	unsigned long size = dataSize;
Toshihiro Shimizu 890ddd
	data = QString(buff + x2 + sizeof("#$#THE") - 1);
Toshihiro Shimizu 890ddd
	size -= data.size();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	while (size > 0) {
Toshihiro Shimizu 890ddd
		memset(buff, 0, sizeof(buff));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
		if ((cnt = recv(sock, buff, sizeof(buff) - 1, 0)) < 0) {
Toshihiro Shimizu 890ddd
			int err = WSAGetLastError();
Toshihiro Shimizu 890ddd
			// GESTIRE L'ERRORE SPECIFICO
Toshihiro Shimizu 890ddd
			return -1;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
		if ((cnt = read(sock, buff, sizeof(buff) - 1)) < 0) {
Toshihiro Shimizu 890ddd
			printf("socket read failure %d\n", errno);
Toshihiro Shimizu 890ddd
			perror("network server");
Toshihiro Shimizu 890ddd
			close(sock);
Toshihiro Shimizu 890ddd
			return -1;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
		else if (cnt == 0) {
Toshihiro Shimizu 890ddd
			break; // break out of loop
Toshihiro Shimizu 890ddd
		} else if (cnt < (int)sizeof(buff)) {
Toshihiro Shimizu 890ddd
			buff[cnt] = '\0';
Toshihiro Shimizu 890ddd
			data += QString(buff);
Toshihiro Shimizu 890ddd
			//break;  // break out of loop
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			data += QString(buff);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef TRACE
Toshihiro Shimizu 890ddd
		cout << buff << endl
Toshihiro Shimizu 890ddd
			 << endl;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		size -= cnt;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef TRACE
Toshihiro Shimizu 890ddd
	cout << "read " << toString((int)data.length()) << " on " << toString((int)dataSize) << endl
Toshihiro Shimizu 890ddd
		 << endl;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (data.size() < dataSize)
Toshihiro Shimizu 890ddd
		return -1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef TRACE
Toshihiro Shimizu 890ddd
	cout << data.toStdString() << endl;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if 0
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TTcpIpServerImp::readData(int sock, string &data)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
  int cnt = 0;
Toshihiro Shimizu 890ddd
  char buff[1024];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  do
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
    memset (buff,0,sizeof(buff));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
    if (( cnt = recv(sock, buff, sizeof(buff), 0)) < 0 )
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
      int err = WSAGetLastError();
Toshihiro Shimizu 890ddd
      // GESTIRE L'ERRORE SPECIFICO
Toshihiro Shimizu 890ddd
      return -1;
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
    if (( cnt = read (sock, buff, sizeof(buff))) < 0 )
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
      printf("socket read failure %d\n", errno);
Toshihiro Shimizu 890ddd
      perror("network server");
Toshihiro Shimizu 890ddd
      close(sock);
Toshihiro Shimizu 890ddd
      return -1;
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
    else
Toshihiro Shimizu 890ddd
    if (cnt == 0)
Toshihiro Shimizu 890ddd
      break;  // break out of loop
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
    data += string(buff);
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
  while (cnt != 0);  // do loop condition
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//#define PRIMA
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef PRIMA
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TTcpIpServerImp::readData(int sock, string &data)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int cnt = 0;
Toshihiro Shimizu 890ddd
	char buff[1024];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	do {
Toshihiro Shimizu 890ddd
		memset(buff, 0, sizeof(buff));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
		if ((cnt = recv(sock, buff, sizeof(buff), 0)) < 0) {
Toshihiro Shimizu 890ddd
			int err = WSAGetLastError();
Toshihiro Shimizu 890ddd
			// GESTIRE L'ERRORE SPECIFICO
Toshihiro Shimizu 890ddd
			return -1;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
		if ((cnt = read(sock, buff, sizeof(buff))) < 0) {
Toshihiro Shimizu 890ddd
			printf("socket read failure %d\n", errno);
Toshihiro Shimizu 890ddd
			perror("network server");
Toshihiro Shimizu 890ddd
			close(sock);
Toshihiro Shimizu 890ddd
			return -1;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
		else if (cnt == 0) {
Toshihiro Shimizu 890ddd
			break; // break out of loop
Toshihiro Shimizu 890ddd
		} else if (cnt < sizeof(buff)) {
Toshihiro Shimizu 890ddd
			data += string(buff);
Toshihiro Shimizu 890ddd
			//break;  // break out of loop
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			data += string(buff);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} while (cnt != 0); // do loop condition
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TTcpIpServerImp::onReceive(int sock, const QString &data)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QMutexLocker sl(&m_mutex);
Toshihiro Shimizu 890ddd
	m_server->onReceive(sock, data);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TTcpIpServer::TTcpIpServer(int port)
Toshihiro Shimizu 890ddd
	: m_imp(new TTcpIpServerImp(port))
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_imp->m_server = this;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
	// Windows Socket startup
Toshihiro Shimizu 890ddd
	WSADATA wsaData;
Toshihiro Shimizu 890ddd
	WORD wVersionRequested = MAKEWORD(1, 1);
Toshihiro Shimizu 890ddd
	int irc = WSAStartup(wVersionRequested, &wsaData);
Toshihiro Shimizu 890ddd
	if (irc != 0)
Toshihiro Shimizu 890ddd
		throw("Windows Socket Startup failed");
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TTcpIpServer::~TTcpIpServer()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_imp->m_s != -1)
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
		closesocket(m_imp->m_s);
Toshihiro Shimizu 890ddd
	WSACleanup();
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
		std::cout << "closing socket" << std::endl;
Toshihiro Shimizu 890ddd
	close(m_imp->m_s);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TTcpIpServer::getPort() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_imp->m_port;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static void shutdown_cb(int)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	Sthutdown = true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class DataReader : public TThread::Runnable
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 262a92
	DataReader(int clientSocket, std::shared_ptr<ttcpipserverimp> serverImp)</ttcpipserverimp>
Shinya Kitaoka 262a92
		: m_clientSocket(clientSocket), m_serverImp(std::move(serverImp)) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void run();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int m_clientSocket;
Shinya Kitaoka 262a92
	std::shared_ptr<ttcpipserverimp> m_serverImp;</ttcpipserverimp>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void DataReader::run()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QString data;
Toshihiro Shimizu 890ddd
	int ret = m_serverImp->readData(m_clientSocket, data);
Toshihiro Shimizu 890ddd
	if (ret != -1) {
Toshihiro Shimizu 890ddd
		if (data == QString("shutdown"))
Toshihiro Shimizu 890ddd
			Sthutdown = true;
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			m_serverImp->onReceive(m_clientSocket, data);
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
		closesocket(m_clientSocket);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
		close(m_clientSocket);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class DataReceiver : public TThread::Runnable
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 262a92
	DataReceiver(int clientSocket, const QString &data, std::shared_ptr<ttcpipserverimp> serverImp)</ttcpipserverimp>
Shinya Kitaoka 262a92
		: m_clientSocket(clientSocket), m_data(data), m_serverImp(std::move(serverImp)) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void run();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int m_clientSocket;
Toshihiro Shimizu 890ddd
	QString m_data;
Shinya Kitaoka 262a92
	std::shared_ptr<ttcpipserverimp> m_serverImp;</ttcpipserverimp>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void DataReceiver::run()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_serverImp->onReceive(m_clientSocket, m_data);
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
	closesocket(m_clientSocket);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
	close(m_clientSocket);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TTcpIpServer::run()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	try {
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int err = establish(m_imp->m_port, m_imp->m_s);
Toshihiro Shimizu 890ddd
		if (!err && m_imp->m_s != -1) {
Toshihiro Shimizu 890ddd
			int t; // client socket
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			while (!Sthutdown) /* loop for connections */
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				if ((t = get_connection(m_imp->m_s)) < 0) /* get a connection */
Toshihiro Shimizu 890ddd
				{
Toshihiro Shimizu 890ddd
					m_exitCode = WSAGetLastError();
Toshihiro Shimizu 890ddd
					// GESTIRE LA CONDIZIONE DI ERRORE
Toshihiro Shimizu 890ddd
					return;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				QString data;
Toshihiro Shimizu 890ddd
				int ret = m_imp->readData(t, data);
Toshihiro Shimizu 890ddd
				if (ret != -1 && data != "") {
Toshihiro Shimizu 890ddd
					if (data == QString("shutdown")) {
Toshihiro Shimizu 890ddd
						//DebugBreak();
Toshihiro Shimizu 890ddd
						Sthutdown = true;
Toshihiro Shimizu 890ddd
					} else {
Toshihiro Shimizu 890ddd
						// creo un nuovo thread per la gestione dei dati ricevuti
Toshihiro Shimizu 890ddd
						TThread::Executor executor;
Shinya Kitaoka 262a92
						executor.addTask(new DataReceiver(t, data, m_imp));
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				} else {
Toshihiro Shimizu 890ddd
					::shutdown(t, 1);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			m_exitCode = err;
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#else // !_WIN32
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int err = establish(m_imp->m_port, m_imp->m_s);
Toshihiro Shimizu 890ddd
		if (!err && m_imp->m_s != -1) {
Toshihiro Shimizu 890ddd
//      signal(SIGCHLD, fireman);           /* this eliminates zombies */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef MACOSX
Toshihiro Shimizu 890ddd
			struct sigaction sact;
Toshihiro Shimizu 890ddd
			sact.sa_handler = shutdown_cb;
Toshihiro Shimizu 890ddd
			sigaction(SIGUSR1, &sact, 0);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
			sigset(SIGUSR1, shutdown_cb);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			int t;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			while (!Sthutdown) /* loop for connections */
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				if ((t = get_connection(m_imp->m_s)) < 0) /* get a connection */
Toshihiro Shimizu 890ddd
				{
Toshihiro Shimizu 890ddd
					if (errno == EINTR) /* EINTR might happen on accept(), */
Toshihiro Shimizu 890ddd
						continue;		/* try again */
Toshihiro Shimizu 890ddd
					perror("accept");   /* bad */
Toshihiro Shimizu 890ddd
					m_exitCode = errno;
Toshihiro Shimizu 890ddd
					return;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				TThread::Executor executor;
Shinya Kitaoka 262a92
				executor.addTask(new DataReader(t, m_imp));
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			m_exitCode = err;
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#endif // _WIN32
Toshihiro Shimizu 890ddd
	} catch (...) {
Toshihiro Shimizu 890ddd
		m_exitCode = 2000;
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_exitCode = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TTcpIpServer::getExitCode() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_exitCode;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TTcpIpServer::sendReply(int socket, const QString &reply)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	string replyUtf8 = reply.toStdString();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QString header("#$#THS01.00");
Toshihiro Shimizu 890ddd
	header += QString::number((int)replyUtf8.size());
Toshihiro Shimizu 890ddd
	header += QString("#$#THE");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	string packet = header.toStdString() + replyUtf8;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//  string packet = reply;;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int nLeft = packet.size();
Toshihiro Shimizu 890ddd
	int idx = 0;
Toshihiro Shimizu 890ddd
	while (nLeft > 0) {
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
		int ret = send(socket, packet.c_str() + idx, nLeft, 0);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
		int ret = write(socket, packet.c_str() + idx, nLeft);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (ret == SOCKET_ERROR) {
Toshihiro Shimizu 890ddd
			// Error
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		nLeft -= ret;
Toshihiro Shimizu 890ddd
		idx += ret;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	::shutdown(socket, 1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int establish(unsigned short portnum, int &sock)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	char myname[MAXHOSTNAME + 1];
Toshihiro Shimizu 890ddd
	struct sockaddr_in sa;
Toshihiro Shimizu 890ddd
	struct hostent *hp;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	memset(&sa, 0, sizeof(struct sockaddr_in)); /* clear our address */
Toshihiro Shimizu 890ddd
	gethostname(myname, MAXHOSTNAME);			/* who are we? */
Toshihiro Shimizu 890ddd
	hp = gethostbyname(myname);					/* get our address info */
Toshihiro Shimizu 890ddd
	if (hp == NULL)								/* we don't exist !? */
Toshihiro Shimizu 890ddd
		return (-1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	sa.sin_family = hp->h_addrtype;					  /* this is our host address */
Toshihiro Shimizu 890ddd
	sa.sin_port = htons(portnum);					  /* this is our port number */
Toshihiro Shimizu 890ddd
	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) /* create socket */
Toshihiro Shimizu 890ddd
	{
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
		int err = WSAGetLastError();
Toshihiro Shimizu 890ddd
		return err;
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
		return errno;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (::bind(sock, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) {
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
		int err = WSAGetLastError();
Toshihiro Shimizu 890ddd
		closesocket(sock);
Toshihiro Shimizu 890ddd
		return err;
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
		return errno;
Toshihiro Shimizu 890ddd
		close(sock);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return listen(sock, 3); /* max # of queued connects */
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/* wait for a connection to occur on a socket created with establish() */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int get_connection(int s)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int t; /* socket of connection */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if ((t = accept(s, NULL, NULL)) < 0) /* accept connection if there is one */
Toshihiro Shimizu 890ddd
		return (-1);
Toshihiro Shimizu 890ddd
	return (t);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifndef _WIN32
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/* as children die we should get catch their returns or else we get
Toshihiro Shimizu 890ddd
 * zombies, A Bad Thing.  fireman() catches falling children.
Toshihiro Shimizu 890ddd
 */
Toshihiro Shimizu 890ddd
void fireman(int)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	while (waitpid(-1, NULL, WNOHANG) > 0)
Toshihiro Shimizu 890ddd
		;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
#endif