qse/samples/si/tcpsvr01.cpp

168 lines
3.7 KiB
C++

#include <qse/si/TcpServer.hpp>
#include <qse/si/Mutex.hpp>
#include <qse/si/sio.h>
#include <qse/si/os.h>
#include <qse/cmn/mem.h>
#include <qse/cmn/str.h>
#include <qse/cmn/HeapMmgr.hpp>
#include <qse/si/App.hpp>
#include <locale.h>
#if defined(_WIN32)
# include <windows.h>
#endif
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#if defined(__linux)
#include <sys/prctl.h>
#endif
class ClientHandler
{
public:
int operator() (QSE::TcpServer* server, QSE::TcpServer::Connection* connection)
{
qse_char_t addrbuf[128];
qse_uint8_t bb[256];
qse_ssize_t n;
connection->address.toStrBuf(addrbuf, QSE_COUNTOF(addrbuf));
qse_printf (QSE_T("hello word..from %s -> wid %zu\n"), addrbuf, connection->getWid());
while (!server->isHaltRequested())
{
if ((n = connection->socket.receive(bb, QSE_COUNTOF(bb))) <= 0)
{
qse_printf (QSE_T("%zd bytes received from %s\n"), n, addrbuf);
break;
}
connection->socket.send (bb, n);
}
qse_printf (QSE_T("byte to %s -> wid %zu\n"), addrbuf, connection->getWid());
return 0;
}
};
#if defined(QSE_LANG_CPP11)
static QSE::TcpServerL<int(QSE::TcpServer::Connection*)>* g_server;
#else
static QSE::TcpServerF<ClientHandler>* g_server;
#endif
class MyApp: public QSE::App
{
public:
MyApp(QSE::Mmgr* mmgr): App(mmgr), server(mmgr) {}
void on_signal (int sig)
{
switch (sig)
{
case SIGINT:
case SIGTERM:
case SIGHUP:
// TODO: don't call stop() if this processs is a guardian
// though it's no harm to call stop().
QSE_APP_LOG3 (this, QSE_LOG_INFO, QSE_T("requesting to stop server...app %p server %p - pid %d\n"), this, &this->server, (int)getpid());
this->server.halt();
break;
}
}
int run ()
{
QSE::App::SignalSet signals;
signals.set (SIGINT);
signals.set (SIGHUP);
signals.set (SIGTERM);
signals.set (SIGUSR1);
signals.set (SIGUSR2);
if (this->guardProcess(signals) > 0)
{
int target_flags;
qse_log_target_data_t target_data;
target_data.file = QSE_T("tcpsvr01.log");
this->setName (QSE_T("tcpsvr01"));
this->setLogTarget (QSE_LOG_CONSOLE | QSE_LOG_FILE, target_data);
this->setLogPriorityMask (QSE_LOG_ALL_PRIORITIES);
this->setLogOption (QSE_LOG_KEEP_FILE_OPEN | QSE_LOG_INCLUDE_PID);
QSE_APP_LOG0 (this, QSE_LOG_DEBUG, QSE_T("Starting server\n"));
QSE_APP_LOG0 (this, QSE_LOG_DEBUG, QSE_T("hello"));
QSE_APP_LOG0 (this, QSE_LOG_INFO, QSE_T(" <tcpsvr01r> "));
QSE_APP_LOG0 (this, QSE_LOG_INFO, QSE_T("started\n"));
this->server.setThreadStackSize (256000);
return this->server.execute(QSE_T("[::]:9998,0.0.0.0:9998"));
}
return -1;
}
protected:
QSE::TcpServerF<ClientHandler> server;
};
static int test1()
{
QSE::HeapMmgr heap_mmgr (30000, QSE::Mmgr::getDFL());
MyApp app (&heap_mmgr);
MyApp app2 (&heap_mmgr);
MyApp app3 (&heap_mmgr);
MyApp app4 (&heap_mmgr);
app.acceptSignal (SIGINT);
app.acceptSignal (SIGTERM);
app4.acceptSignal (SIGINT);
app3.acceptSignal (SIGINT);
app2.acceptSignal (SIGINT);
int n = app.run();
app.discardSignal (SIGTERM);
app.discardSignal (SIGINT);
app4.neglectSignal (SIGINT);
app3.neglectSignal (SIGINT);
app2.neglectSignal (SIGINT);
QSE_APP_LOG1 (&app, QSE_LOG_INFO, QSE_T("END OF %d\n"), (int)getpid());
return n;
}
int main ()
{
#if defined(_WIN32)
char locale[100];
UINT codepage = GetConsoleOutputCP();
if (codepage == CP_UTF8)
{
/*SetConsoleOutputCP (CP_UTF8);*/
qse_setdflcmgrbyid (QSE_CMGR_UTF8);
}
else
{
qse_mbsxfmt (locale, QSE_COUNTOF(locale), ".%u", (unsigned int)codepage);
setlocale (LC_ALL, locale);
/*qse_setdflcmgrbyid (QSE_CMGR_SLMB);*/
}
#else
setlocale (LC_ALL, "");
/*qse_setdflcmgrbyid (QSE_CMGR_SLMB);*/
#endif
qse_open_stdsios ();
test1();
qse_close_stdsios ();
return 0;
}