| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | #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>
 | 
					
						
							| 
									
										
										
										
											2018-09-05 14:52:51 +00:00
										 |  |  | #include <qse/cmn/str.h>
 | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | #include <qse/cmn/HeapMmgr.hpp>
 | 
					
						
							|  |  |  | #include <qse/sttp/Sttp.hpp>
 | 
					
						
							|  |  |  | #include <qse/si/App.hpp>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <locale.h>
 | 
					
						
							|  |  |  | #if defined(_WIN32)
 | 
					
						
							|  |  |  | #	include <windows.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <unistd.h>
 | 
					
						
							|  |  |  | #include <signal.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-18 16:47:20 +00:00
										 |  |  | class Proto: public QSE::Sttp | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  | 	Proto (QSE::Socket* sck): sck(sck) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int handle_command (const QSE::SttpCmd& cmd) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		qse_printf (QSE_T("command -> %js\n"), cmd.name.getData()); | 
					
						
							|  |  |  | 		int n = this->sendCmd(QSE_T("OK"), 1, cmd.name.getData()); | 
					
						
							|  |  |  | 		if (cmd.name == QSE_T("quit")) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			sck->shutdown (); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return n; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int write_bytes (const qse_uint8_t* data, qse_size_t len) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		int n = this->sck->sendx(data, len, QSE_NULL); | 
					
						
							|  |  |  | 		if (QSE_UNLIKELY(n <= -1)) this->setErrorFmt(E_ESYSERR, QSE_T("%js"), sck->getErrorMsg()); | 
					
						
							|  |  |  | 		return n; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | protected: | 
					
						
							|  |  |  | 	QSE::Socket* sck; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | #if defined(QSE_LANG_CPP11)
 | 
					
						
							| 
									
										
										
										
											2019-06-14 08:35:11 +00:00
										 |  |  | QSE::TcpServerL<int(QSE::TcpServer::Connection*)>* g_server; | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ClientHandler | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2019-06-14 08:35:11 +00:00
										 |  |  | 	int operator() (QSE::TcpServer* server, QSE::TcpServer::Connection* connection) | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		qse_char_t addrbuf[128]; | 
					
						
							|  |  |  | 		qse_uint8_t bb[256]; | 
					
						
							|  |  |  | 		qse_ssize_t n; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-14 08:35:11 +00:00
										 |  |  | 		connection->address.toStrBuf(addrbuf, QSE_COUNTOF(addrbuf)); | 
					
						
							|  |  |  | 		qse_printf (QSE_T("hello word..from %s[%zu]\n"), addrbuf, connection->getWid()); | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-18 16:47:20 +00:00
										 |  |  | 		Proto proto (&connection->socket); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-15 18:48:13 +00:00
										 |  |  | 		while (!server->isHaltRequested()) | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2020-08-18 16:47:20 +00:00
										 |  |  | 			if ((n = connection->socket.receive(bb, QSE_COUNTOF(bb))) <= 0) | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2020-08-18 16:47:20 +00:00
										 |  |  | 				if (n <= -1) | 
					
						
							|  |  |  | 					qse_printf (QSE_T("%s[%zu] -> got error\n"), addrbuf, connection->getWid()); | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-07-20 14:56:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-18 16:47:20 +00:00
										 |  |  | 			if (proto.feed(bb, n, QSE_NULL) <= -1) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				qse_printf (QSE_T("%s[%zu] -> protocol error - %js\n"), addrbuf, connection->getWid(), proto.getErrorMsg()); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-14 08:35:11 +00:00
										 |  |  | 		qse_printf (QSE_T("byte to %s -> wid %zu\n"), addrbuf, connection->getWid()); | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static QSE::TcpServerF<ClientHandler>* g_server; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int test1 (void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-10-31 10:40:25 +00:00
										 |  |  | 	QSE::HeapMmgr heap_mmgr (30000, QSE::Mmgr::getDFL()); | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined(QSE_LANG_CPP11)
 | 
					
						
							| 
									
										
										
										
											2019-06-14 08:35:11 +00:00
										 |  |  | 	QSE::TcpServerL<int(QSE::TcpServer::Connection*)> server ( | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// workload by lambda
 | 
					
						
							| 
									
										
										
										
											2019-06-14 08:35:11 +00:00
										 |  |  | 		([&server](QSE::TcpServer::Connection* connection) { | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | 			qse_char_t addrbuf[128]; | 
					
						
							|  |  |  | 			qse_uint8_t bb[256]; | 
					
						
							|  |  |  | 			qse_ssize_t n; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-14 08:35:11 +00:00
										 |  |  | 			connection->address.toStrBuf(addrbuf, QSE_COUNTOF(addrbuf)); | 
					
						
							|  |  |  | 			qse_printf (QSE_T("hello word..from %s --> wid %zu\n"), addrbuf, connection->getWid()); | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-18 16:47:20 +00:00
										 |  |  | 			Proto proto (&connection->socket); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			while (!server.isHaltRequested()) | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2020-08-18 16:47:20 +00:00
										 |  |  | 				if ((n = connection->socket.receive(bb, QSE_COUNTOF(bb))) <= 0) | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2020-08-18 16:47:20 +00:00
										 |  |  | 					if (n <= -1) | 
					
						
							|  |  |  | 						qse_printf (QSE_T("%s[%zu] -> got error\n"), addrbuf, connection->getWid()); | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2018-09-04 10:27:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-18 16:47:20 +00:00
										 |  |  | 				if (proto.feed(bb, n, QSE_NULL) <= -1) | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					qse_printf (QSE_T("%s[%zu] -> protocol error - %js\n"), addrbuf, connection->getWid(), proto.getErrorMsg()); | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-14 08:35:11 +00:00
										 |  |  | 			qse_printf (QSE_T("byte to %s -> wid %zu\n"), addrbuf, connection->getWid()); | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | 			return 0; | 
					
						
							|  |  |  | 		}), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		&heap_mmgr | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	QSE::TcpServerF<ClientHandler> server (&heap_mmgr); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	server.setThreadStackSize (256000); | 
					
						
							|  |  |  | 	g_server = &server; | 
					
						
							| 
									
										
										
										
											2019-11-12 07:55:32 +00:00
										 |  |  | 	//server.execute (QSE_T("0.0.0.0:9998"));
 | 
					
						
							|  |  |  | 	server.execute (QSE_T("[::]:9998,0.0.0.0:9998")); | 
					
						
							|  |  |  | 	//server.execute (QSE_T("[fe80::1c4:a90d:a0f0:d52%wlan0]:9998,0.0.0.0:9998"));
 | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | 	g_server = QSE_NULL; | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void handle_sigint (int sig) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-11-12 07:55:32 +00:00
										 |  |  | 	if (g_server) g_server->halt (); | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int main () | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #if defined(_WIN32)
 | 
					
						
							|  |  |  |  	char locale[100]; | 
					
						
							|  |  |  | 	UINT codepage = GetConsoleOutputCP(); | 
					
						
							|  |  |  | 	if (codepage == CP_UTF8) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-09-10 14:15:28 +00:00
										 |  |  | 		/*SetConsoleOutputCP (CP_UTF8);*/ | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | 		qse_setdflcmgrbyid (QSE_CMGR_UTF8); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-09-05 14:52:51 +00:00
										 |  |  | 		qse_mbsxfmt (locale, QSE_COUNTOF(locale), ".%u", (unsigned int)codepage); | 
					
						
							| 
									
										
										
										
											2018-07-20 14:52:34 +00:00
										 |  |  | 		setlocale (LC_ALL, locale); | 
					
						
							|  |  |  | 		/*qse_setdflcmgrbyid (QSE_CMGR_SLMB);*/ | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 	setlocale (LC_ALL, ""); | 
					
						
							|  |  |  | 	/*qse_setdflcmgrbyid (QSE_CMGR_SLMB);*/ | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	qse_open_stdsios (); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	QSE::App::setSignalHandler (SIGINT, handle_sigint); | 
					
						
							|  |  |  | 	test1(); | 
					
						
							|  |  |  | 	QSE::App::unsetSignalHandler (SIGINT); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	qse_close_stdsios (); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } |