Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
CScommBase.hh
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5 Multimediale Systeme der Informationsverarbeitung
6 Institut fuer Informatik
7 Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #ifndef __BIASCScommBase__
26 #define __BIASCScommBase__
27 
28 #include <bias_config.h>
29 #include <Base/Common/W32Compat.hh>
30 #include <Base/Common/BIASpragmaStart.hh>
31 
32 #ifndef BIAS_HAVE_PTHREADS
33 # error BIAS_HAVE_PTHREADS not defined. But BIASNetworkComm needs pthreads (on Unix and Win32). Please enable USE_PTHREADS in CMake configure step.
34 #endif
35 
36 #include <pthread.h>
37 #include <sys/types.h>
38 #include <vector>
39 #include <map>
40 #include <Base/Debug/Debug.hh>
41 #include <NetworkComm/CScommClasses.hh>
42 
43 namespace BIAS {
44 
45 #define D_CS_MAXCLIENTS 100
46 #define D_CS_DEFAULT_PORT 4123
47 
48 #define D_CS_LISTENER 1<<0
49 #define D_CS_RECEIVER 1<<1
50 #define D_CS_CONNECT 1<<2
51 #define D_CS_ANALYZE 1<<3
52 #define D_CS_SEND 1<<4
53 #define D_CS_GETDATA 1<<5
54 
55 #ifdef WIN32
56 # define mygetpid() (pthread_self()).p
57 #else
58 # define mygetpid() getpid()
59 #endif //WIN32
60 
61  /**
62  @class CScommBase
63  @brief this class CScomm (ClientServer communciation)
64  handles data comunication via TCP/IP for one server and
65  multiple clients.
66  @ingroup network
67  It spawns threads itself for all communication.
68  Messages can be registered by functions or within a file(not yet).
69  See CScommClient or CScommServer for more details.
70 
71  @author Daniel Grest, Jan 2004
72  */
73  class BIASNetworkComm_EXPORT CScommBase
74  : public BIAS::Debug
75  {
76  public:
77  virtual ~CScommBase();
78 
79  /** Set threaded to false for deactivating the receive-thread. Data will be
80  read from TCP-buffer only when GetData methods are called. Threaded
81  receive is activated by default!
82  Beware: if there's no msg in tcp-buffer, GetData will BLOCK until there
83  is any new msg (this need not be the one GetData was called for,
84  for example binary instead of int)
85  if receive-buffer is completly filled, send blocks until msg
86  can be delivered!
87  */
88  CScommBase(bool threaded = true);
89 
90  /// copy ctor required due to ostream member with explicit ctor JW
91  CScommBase(const CScommBase & arg);
92 
93  /// assignment op. required due to ostream member with explicit ctor JW
94  CScommBase & operator=(const CScommBase & arg);
95 
96  /** If not threaded you can set this true to keep all received data.
97  Else a call of GetData() will deliver the newest msg only.
98  Default is off.
99  If threaded this is useless... (always off)
100  */
101  void SetKeepAll(bool on) { keepAll_=on; }
102 
103  /** only if not threaded! <br>
104  Blocks until any new msg arrives,
105  or returns instantly if a new message
106  is already in a buffer slot. The msg name is returned in msgName.
107 
108  The return value indicates how many additional new msgs are in the
109  buffer slots, e.g. if 0 the msgName is the only new message.
110  @return <0 if an error occured, >=0 the amount of new msgs in other
111  slots.
112  */
113  int WaitForNewMessage(std::string &msgName);
114 
115 
116  /** returns instantly:<br>
117  0 if new data has arrived and the data in xxxData <br>
118  1 if no new data has arrived, the data in xxxData stays unchanged<br>
119  -1 in case of errors
120  */
121  int GetData(const std::string &msgName, std::vector<float> &floatData);
122  int GetData(const std::string &msgName, std::vector<int> &intData);
123  int GetData(const std::string &msgName,
124  std::vector<std::string> &stringData);
125  /** returns the binarydata in the vector, its wise to reserve enough
126  bytes, if the size is known.
127  */
128  int GetData(const std::string &msgName,
129  std::vector<char> &binaryData);
130 
131  /** sends msg msgName to all connected commPartners.
132  Msg doesn't have to be registered on the sender side,
133  but must be registered on the receiver side!
134  */
135  int SendMsg(const std::string &msgName, std::vector<float> &floatData);
136  int SendMsg(const std::string &msgName, std::vector<int> &intData);
137  int SendMsg(const std::string &msgName,
138  std::vector<std::string> &stringData);
139 
140  /** maximum size for binary data is 15MB!
141  */
142  int SendMsg(const std::string &msgName, char* binaryData, unsigned int size);
143 
144  /** like above, but msg is only send to one specific commPartner given
145  as string, which must equal the name given by the client to itself<br>
146  @return -2 if no such commPartner, 0 in case of no error
147  */
148  int SendMsg(const std::string commPartnerName,
149  const std::string &msgName, char* binaryData, unsigned int size);
150 
151  /** like above, but msg is only send to one specific commPartner given
152  as the index number of all connected partners
153  @return -2 if no such commPartner, 0 in case of no error
154  */
155  int SendMsg(int commPartnerNr,
156  const std::string &msgName, char* binaryData, unsigned int size);
157 
158 
159  /** only registered msgs are accepted by commPartners
160  Register a msg with this functions.
161  Amount is the number of dataTypes for this msg,
162  for binarydata this is not necessary <br>
163  The msg will be bound to the first commPartner sending such a msg.
164  And will be accepted only from him later.<br>
165  All msgNames have to be unique!
166 
167  return zero on success
168  <0 on errors
169  */
170  int RegisterMsg(std::string msgName, EdataType dataType, int amount=1);
171 
172  /** same as above, but the msg is only accepted from a specific commPartner
173  */
174  int RegisterMsg(std::string commPartnerName,
175  std::string msgName, EdataType dataType, int amount=1);
176 
177  /** returns the number of connected commPartners
178  */
179  inline int GetConnections() { return commPartnersConnected_; }
180 
181  /** returns the name of the commPartner with nr commPartnerNr or
182  empty string in case of a number, that is to high.
183  */
184  std::string GetCommPartnerName(int commPartnerNr);
185 
186  /** set the time in ms until a commPartner is assumed to be disconnected.<br>
187  If time is zero there is no timeOut. default is no Time out
188  */
189  inline void SetConnectionTimeOut(unsigned int time) {
190  if (time==0) timeOutFlag_=false; timeOut_=time;}
191 
192  /** if set on, the server will take automatically the next free TCP port
193  for connections. The client tries 10 consecutive different ports
194  to conncect the server. Default is off. Useful if you don't
195  care about port numbers and just want a connection somehow.
196  */
197  inline void SetAutomaticPortChange(bool on) { portChange_=on; }
198 
199  // tells wether receive-threads are active or not
200  inline bool GetThreadedReceive() { return threaded_; }
201 
202  /** gives a lot of information regarding the connections, like the exact
203  data received and send. Implies verbose.
204  */
205  void SetLog(bool on);
206 
207  /** set the output of log msgs to another stream, e.g. to a file.
208  Default ist cout.
209  */
210  void SetLogOut(std::ostream &outputStream);
211 
212  /** gives some information about establising conn, and disconnecting etc.
213  */
214  void SetVerbose(bool on);
215 
216  /** set the output of verbose msgs to another stream, e.g. to a file.
217  Default ist cout.
218  */
219  void SetVerboseOut(std::ostream &outputStream);
220 
221  protected:
222 
223  // exports for dll (cmenk)
224  //BIAS_EXPORT_STL_VECTOR( BIASNetworkComm_EXPORT, CScommData )
225  //BIAS_EXPORT_STL_VECTOR( BIASNetworkComm_EXPORT, CScommMsg )
226  //BIAS_EXPORT_STL_MAP( BIASNetworkComm_EXPORT, std::string, int )
227 
228  void logOutPut_(const char *data, unsigned int size);
229 
230  // helper func for the SendMsg() funcs
231  int SendMsg_(const std::string &data);
232 
233  // helper for GetData(), finds the index of the msg in registeredMsgs
234  // returns the index, by use of a the std::map indexRegMsgs_
235  int GetData_(const std::string &msgName);
236 
237  /** return values:
238  0 no error all fine
239 
240  warnings:
241  1 not enough data to analyze (<3 bytes)
242  2 no data after msg name
243  3 more data read than registered for a msg
244  4 less data read than registered
245  A warning is returned if one of the above cases was true for any one
246  msg in the buffer.
247 
248  errors:
249  -1 only trash received
250  */
251  int AnalyzeData_(int clientNr);
252 
253  // checks if the msg with msgName ist registered for this comm and
254  // returns the dataTypeToread and the dataSizeToRead if the msg is registered
255  // return value is the index of the reg msg in registeredMsgs_ ,
256  // or <0 for errors and unregistered msgs
257  int CheckRegisteredMsgs_(std::string &msgName, const CScommData &cPartner,
258  EdataType &dataTypeToRead,
259  unsigned int &dataSizeToRead);
260 
261  void receiveThread_(int clientNr);
262 
263  //Replaces receiveThread_(..) if threaded-receive is deactivated.
264  //Reads up to 200000 bytes from receive-buffer for all comm-partners
265  void syncReceive_();
266 
267  // this is specific for server, dataSize is changed to the rest of bytes to
268  // process, while offset is the number of processed bytes
269  int AnalyzeFirstMsg_(int commNr);
270 
271  // starts a receive thread for a new connection, called by listener(server)
272  // or by ConnectServer (client)
273  int AcceptConn_(int fd);
274 
275  std::vector<CScommData> commPartners_;
278 
279  // if true, the TCP input buffer is read completely each time
281  bool isServer_;
282 
283  // added by aptersen
285  bool threaded_;
286  bool keepAll_;
287 
288  bool log_;
289  std::ostream logOut_;
290  bool verbose_;
291  std::ostream verboseOut_;
292 
293  std::string name_;
294  unsigned int timeOut_;//after this time(ms) without data ,a comm is disc.
295  bool timeOutFlag_; // if false, there is no timeOut
297  pthread_mutex_t registerLock_; // needed for acces on registeredMsgs_
298 
299  std::vector<CScommMsg> msgBuffer_;
300  std::vector<CScommMsg> registeredMsgs_;
301 
302  private: // avoid DLL export
303  /// used by GetData
304  /// stores the index to registeredMsgs_
305  std::map<std::string, int> indexRegMsgs_;
306 
307  // bool binaryMsgActive_; // for analyzeData
308 
309  protected:
310  friend void* receivethread(void *data);
311  // friend void* listenthread(void *data);
312  };
313 
314  /// these are wrapper to comply to the pthread_create() interface
315  void *receivethread(void *data);
316  //extern void* listenthread(void *data); // defined in CScommServer.cc
317 
318 
319 }
320 #include <Base/Common/BIASpragmaEnd.hh>
321 #endif
int commPartnersConnected_
Definition: CScommBase.hh:277
unsigned int timeOut_
Definition: CScommBase.hh:294
std::vector< CScommMsg > registeredMsgs_
Definition: CScommBase.hh:300
helper class for CScommBase
void SetConnectionTimeOut(unsigned int time)
set the time in ms until a commPartner is assumed to be disconnected.
Definition: CScommBase.hh:189
int GetConnections()
returns the number of connected commPartners
Definition: CScommBase.hh:179
pthread_mutex_t registerLock_
Definition: CScommBase.hh:297
void SetAutomaticPortChange(bool on)
if set on, the server will take automatically the next free TCP port for connections.
Definition: CScommBase.hh:197
std::vector< CScommData > commPartners_
Definition: CScommBase.hh:275
this class CScomm (ClientServer communciation) handles data comunication via TCP/IP for one server an...
Definition: CScommBase.hh:73
std::vector< CScommMsg > msgBuffer_
Definition: CScommBase.hh:299
bool GetThreadedReceive()
Definition: CScommBase.hh:200
void * receivethread(void *data)
these are wrapper to comply to the pthread_create() interface
void SetKeepAll(bool on)
If not threaded you can set this true to keep all received data.
Definition: CScommBase.hh:101
std::ostream logOut_
Definition: CScommBase.hh:289
std::ostream verboseOut_
Definition: CScommBase.hh:291
std::string name_
Definition: CScommBase.hh:293