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