Advertisement
Guest User

netserver.h / netserver.cpp

a guest
May 16th, 2016
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.01 KB | None | 0 0
  1. //
  2. //  NetServer.h
  3. //  OsciStudio
  4. //
  5. //  Created by Hansi on 07.06.15.
  6. //
  7. //
  8.  
  9. #ifndef __OsciStudio__NetServer__
  10. #define __OsciStudio__NetServer__
  11.  
  12. #include "ofMain.h"
  13. #include "Poco/Net/TCPServer.h"
  14. #include "Poco/Net/TCPServerParams.h"
  15. #include "Poco/Net/TCPServerConnectionFactory.h"
  16. #include "Poco/Net/TCPServerConnection.h"
  17. #include "Poco/Net/Socket.h"
  18.  
  19. #include <mutex>
  20.  
  21. class NetClient;
  22.  
  23. struct NetStatus{
  24.     NetStatus() : client(NULL),online(false){}
  25.     NetStatus( NetClient * client ) : client(client),online(true){}
  26.     NetClient * client;
  27.     bool online;
  28. };
  29.  
  30. class NetMessage{
  31. public:
  32.     NetMessage() : clientId(-1),str(""){};
  33.     NetMessage(int clientId, string str) : clientId(clientId),str(str){};
  34.    
  35.     int clientId;
  36.     string str;
  37. };
  38.  
  39.  
  40.  
  41. // based on http://stackoverflow.com/questions/14632341/poconet-server-client-tcp-connection-event-handler
  42. class NetServer : public Poco::Net::TCPServerConnectionFactory{
  43. public:
  44.     NetServer();
  45.     void start( int port );
  46.     void stop();
  47.    
  48.     NetMessage nextMessage();
  49.     void send( int clientId, string message );
  50.    
  51.     Poco::Net::ServerSocket * socket;
  52.     Poco::Net::TCPServer * server;
  53. private:
  54.     Poco::Net::TCPServerConnection* createConnection(const Poco::Net::StreamSocket& socket);
  55.     map<int,NetStatus> clientStatus;
  56.     int nextClientId = 0;
  57.     queue<NetMessage> messageQueue;
  58.     std::mutex queueMutex;
  59.     friend class NetClient;
  60. };
  61.  
  62. class NetClient : public Poco::Net::TCPServerConnection{
  63. public:
  64.     NetClient(NetServer & server, const Poco::Net::StreamSocket& s);
  65.     void run();
  66.     void send( string message );
  67.     int id;
  68.     bool die;
  69.    
  70.     NetServer &server;
  71. };
  72.  
  73.  
  74. #endif /* defined(__OsciStudio__NetServer__) */
  75.  
  76.  
  77.  
  78.  
  79. //
  80. //  NetServer.cpp
  81. //  OsciStudio
  82. //
  83. //  Created by Hansi on 07.06.15.
  84. //
  85. //
  86.  
  87. #include "NetServer.h"
  88. #include <algorithm>
  89.  
  90.  
  91.              
  92. NetServer::NetServer() : socket(NULL),server(NULL){
  93.    
  94. }
  95.  
  96.  
  97. void NetServer::start(int port){
  98.     socket = new Poco::Net::ServerSocket(port);
  99.    
  100.     //Configure some server params.
  101.     Poco::Net::TCPServerParams* pParams = new Poco::Net::TCPServerParams();
  102.     pParams->setMaxThreads(4);
  103.     pParams->setMaxQueued(4);
  104.     pParams->setThreadIdleTime(100);
  105.    
  106.     //Create your server
  107.     server = new Poco::Net::TCPServer(this, *socket, pParams);
  108.     server->start();
  109. }
  110.  
  111. void NetServer::stop(){
  112.     if( socket != NULL ){
  113.         socket->close();
  114.         socket = NULL;
  115.     }
  116.     if( server != NULL ){
  117.         server->stop();
  118.         server = NULL;
  119.     }
  120.    
  121.     // disconnect all clients that are still online
  122.     for( int i = 0; i < nextClientId; i++ ){
  123.         if( clientStatus[i].online ){
  124.             clientStatus[i].client->die = false;
  125.         }
  126.     }
  127. }
  128.  
  129. Poco::Net::TCPServerConnection* NetServer::createConnection(const Poco::Net::StreamSocket& socket)
  130. {
  131.     return new NetClient(*this, socket);
  132. }
  133.  
  134. NetMessage NetServer::nextMessage(){
  135.     if( messageQueue.size() == 0 ){
  136.         return NetMessage();
  137.     }
  138.     else{
  139.         NetMessage message = messageQueue.front();
  140.         lock_guard<mutex> lock(queueMutex);
  141.         messageQueue.pop();
  142.         return message;
  143.     }
  144. }
  145.  
  146. void NetServer::send( int clientId, string message ){
  147.     if( clientStatus[clientId].online ){
  148.         clientStatus[clientId].client->send(message);
  149.     }
  150. }
  151.  
  152.  
  153.  
  154.  
  155. NetClient::NetClient(NetServer &server, const Poco::Net::StreamSocket& s) : Poco::Net::TCPServerConnection(s), die(false), id(server.nextClientId++), server(server){
  156.     server.clientStatus[id] = NetStatus(this);
  157. }
  158.  
  159. void NetClient::run(){
  160.     cout << "New connection from: " << socket().peerAddress().host().toString() <<  endl << flush;
  161.     bool isOpen = true;
  162.     Poco::Timespan timeOut(10,0);
  163.     unsigned char incommingBuffer[1000];
  164.     stringstream message;
  165.    
  166.     while(isOpen && !die){
  167.         if (socket().poll(timeOut,Poco::Net::Socket::SELECT_READ) == false){
  168.             // just a poll timeout. no worries!
  169.             // cout << "TIMEOUT!" << endl << flush;
  170.         }
  171.         else{
  172.             int nBytes = -1;
  173.            
  174.             try {
  175.                 nBytes = socket().receiveBytes(incommingBuffer, sizeof(incommingBuffer));
  176.             }
  177.             catch (Poco::Exception& exc) {
  178.                 //Handle your network errors.
  179.                 cerr << "Network error: " << exc.displayText() << endl;
  180.                 isOpen = false;
  181.             }
  182.            
  183.             if (nBytes==0){
  184.                 cout << "Client closes connection!" << endl << flush;
  185.                 isOpen = false;
  186.             }
  187.             else{
  188.                 //cout << "Receiving nBytes: " << nBytes << endl << flush;
  189.                 const unsigned char* start = incommingBuffer;
  190.                 const unsigned char* end = incommingBuffer + nBytes;
  191.                 while( start != end ){
  192.                     const unsigned char* match = std::find(start, end, '\n');
  193.                     string str = string(start,match);
  194.                     message << str;
  195.                    
  196.                     if( match != end ){
  197.                         server.queueMutex.lock();
  198.                         server.messageQueue.push(NetMessage(id,message.str()));
  199.                         server.queueMutex.unlock();
  200.                         message.str("");
  201.                         message.clear();
  202.                        
  203.                         start = match + 1;
  204.                     }
  205.                     else{
  206.                         start = end;
  207.                     }
  208.                 }
  209.             }
  210.         }
  211.     }
  212.    
  213.     server.clientStatus[id].client = NULL;
  214.     server.clientStatus[id].online = false;
  215.     cout << "Connection finished!" << endl << flush;
  216. }
  217.  
  218. void NetClient::send( string message ){
  219.     socket().sendBytes(message.c_str(), message.length());
  220. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement