Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tbaseserver.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef WIN32
Toshihiro Shimizu 890ddd
#include <sys types.h=""></sys>
Toshihiro Shimizu 890ddd
#include <sys socket.h=""></sys>
Toshihiro Shimizu 890ddd
#include <netinet in.h=""></netinet>
Toshihiro Shimizu 890ddd
#include <netdb.h></netdb.h>
Toshihiro Shimizu 890ddd
#include <stdio.h></stdio.h>
Toshihiro Shimizu 890ddd
#include <unistd.h></unistd.h>
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//#include "tcommon.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <string></string>
Toshihiro Shimizu 890ddd
#include <vector></vector>
Toshihiro Shimizu 890ddd
using namespace std;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TBaseServer::TBaseServer(int port)
Shinya Kitaoka 120a6e
    : m_port(port), m_socketId(-1), m_stopped(false) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TBaseServer::~TBaseServer() {
Shinya Kitaoka 120a6e
  if (m_socketId != -1) stop();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TBaseServer::start() {
Toshihiro Shimizu 890ddd
#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
#else
Shinya Kitaoka 120a6e
  int c;
Shinya Kitaoka 120a6e
  FILE *fp;
Shinya Kitaoka 120a6e
  register int ns;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if ((m_socketId = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
Toshihiro Shimizu 890ddd
#ifdef WIN32
Shinya Kitaoka 120a6e
    char szError[1024];
Shinya Kitaoka 120a6e
    wsprintf(szError, TEXT("Allocating socket failed. Error: %d"),
Shinya Kitaoka 120a6e
             WSAGetLastError());
Shinya Kitaoka 120a6e
    throw(szError);
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
    throw("Allocating socket failed.");
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  struct sockaddr_in myname;
Shinya Kitaoka 120a6e
  myname.sin_family      = AF_INET;
Shinya Kitaoka 120a6e
  myname.sin_port        = htons(m_port);
Shinya Kitaoka 120a6e
  myname.sin_addr.s_addr = INADDR_ANY;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (bind(m_socketId, (sockaddr *)&myname, sizeof myname) < 0) {
Shinya Kitaoka 120a6e
    throw("Unable to bind to connection");
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef TRACE
Shinya Kitaoka 120a6e
  cout << "Listening ..." << endl;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // length of the queue of pending connections
Shinya Kitaoka 120a6e
  int maxPendingConnections = 5;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (listen(m_socketId, maxPendingConnections) < 0) {
Shinya Kitaoka 120a6e
    throw("Unable to start listening");
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  while (true) {
Shinya Kitaoka 120a6e
    register int clientSocket;
Shinya Kitaoka 120a6e
    if ((clientSocket = accept(m_socketId, 0, 0)) < 0) {
Shinya Kitaoka 120a6e
      if (m_stopped)
Shinya Kitaoka 120a6e
        return;
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        throw("Error accepting from client");
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    printf("ho accettato\n");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    char msgFromClient[1024];
Shinya Kitaoka 120a6e
    memset(msgFromClient, 0, sizeof(msgFromClient));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef WIN32
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // Receive data from the client.
Shinya Kitaoka 120a6e
    int iReturn = recv(clientSocket, msgFromClient, sizeof(msgFromClient), 0);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // Verify that data was received. If yes, use it.
Shinya Kitaoka 120a6e
    if (iReturn == SOCKET_ERROR) {
Shinya Kitaoka 120a6e
      char szError[1024];
Shinya Kitaoka 120a6e
      wsprintf(szError,
Shinya Kitaoka 120a6e
               TEXT("No data is received, receive failed.") TEXT(" Error: %d"),
Shinya Kitaoka 120a6e
               WSAGetLastError());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      throw(szError);
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
    fp = fdopen(clientSocket, "r");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    printf("Partito!\n");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    int i = 0;
Shinya Kitaoka 120a6e
    while ((int)(c = fgetc(fp)) != EOF) {
Shinya Kitaoka 120a6e
      putchar(c);
Shinya Kitaoka 120a6e
      msgFromClient[i] = c;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    printf("msg finito\n");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    char *argv[128];
Shinya Kitaoka 120a6e
    int argc = extractArgs(msgFromClient, argv);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    string reply = exec(argc, argv);
Shinya Kitaoka 120a6e
    reply += "\n";
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    for (int i = 0; i < argc; ++i) delete[] argv[i];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // Send the reply string from the server to the client.
Shinya Kitaoka 120a6e
    if (send(clientSocket, reply.c_str(), reply.length() + 1, 0) < 0) {
Shinya Kitaoka 120a6e
      char szError[1024];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef WIN32
Shinya Kitaoka 120a6e
      wsprintf(szError, TEXT("Sending data to the client failed. Error: %d"),
Shinya Kitaoka 120a6e
               WSAGetLastError());
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      throw(szError);
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef WIN32
Shinya Kitaoka 120a6e
    close(clientSocket);
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TBaseServer::stop() {
Shinya Kitaoka 120a6e
  //  TThread::ScopedLock sl(m_mutex);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!m_stopped) {
Shinya Kitaoka 120a6e
    m_stopped = true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef WIN32
Shinya Kitaoka 120a6e
    if (closesocket(m_socketId) != 0) {
Shinya Kitaoka 120a6e
      char szError[1024];
Shinya Kitaoka 120a6e
      wsprintf(szError, TEXT(" Error: %d"), WSAGetLastError());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      throw(szError);
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
    close(m_socketId);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_socketId = -1;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TBaseServer::extractArgs(char *s, char *argv[]) {
Shinya Kitaoka 120a6e
  string ss(s);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  string::size_type pos1 = 0;
Shinya Kitaoka 120a6e
  string::size_type pos2 = ss.find(",");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  vector<string> args;</string>
Shinya Kitaoka 120a6e
  while (pos2 != string::npos) {
Shinya Kitaoka 120a6e
    string arg = ss.substr(pos1, pos2 - pos1);
Shinya Kitaoka 120a6e
    args.push_back(arg);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    pos1 = pos2 + 1;
Shinya Kitaoka 120a6e
    pos2 = ss.find(",", pos1);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  string arg = ss.substr(pos1, ss.length() - pos1);
Shinya Kitaoka 120a6e
  args.push_back(arg);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  vector<string>::iterator it = args.begin();</string>
Shinya Kitaoka 120a6e
  for (int i = 0; it != args.end(); ++it, ++i) {
Shinya Kitaoka 120a6e
    string arg = *it;
Shinya Kitaoka 120a6e
    argv[i]    = new char[arg.size() + 1];
Shinya Kitaoka 120a6e
    strcpy(argv[i], arg.c_str());
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return args.size();
Toshihiro Shimizu 890ddd
}