MRPT  2.0.0
CClientTCPSocket.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 #pragma once
10 
11 #include <mrpt/config.h> // MRPT_WORD_SIZE
12 #include <mrpt/io/CStream.h>
13 #include <mrpt/system/os.h>
14 #include <cstdint>
15 #include <cstring> // strlen()
16 #include <string>
17 
18 namespace mrpt
19 {
20 /** Serial and networking devices and utilities */
21 namespace comms
22 {
23 class CServerTCPSocket;
24 
25 /** A TCP socket that can be connected to a TCP server, implementing MRPT's
26  * CStream interface for passing objects as well as generic read/write methods.
27  * Unless otherwise noticed, operations are blocking.
28  *
29  * Note that for convenience, DNS lookup is performed with a timeout
30  * (default=3000ms), which can be changed by the static member
31  * CClientTCPSocket::DNS_LOOKUP_TIMEOUT_MS
32  * \ingroup mrpt_comms_grp
33  */
35 {
36  friend class CServerTCPSocket;
37 
38  public:
39  /** See description of CClientTCPSocket */
40  static unsigned int DNS_LOOKUP_TIMEOUT_MS;
41 
42  protected:
43 #ifdef _WIN32
44 /** The handle for the connected TCP socket, or INVALID_SOCKET
45  */
46 #if MRPT_WORD_SIZE == 64
47  uint64_t m_hSock;
48 #else
49  uint32_t m_hSock;
50 #endif
51 #else
52  /** The handle for the connected TCP socket, or -1 */
53  int m_hSock;
54 #endif
55  /** The IP address of the remote part of the connection. */
56  std::string m_remotePartIP;
57  /** The TCP port of the remote part of the connection. */
58  unsigned short m_remotePartPort = 0;
59 
60  /** Introduces a virtual method responsible for reading from the stream
61  * (This method BLOCKS)
62  * This method is implemented as a call to "readAsync" with infinite
63  * timeouts.
64  * \sa readAsync */
65  size_t Read(void* Buffer, size_t Count) override;
66 
67  /** Introduces a virtual method responsible for writing to the stream.
68  * Write attempts to write up to Count bytes to Buffer, and returns the
69  * number of bytes actually written.
70  * This method is implemented as a call to "writeAsync" with infinite
71  * timeouts.
72  * \sa writeAsync */
73  size_t Write(const void* Buffer, size_t Count) override;
74 
75  /** Returns a description of the last Sockets error */
76  std::string getLastErrorStr();
77 
78  public:
79  /** Default constructor \sa connect */
81 
82  /** Destructor */
83  ~CClientTCPSocket() override;
84 
85  /** Establishes a connection with a remote part.
86  * \param remotePartAddress This string can be a host name, like "server"
87  * or "www.mydomain.org", or an IP address "11.22.33.44".
88  * \param remotePartTCPPort The port on the remote machine to connect to.
89  * \param timeout_ms The timeout to wait for the connection (0: NO
90  * TIMEOUT)
91  * \exception This method raises an exception if an error is found with a
92  * textual description of the error.
93  */
94  void connect(
95  const std::string& remotePartAddress, unsigned short remotePartTCPPort,
96  unsigned int timeout_ms = 0);
97 
98  /** Returns true if this objects represents a successfully connected socket
99  */
100  bool isConnected();
101 
102  /** Closes the connection */
103  void close();
104 
105  /** Writes a string to the socket.
106  * \exception std::exception On communication errors
107  */
108  void sendString(const std::string& str);
109 
110  /** This virtual method has no effect in this implementation over a TCP
111  * socket, and its use raises an exception */
112  uint64_t Seek(
113  int64_t off, CStream::TSeekOrigin org = sFromBeginning) override;
114 
115  /** This virtual method has no effect in this implementation over a TCP
116  * socket, and its use raises an exception */
117  uint64_t getTotalBytesCount() const override;
118 
119  /** This virtual method has no effect in this implementation over a TCP
120  * socket, and its use raises an exception */
121  uint64_t getPosition() const override;
122 
123  /** A method for reading from the socket with an optional timeout.
124  * \param Buffer The destination of data.
125  * \param Cound The number of bytes to read.
126  * \param timeoutStart_ms The maximum timeout (in milliseconds) to wait for
127  * the starting of data from the other side.
128  * \param timeoutBetween_ms The maximum timeout (in milliseconds) to wait
129  * for a chunk of data after a previous one.
130  * Set timeout's to -1 to block until the desired number of bytes are
131  * read, or an error happens.
132  * \return The number of actually read bytes.
133  */
134  size_t readAsync(
135  void* Buffer, const size_t Count, const int timeoutStart_ms = -1,
136  const int timeoutBetween_ms = -1);
137 
138  /** A method for writing to the socket with optional timeouts.
139  * The method supports writing block by block as the socket allows us to
140  * write more data.
141  * \param Buffer The data.
142  * \param Cound The number of bytes to write.
143  * \param timeout_ms The maximum timeout (in milliseconds) to wait for the
144  * socket to be available for writing (for each block).
145  * Set timeout's to -1 to block until the desired number of bytes are
146  * written, or an error happens.
147  * \return The number of actually written bytes.
148  */
149  size_t writeAsync(
150  const void* Buffer, const size_t Count, const int timeout_ms = -1);
151 
152  /** Send a message through the TCP stream.
153  * \param outMsg The message to be shown.
154  * \param timeout_ms The maximum timeout (in milliseconds) to wait for the
155  * socket in each write operation.
156  * \return Returns false on any error, or true if everything goes fine.
157  * \tparam MESSAGE can be mrpt::serialization::CMessage
158  */
159  template <class MESSAGE>
160  bool sendMessage(const MESSAGE& outMsg, const int timeout_ms = -1)
161  {
162  // (1) Send a "magic word":
163  const char* magic = "MRPTMessage";
164  uint32_t toWrite = strlen(magic);
165  uint32_t written = writeAsync(magic, toWrite, timeout_ms);
166  if (written != toWrite) return false; // Error!
167  // (2) Send the message type:
168  toWrite = sizeof(outMsg.type);
169  written = writeAsync(&outMsg.type, toWrite, timeout_ms);
170  if (written != toWrite) return false; // Error!
171  // (3) Send the message's content length:
172  uint32_t contentLen = outMsg.content.size();
173  toWrite = sizeof(contentLen);
174  written = writeAsync(&contentLen, toWrite, timeout_ms);
175  if (written != toWrite) return false; // Error!
176  // (4) Send the message's contents:
177  toWrite = contentLen;
178  written = writeAsync(&outMsg.content[0], toWrite, timeout_ms);
179  if (written != toWrite) return false; // Error!
180  return true;
181  }
182 
183  /** Waits for an incoming message through the TCP stream.
184  * \param inMsg The received message is placed here.
185  * \param timeoutStart_ms The maximum timeout (in milliseconds) to wait for
186  * the starting of data from the other side.
187  * \param timeoutBetween_ms The maximum timeout (in milliseconds) to wait
188  * for a chunk of data after a previous one.
189  * \return Returns false on any error (or timeout), or true if everything
190  * goes fine.
191  * \tparam MESSAGE can be mrpt::serialization::CMessage
192  */
193  template <class MESSAGE>
195  MESSAGE& inMsg, const unsigned int timeoutStart_ms = 100,
196  const unsigned int timeoutBetween_ms = 1000)
197  {
198  // (1) Read the "magic word":
199  char magic[20];
200  uint32_t toRead = 11;
201  uint32_t actRead =
202  readAsync(magic, toRead, timeoutStart_ms, timeoutBetween_ms);
203  if (actRead != toRead) return false; // Error!
204  magic[actRead] = 0; // Null-term string
205  // Check magic:
206  if (0 != ::strcmp("MRPTMessage", magic)) return false;
207  // (2) Read the message type:
208  toRead = sizeof(inMsg.type);
209  actRead = readAsync(
210  &inMsg.type, toRead, timeoutBetween_ms, timeoutBetween_ms);
211  if (actRead != toRead) return false; // Error!
212  // (3) Read the message's content length:
213  uint32_t contentLen;
214  toRead = sizeof(contentLen);
215  actRead = readAsync(
216  &contentLen, toRead, timeoutBetween_ms, timeoutBetween_ms);
217  if (actRead != toRead) return false; // Error!
218  inMsg.content.resize(contentLen);
219  // (4) Read the message's contents:
220  toRead = contentLen;
221  actRead = readAsync(
222  &inMsg.content[0], toRead, timeoutBetween_ms, timeoutBetween_ms);
223  if (actRead != toRead) return false; // Error!
224  return true;
225  }
226 
227  /** Return the number of bytes already in the receive queue (they can be
228  * read without waiting) */
229  size_t getReadPendingBytes();
230 
231  /** Set the TCP no delay option of the protocol (Nagle algorithm).
232  * \param newValue New value (0 enable Nagle algorithm, 1 disable).
233  * \return Return a number lower than 0 if any error occurred.
234  */
235  int setTCPNoDelay(int newValue);
236 
237  /** Return the value of the TCPNoDelay option. */
238  int getTCPNoDelay();
239 
240  /** Set the size of the SO send buffer. This buffer is used to store data,
241  * and is sended when is full.
242  * \param newValue New size of the SO send buffer.
243  * \return Return a number lower than 0 if any error occurred.
244  */
245  int setSOSendBufffer(int newValue);
246 
247  /** Return the current size of the SO send buffer. */
248  int getSOSendBufffer();
249 
250 }; // End of class def.
251 
252 } // namespace comms
253 } // namespace mrpt
static unsigned int DNS_LOOKUP_TIMEOUT_MS
See description of CClientTCPSocket.
int setSOSendBufffer(int newValue)
Set the size of the SO send buffer.
bool sendMessage(const MESSAGE &outMsg, const int timeout_ms=-1)
Send a message through the TCP stream.
void connect(const std::string &remotePartAddress, unsigned short remotePartTCPPort, unsigned int timeout_ms=0)
Establishes a connection with a remote part.
size_t Write(const void *Buffer, size_t Count) override
Introduces a virtual method responsible for writing to the stream.
bool isConnected()
Returns true if this objects represents a successfully connected socket.
bool receiveMessage(MESSAGE &inMsg, const unsigned int timeoutStart_ms=100, const unsigned int timeoutBetween_ms=1000)
Waits for an incoming message through the TCP stream.
uint64_t Seek(int64_t off, CStream::TSeekOrigin org=sFromBeginning) override
This virtual method has no effect in this implementation over a TCP socket, and its use raises an exc...
int getSOSendBufffer()
Return the current size of the SO send buffer.
size_t Read(void *Buffer, size_t Count) override
Introduces a virtual method responsible for reading from the stream (This method BLOCKS) This method ...
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: io/CStream.h:28
uint64_t getTotalBytesCount() const override
This virtual method has no effect in this implementation over a TCP socket, and its use raises an exc...
std::string m_remotePartIP
The IP address of the remote part of the connection.
~CClientTCPSocket() override
Destructor.
A TCP socket that can be wait for client connections to enter.
CClientTCPSocket()
Default constructor.
int getTCPNoDelay()
Return the value of the TCPNoDelay option.
std::string getLastErrorStr()
Returns a description of the last Sockets error.
size_t writeAsync(const void *Buffer, const size_t Count, const int timeout_ms=-1)
A method for writing to the socket with optional timeouts.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
int setTCPNoDelay(int newValue)
Set the TCP no delay option of the protocol (Nagle algorithm).
uint64_t getPosition() const override
This virtual method has no effect in this implementation over a TCP socket, and its use raises an exc...
A TCP socket that can be connected to a TCP server, implementing MRPT&#39;s CStream interface for passing...
void close()
Closes the connection.
unsigned short m_remotePartPort
The TCP port of the remote part of the connection.
uint32_t m_hSock
The handle for the connected TCP socket, or INVALID_SOCKET.
size_t getReadPendingBytes()
Return the number of bytes already in the receive queue (they can be read without waiting) ...
size_t readAsync(void *Buffer, const size_t Count, const int timeoutStart_ms=-1, const int timeoutBetween_ms=-1)
A method for reading from the socket with an optional timeout.
void sendString(const std::string &str)
Writes a string to the socket.



Page generated by Doxygen 1.8.14 for MRPT 2.0.0 Git: b38439d21 Tue Mar 31 19:58:06 2020 +0200 at miƩ abr 1 00:50:30 CEST 2020