socket library which can be used immediately (sock_stream) (unix_domain/inet_domain) a kind of short packet message exchanger.
Clone and make.
$ git clone https://github.com/ysan/immsocket
$ cd immsocket
$ make
Then shared libraries is created.
$ tree -P *.so
.
├── immsocket
│ └── libimmsocket.so
├── immsocketcommon
│ └── libimmsocketcommon.so
└── immsocketservice
└── libimmsocketservice.so
server code (echo server)
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<errno.h>#include<unistd.h>#include<signal.h>#include"ImmSocketService.h"usingnamespacestd;
usingnamespaceImmSocketService;
//// You inherit CPacketHandler and implement the following three methods.// - onHandleRequest// - onHandleReply// - onHandleNotify//// Attention:// If there are multiple thread pools, the above functions are called in parallel.// Therefore, reentrant code is mandatory.// Also, putting mutex makes sense of thread pool meaningless.//classCSvrMessageHandler : publicCPacketHandler
{
public:
explicitCSvrMessageHandler (intthreadPoolNum) : CPacketHandler (threadPoolNum) {}
virtual ~CSvrMessageHandler (void) {}
private:
voidonHandleRequest (CRequestMessage*pRequestMsg) override {
_UTL_LOG_I ("%s\n", __PRETTY_FUNCTION__);
switch ((int)pRequestMsg->getCommand()) {
case0x01: {
char*p= (char*)pRequestMsg->getData();
_UTL_LOG_I ("received -> [%s]\n", p);
CReplyMessage*pReplyMsg=newCReplyMessage (pRequestMsg);
pReplyMsg->sendOK ((uint8_t*)p, (int)strlen(p)); // echo replydeletepReplyMsg;
pReplyMsg=NULL;
} break;
default: {
CReplyMessage*pReplyMsg=newCReplyMessage (pRequestMsg);
pReplyMsg->sendNG();
deletepReplyMsg;
pReplyMsg=NULL;
} break;
}
}
voidonHandleReply (CReplyMessage*pReplyMsg) override {
_UTL_LOG_I ("%s\n", __PRETTY_FUNCTION__);
}
voidonHandleNotify (CNotifyMessage*pNotifyMsg) override {
_UTL_LOG_I ("%s\n", __PRETTY_FUNCTION__);
}
};
intmain (void)
{ //TODOsigset_tsigset;
sigemptyset (&sigset);
sigaddset (&sigset, SIGPIPE);
sigprocmask (SIG_BLOCK, &sigset, NULL);
// Specify a class that inherits from CPacketHandler in template.// Specify message handle thread pool num = 2// CSvrMessageHandler instance is created for each client connection.// thread pool is created for each connection.CClientHandler<CSvrMessageHandler>*pClientHandler=newCClientHandler<CSvrMessageHandler> (2);
CServerserver (65000, pClientHandler); // specified tcp port 65000server.start();
fgetc (stdin);
server.syncStop();
if (pClientHandler) {
deletepClientHandler;
pClientHandler=NULL;
}
exit (EXIT_SUCCESS);
}client code
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<errno.h>#include<unistd.h>#include<signal.h>#include"ImmSocketService.h"usingnamespacestd;
usingnamespaceImmSocketService;
CMessageId::CIdg_id;
//// You inherit CPacketHandler and implement the following three methods.// - onHandleRequest// - onHandleReply// - onHandleNotify//// Attention:// If there are multiple thread pools, the above functions are called in parallel.// Therefore, reentrant code is mandatory.// Also, putting mutex makes sense of thread pool meaningless.//classCClMessageHandler : publicCPacketHandler
{
public:
explicitCClMessageHandler (intthreadPoolNum) : CPacketHandler (threadPoolNum) {}
virtual ~CClMessageHandler (void) {}
private:
voidonHandleRequest (CRequestMessage*pRequestMsg) override {
_UTL_LOG_I ("%s\n", __PRETTY_FUNCTION__);
}
voidonHandleReply (CReplyMessage*pReplyMsg) override {
_UTL_LOG_I ("%s\n", __PRETTY_FUNCTION__);
CMessageId::CIdid=*pReplyMsg->getId();
if (id==g_id) { // id match_UTL_LOG_I ("%s (async)\n", pReplyMsg->isReplyResultOK() ? "REPLY_OK" : "REPLY_NG")
;
_UTL_LOG_I ("replyData [%s]\n", (char*)(pReplyMsg->getData()));
}
}
voidonHandleNotify (CNotifyMessage*pNotifyMsg) override {
_UTL_LOG_I ("%s\n", __PRETTY_FUNCTION__);
}
};
intmain (void)
{
//TODOsigset_tsigset;
sigemptyset (&sigset);
sigaddset (&sigset, SIGPIPE);
sigprocmask (SIG_BLOCK, &sigset, NULL);
// specify message handle thread pool num = 2CClMessageHandler*pHandler=newCClMessageHandler(2);
CClientclient ((constchar*)"127.0.0.1", 65000, pHandler); // specified tcp port 65000// connectboolr=client.connectToServer();
if (!r) {
exit (EXIT_FAILURE);
}
client.startReceiver();
uint8_tcommand=0x01;
char*p_data= (char*)"test";
// async request -> reply is handled by CClMessageHandler.CRequestMessage*pRequestMsg=newCRequestMessage (&client);
g_id=pRequestMsg->generateId(); // for async reply id matchpRequestMsg->sendAsync (&g_id, command, (uint8_t*)p_data, (int)strlen(p_data));
deletepRequestMsg;
pRequestMsg=NULL;
// sync requestCRequestMessage*pRequestMsgSync=newCRequestMessage (&client);
pRequestMsgSync->sendSync (command, (uint8_t*)p_data, (int)strlen(p_data)); // request and wait replyif (pRequestMsgSync->isReplyResultOK()) {
_UTL_LOG_I ("REPLY_OK (sync)\n");
} else {
_UTL_LOG_I ("REPLY_NG (sync)\n");
}
_UTL_LOG_I ("replyData [%s]\n", (char*)(pRequestMsgSync->getData()));
deletepRequestMsgSync;
pRequestMsgSync=NULL;
fgetc (stdin);
// disconnectclient.syncStopReceiver();
client.disconnectFromServer();
if (pHandler) {
deletepHandler;
pHandler=NULL;
}
exit (EXIT_SUCCESS);
}Generic Linux will be ok. (confirmed worked on Ubuntu, Fedora)


