|
UniSet
2.6.0
|
00001 // ------------------------------------------------------------------------- 00002 #ifndef ModbusTCPServer_H_ 00003 #define ModbusTCPServer_H_ 00004 // ------------------------------------------------------------------------- 00005 #include <string> 00006 #include <queue> 00007 #include <ev++.h> 00008 #include <sigc++/sigc++.h> 00009 #include "Mutex.h" 00010 #include "Debug.h" 00011 #include "Configuration.h" 00012 #include "PassiveTimer.h" 00013 #include "ModbusTypes.h" 00014 #include "ModbusServer.h" 00015 #include "ModbusTCPSession.h" 00016 #include "UTCPSocket.h" 00017 #include "EventLoopServer.h" 00018 // ------------------------------------------------------------------------- 00019 namespace uniset 00020 { 00021 // ------------------------------------------------------------------------- 00029 class ModbusTCPServer: 00030 public EventLoopServer, 00031 public ModbusServer 00032 { 00033 public: 00034 ModbusTCPServer( const std::string& addr, int port = 502 ); 00035 virtual ~ModbusTCPServer(); 00036 00040 void run( const std::unordered_set<ModbusRTU::ModbusAddr>& vmbaddr, bool thread = false ); 00041 00042 virtual bool isActive() const override; 00043 00044 void setMaxSessions( size_t num ); 00045 inline size_t getMaxSessions() 00046 { 00047 return maxSessions; 00048 } 00049 00051 void setSessionTimeout( timeout_t msec ); 00052 inline timeout_t getSessionTimeout() 00053 { 00054 return sessTimeout; 00055 } 00056 00058 size_t getCountSessions(); 00059 00060 inline void setIgnoreAddrMode( bool st ) 00061 { 00062 ignoreAddr = st; 00063 } 00064 inline bool getIgnoreAddrMode() 00065 { 00066 return ignoreAddr; 00067 } 00068 00069 virtual void terminate(); 00070 00071 // Сбор статистики по соединениям... 00072 struct SessionInfo 00073 { 00074 SessionInfo( const std::string& a, unsigned int ask ): iaddr(a), askCount(ask) {} 00075 00076 std::string iaddr; 00077 unsigned int askCount; 00078 }; 00079 00080 typedef std::list<SessionInfo> Sessions; 00081 00082 void getSessions( Sessions& lst ); 00083 00084 inline std::string getInetAddress() 00085 { 00086 return iaddr; 00087 } 00088 inline int getInetPort() 00089 { 00090 return port; 00091 } 00092 00093 // ------------------------------------------------- 00094 // Таймер. 00095 // Т.к. eventLoop() "бесконечный", то сделана возможность 00096 // подключиться к сигналу "таймера", например для обновления статистики по сессиям 00097 // \warning Следует иметь ввиду, что обработчик сигнала, должен быть максимально коротким 00098 // т.к. на это время останавливается работа основного потока (eventLoop) 00099 // ------------------------------------------------- 00100 typedef sigc::signal<void> TimerSignal; 00101 TimerSignal signal_timer(); 00102 00103 void setTimer( timeout_t msec ); 00104 inline timeout_t getTimer() 00105 { 00106 return tmTime; 00107 } 00108 00109 protected: 00110 00111 // ожидание (при этом время отдаётся eventloop-у) 00112 virtual void iowait( timeout_t msec ) override; 00113 00114 // функция receive пока не поддерживается... 00115 virtual ModbusRTU::mbErrCode realReceive( const std::unordered_set<ModbusRTU::ModbusAddr>& vaddr, timeout_t msecTimeout ) override; 00116 00117 virtual void evprepare() override; 00118 virtual void evfinish() override; 00119 00120 virtual void ioAccept(ev::io& watcher, int revents); 00121 void onTimer( ev::timer& t, int revents ); 00122 00123 void sessionFinished( const ModbusTCPSession* s ); 00124 00125 virtual size_t getNextData( unsigned char* buf, int len ) override 00126 { 00127 return 0; 00128 } 00129 00130 virtual ModbusRTU::mbErrCode sendData( unsigned char* buf, int len ) override 00131 { 00132 return ModbusRTU::erHardwareError; 00133 } 00134 00136 virtual void setChannelTimeout( timeout_t msec ) override {}; 00137 00138 int port = { 0 }; 00139 std::string iaddr; 00140 std::string myname; 00141 std::queue<unsigned char> qrecv; 00142 ModbusRTU::ADUHeader curQueryHeader; 00143 00144 std::mutex sMutex; 00145 typedef std::list<std::shared_ptr<ModbusTCPSession>> SessionList; 00146 SessionList slist; 00147 00148 bool ignoreAddr = { false }; 00149 00150 size_t maxSessions = { 100 }; 00151 size_t sessCount = { 0 }; 00152 00153 timeout_t sessTimeout = { 10000 }; // msec 00154 00155 ev::io io; 00156 ev::timer ioTimer; 00157 std::shared_ptr<UTCPSocket> sock; 00158 00159 const std::unordered_set<ModbusRTU::ModbusAddr>* vmbaddr = { nullptr }; 00160 TimerSignal m_timer_signal; 00161 00162 timeout_t tmTime_msec = { UniSetTimer::WaitUpTime }; // время по умолчанию для таймера (TimerSignal) 00163 double tmTime = { 0.0 }; 00164 00165 PassiveTimer ptWait; 00166 00167 private: 00168 // транслирование сигналов от Sessions.. 00169 void postReceiveEvent( ModbusRTU::mbErrCode res ); 00170 ModbusRTU::mbErrCode preReceiveEvent( const std::unordered_set<ModbusRTU::ModbusAddr> vaddr, timeout_t tout ); 00171 }; 00172 // ------------------------------------------------------------------------- 00173 } // end of namespace uniset 00174 // ------------------------------------------------------------------------- 00175 #endif // ModbusTCPServer_H_ 00176 // -------------------------------------------------------------------------
1.7.6.1