|
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
|