daily pastebin goal
37%
SHARE
TWEET

Untitled

a guest Jun 19th, 2017 44 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <cstdio>
  2. #include <string>
  3. #include <iostream>
  4. #include <sstream>
  5. #include <list>
  6. #include <zmq.hpp>
  7.  
  8. /* TCPListener: declaration */
  9. class TCPListener
  10. {
  11. public:
  12.     TCPListener(int listen_port) : context(NULL), listenSocket(NULL), port(listen_port) {}
  13.     virtual ~TCPListener();
  14.  
  15.     friend class MultiServer;
  16.  
  17. protected:
  18.     // Methods called by MultiServer
  19.     virtual std::string receive();
  20.     virtual void setup(zmq::context_t *ctx);
  21.     virtual void * getSocket() { return (void*)listenSocket; }
  22.  
  23.     zmq::context_t *context;
  24.     zmq::socket_t *listenSocket;
  25.     int port;
  26. };
  27.  
  28. /* TCPListener: implementation */
  29. TCPListener::~TCPListener()
  30. {
  31.     try
  32.     {
  33.         delete listenSocket;
  34.         delete context;
  35.     }
  36.     catch (zmq::error_t &err)
  37.     {
  38.         printf("[!] TCPListener: %s\n", err.what());
  39.     }
  40. }
  41.  
  42. void TCPListener::setup(zmq::context_t *ctx)
  43. {
  44.     context = ctx;
  45.  
  46.     try
  47.     {
  48.         // Create and bind the listening socket
  49.         listenSocket = new zmq::socket_t(*context, ZMQ_REP);
  50.  
  51.         std::stringstream bind_address;
  52.         bind_address << "tcp://*:";
  53.         bind_address << port;
  54.  
  55.         printf("[TCP] Binding to %s\n", bind_address.str().c_str());
  56.         listenSocket->bind(bind_address.str().c_str());
  57.     }
  58.     catch (zmq::error_t &err)
  59.     {
  60.         printf("[!] TCPListener: %s\n", err.what());
  61.         throw std::bad_alloc();
  62.     }
  63. }
  64.  
  65. std::string TCPListener::receive()
  66. {
  67.     zmq::message_t request;
  68.  
  69.     printf("[TCP] Receiving...\n");
  70.  
  71.     try
  72.     {
  73.         listenSocket->recv(&request);
  74.     }
  75.     catch (zmq::error_t &e)
  76.     {
  77.         printf("[!] IPC: receive() : %s\n", e.what());
  78.     }
  79.  
  80.     // Debug
  81.     printf ("Received message: \"%s\"\n", (char *)request.data());
  82.  
  83.     return std::string((const char*)request.data());
  84. }
  85.  
  86. /* MultiServer: declaration */
  87. class MultiServer
  88. {
  89. public:
  90.     MultiServer() : context(1) {}            //!< Initialise the zmq context
  91.     virtual ~MultiServer() {}
  92.  
  93.     void plug(TCPListener *listener);        //!< Plug a TCPListener
  94.     std::string receive(long timeout = -1);  //!< Poll all listeners and receive data
  95.  
  96. protected:
  97.     bool remListener(TCPListener *listener);  //!< Remove a TCPListener
  98.     zmq::context_t context;                   //!< ZeroMQ context
  99.     std::list<TCPListener *> listeners;       //!< This is where TCPListeners are added
  100. };
  101.  
  102. /* MultiServer: implementation */
  103. bool MultiServer::remListener(TCPListener *listener)
  104. {
  105.     bool found = false;
  106.  
  107.     std::list<TCPListener *>::iterator it;
  108.     for (it = listeners.begin(); !found && it != listeners.end(); ++it)
  109.     {
  110.         if (*it == listener)
  111.         {
  112.             listeners.erase(it);
  113.             printf("[-] Removed Listener %04x\n", listener);
  114.             found = true;
  115.         }
  116.     }
  117.  
  118.     return found;
  119. }
  120.  
  121. void MultiServer::plug(TCPListener *listener)
  122. {
  123.     // TODO: Prevent multiple plug to the same listener.
  124.     if (listener != NULL)
  125.     {
  126.         listener->setup(&context);
  127.         listeners.push_back(listener);
  128.         printf("[+] Added TCPListener %04x (socket: %04x)\n", listener, listener->getSocket());
  129.     }
  130. }
  131.  
  132. std::string MultiServer::receive(long timeout)
  133. {
  134.     printf("[ ] Polling %ld listener(s)...\n", listeners.size());
  135.  
  136.     // Make a new pollitem array
  137.     zmq::pollitem_t poll_items[listeners.size()];
  138.     unsigned int i = 0;
  139.     std::list<TCPListener *>::iterator it;
  140.     for (it = listeners.begin(); it != listeners.end(); ++it, ++i)
  141.     {
  142.         poll_items[i].socket = (*it)->getSocket();
  143.         poll_items[i].fd = 0;
  144.         poll_items[i].events = ZMQ_POLLIN;
  145.         poll_items[i].revents = 0;
  146.     }
  147.  
  148.     try
  149.     {
  150.         for (unsigned int i = 0; i < listeners.size(); ++i)
  151.             printf("[%u] { %04x | %d | %u | %u }\n",
  152.                    i, poll_items[i].socket, poll_items[i].fd, poll_items[i].events, poll_items[i].revents);
  153.  
  154.         /*********** SEGMENTATION FAULT ***********/
  155.         // Poll listeners
  156.         zmq::poll(poll_items, (int)listeners.size(), timeout);
  157.         /******************************************/
  158.     }
  159.     catch (zmq::error_t &err)
  160.     {
  161.         printf("[!] MultiServer: %s\n", err.what());
  162.         throw std::bad_alloc();
  163.     }
  164.  
  165.     /* -- Disabled for the moment --
  166.     // Examine polled listeners and collect data
  167.     for (unsigned int i = 0; i < listeners.size(); ++i)
  168.     {
  169.         if (pollItems[i]->revents & ZMQ_POLLIN)
  170.         {
  171.             printf("[ ] Incoming message on listener %d\n", i);
  172.  
  173.             // Fetch the message
  174.             return listeners[i]->receive();
  175.         }
  176. }
  177.     */
  178.     return "..."; // Temporary dummy return to make the compiler happy
  179. }
  180.  
  181.  
  182. /* ---   M A I N   --- */
  183. int main(int argc, char *argv[])
  184. {
  185.     try
  186.     {
  187.         TCPListener tcp_listener(25000);
  188.         MultiServer server;
  189.        
  190.         server.plug(&tcp_listener);
  191.        
  192.         while (true)
  193.         {
  194.             std::string message = server.receive();
  195.             printf("[R] %s\n", message.c_str());
  196.         }
  197.     }
  198.     catch (std::exception &e)
  199.     {
  200.         printf("[!] Exception: %s\n", e.what());
  201.     }
  202.    
  203.     return 0;
  204. }
RAW Paste Data
Top