jwendelil4 | 21d169f | 2020-03-23 18:03:22 +0100 | [diff] [blame] | 1 | /* |
| 2 | * TCPSelectServer.h |
| 3 | * |
| 4 | * Author: wendel |
| 5 | */ |
| 6 | |
| 7 | #ifndef BASYX_SERVER_BASYXTCPSELECTSERVER_H_ |
| 8 | #define BASYX_SERVER_BASYXTCPSELECTSERVER_H_ |
| 9 | |
| 10 | #include <BaSyx/vab/core/IModelProvider.h> |
| 11 | #include <BaSyx/vab/provider/native/frame/BaSyxNativeFrameProcessor.h> |
| 12 | #include <BaSyx/log/log.h> |
| 13 | |
| 14 | #include <sys/time.h> |
| 15 | #include <sys/socket.h> |
| 16 | #include <sys/ioctl.h> |
| 17 | #include <netinet/in.h> |
| 18 | |
| 19 | namespace basyx { |
| 20 | namespace vab { |
| 21 | namespace provider { |
| 22 | namespace native { |
| 23 | |
| 24 | using socket_t = int; |
| 25 | |
| 26 | /**********************************************************************************************/ |
| 27 | /* A non-blocking server that is capable to observe real-time properties. */ |
| 28 | /* To obtain this property the server loops over the ingoing connections, */ |
| 29 | /* instead of waiting actively. */ |
| 30 | /* This implementation is based on an example given on: */ |
| 31 | /* https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_72/rzab6/xnonblock.htm */ |
| 32 | /**********************************************************************************************/ |
| 33 | class TCPSelectServer |
| 34 | { |
| 35 | public: |
| 36 | /**********************************************************************************************/ |
| 37 | /* Server Constructor */ |
| 38 | /* */ |
| 39 | /* @param backend the backen (normally a model provider) */ |
| 40 | /* @param port the tcp port which should be used for connections */ |
| 41 | /* @param timeout_ms Time until the server is closed if no connection comes in. */ |
| 42 | /* @param listen_backlog defines the number of pending connections until server rejects */ |
| 43 | /* incoming connections. */ |
| 44 | /**********************************************************************************************/ |
| 45 | TCPSelectServer(core::IModelProvider * backend, int port, |
| 46 | int timeout_ms, int listen_backlog = 32); |
| 47 | |
| 48 | /**********************************************************************************************/ |
| 49 | /* Destructor. Closes all connections. */ |
| 50 | /**********************************************************************************************/ |
| 51 | ~TCPSelectServer(); |
| 52 | |
| 53 | /**********************************************************************************************/ |
| 54 | /* Initializes the server. */ |
| 55 | /**********************************************************************************************/ |
| 56 | void Init(); |
| 57 | |
| 58 | /**********************************************************************************************/ |
| 59 | /* Needs to be called periodically. */ |
| 60 | /* Waiting for incoming connections or data of connected sockets. */ |
| 61 | /**********************************************************************************************/ |
| 62 | int Update(); |
| 63 | |
| 64 | /**********************************************************************************************/ |
| 65 | /* Closes all connections. */ |
| 66 | /**********************************************************************************************/ |
| 67 | void Close(); |
| 68 | |
| 69 | /**********************************************************************************************/ |
| 70 | /* Currenct server running state. */ |
| 71 | /**********************************************************************************************/ |
| 72 | bool isRunning(); |
| 73 | |
| 74 | private: |
| 75 | void clean_up(); |
| 76 | |
| 77 | /*************************************************/ |
| 78 | /* Accept all incoming connections that are */ |
| 79 | /* queued up on the listening socket before we */ |
| 80 | /* loop back and call select again. */ |
| 81 | /*************************************************/ |
| 82 | void accept_incoming_connections(); |
| 83 | |
| 84 | /*************************************************/ |
| 85 | /* Receive all incoming data on this socket */ |
| 86 | /* before we loop back and call select again. */ |
| 87 | /*************************************************/ |
| 88 | void receive_incoming_data(int fd); |
| 89 | |
| 90 | private: |
| 91 | bool initialized; |
| 92 | |
| 93 | vab::core::IModelProvider* backend; |
| 94 | std::unique_ptr<vab::provider::native::frame::BaSyxNativeFrameProcessor> frame_processor; |
| 95 | basyx::log log; |
| 96 | |
| 97 | // Buffers |
| 98 | static constexpr std::size_t default_buffer_size = 4096; |
| 99 | std::array<char, default_buffer_size> recv_buffer; |
Constantin Ziesche | 02817f1 | 2020-08-04 21:40:43 +0200 | [diff] [blame^] | 100 | std::array<char, default_buffer_size> send_buffer; |
jwendelil4 | 21d169f | 2020-03-23 18:03:22 +0100 | [diff] [blame] | 101 | |
| 102 | //tcp |
| 103 | int port; |
| 104 | struct timeval timeout; |
| 105 | socket_t listen_sd, max_socket; |
| 106 | int listen_backlog; |
| 107 | int desc_ready, end_server = 0; |
| 108 | struct sockaddr_in addr; |
| 109 | fd_set master_set; |
| 110 | bool close_connection; |
| 111 | }; |
| 112 | |
| 113 | } |
| 114 | } |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | #endif |