]> Dogcows Code - chaz/yoink/blob - src/stlplus/portability/tcp_sockets.hpp
cleanup stlplus files
[chaz/yoink] / src / stlplus / portability / tcp_sockets.hpp
1 #ifndef STLPLUS_TCP_SOCKET
2 #define STLPLUS_TCP_SOCKET
3 ////////////////////////////////////////////////////////////////////////////////
4
5 // Author: Andy Rushton
6 // Copyright: (c) Southampton University 1999-2004
7 // (c) Andy Rushton 2004-2009
8 // License: BSD License, see ../docs/license.html
9
10 // A platform-independent (Unix and Windows anyway) interface to TCP sockets
11
12 ////////////////////////////////////////////////////////////////////////////////
13
14 #include "portability_fixes.hpp"
15 #include "ip_sockets.hpp"
16 #include <string>
17
18 namespace stlplus
19 {
20
21 //////////////////////////////////////////////////////////////////////////////
22 // Server Classes: A server creates a listening port which waits for incoming
23 // connections. This is placed on the port number appropriate for the service
24 // - for example, a Telnet server would typically use port 23. For a new
25 // service you should of course use any port not allocated to a standard
26 // service. I believe that RFC 1700 defines the standard service port numbers.
27 // When an incoming connection is made, the server accepts it and in the
28 // process creates a new connection on a different port. This leaves the
29 // standard port listening for further connections. In effect, the server
30 // farms out the handling of the connections themselves and only takes
31 // responsibility for accepting the connection. This is reflected in the class
32 // structure. A TCP_server performs the listening and accepting roles, but
33 // creates a TCP_connection to handle the accepted connection.
34 //////////////////////////////////////////////////////////////////////////////
35
36 //////////////////////////////////////////////////////////////////////////////
37 // connection class created by TCP_server when a connection is accepted
38 // this is then used to perform any communications with the remote client
39
40 class TCP_connection : protected IP_socket
41 {
42 private:
43 // constructor to actually initialise the class - can only be constructed by TCP_server
44 friend class TCP_server;
45 TCP_connection(const IP_socket& socket);
46
47 public:
48
49 ////////////////////////////////////////////////////////////////////////////
50 // constructors/destructors
51
52 // create an uninitialised connection
53 TCP_connection(void);
54
55 ////////////////////////////////////////////////////////////////////////////
56 // initialisation, connection control
57 // Note: TCP connections can only be initialised by a TCP server
58
59 // test whether this is an initialised socket
60 // - returns whether this is initialised
61 // bool initialised(void) const;
62 using IP_socket::initialised;
63
64 // close, i.e. disconnect the socket
65 // - returns a success flag
66 // bool close(void);
67 using IP_socket::close;
68
69 ////////////////////////////////////////////////////////////////////////////
70 // sending/receiving
71
72 // test whether a socket is connected and ready to send data, returns if ready or on timeout
73 // - timeout: how long to wait in microseconds if not connected yet (blocking)
74 // - returns status
75 // bool send_ready(unsigned timeout = 0);
76 using IP_socket::send_ready;
77
78 // send data through the socket - if the data is long only part of it may
79 // be sent. The sent part is removed from the data, so the same string can
80 // be sent again and again until it is empty.
81 // - data: string containing data to be sent - any data successfully sent is removed
82 // - returns success flag
83 // bool send (std::string& data);
84 using IP_socket::send;
85
86 // test whether a socket is connected and ready to receive data, returns if ready or on timeout
87 // - timeout: how long to wait in microseconds if not connected yet (blocking)
88 // - returns status
89 // bool receive_ready(unsigned timeout = 0);
90 using IP_socket::receive_ready;
91
92 // receive data through the socket - if the data is long only part of it
93 // may be received. The received data is appended to the string, building
94 // it up in stages, so the same string can be received again and again
95 // until all information has been received.
96 // - data: string receiving data from socket - any data successfully received is appended
97 // - returns success flag
98 // bool receive (std::string& data);
99 using IP_socket::receive;
100
101 ////////////////////////////////////////////////////////////////////////////
102 // informational
103
104 // the local port number of the connection
105 // - returns the port number, 0 if not bound to a port
106 // unsigned short local_port(void) const;
107 using IP_socket::local_port;
108
109 // the remote address of the connection
110 // - returns the address, 0 if not connected
111 // unsigned long remote_address(void) const;
112 using IP_socket::remote_address;
113
114 // the remote port number of the connection
115 // - returns the port number, 0 if not connected to a port
116 // unsigned short remote_port(void) const;
117 using IP_socket::remote_port;
118
119 ////////////////////////////////////////////////////////////////////////////
120 // error handling
121 // errors are set internally
122 // an error code of 0 is the test for no error, don't rely on the message being an empty string
123 // an error code != 0 means an error, then there will be a message explaining the error
124
125 // if an error is set it stays set - so you must clear it before further operations
126 // void clear_error(void) const;
127 using IP_socket::clear_error;
128
129 // get the error code of the last error
130 // int error(void) const;
131 using IP_socket::error;
132
133 // get the explanatory message of the last error
134 // std::string message(void) const;
135 using IP_socket::message;
136
137 ////////////////////////////////////////////////////////////////////////////
138
139 // deprecated version of remote_port
140 unsigned short port(void) const;
141
142 ////////////////////////////////////////////////////////////////////////////
143 };
144
145 //////////////////////////////////////////////////////////////////////////////
146 // server class that does the listening on the designated port
147 // incoming connections can be queued up to a maximum queue length specified
148 // in the constructor/initialise
149
150 class TCP_server : protected IP_socket
151 {
152 public:
153
154 // create an uninitialised server
155 TCP_server(void);
156
157 // initialise a socket and set it up to be a listening port
158 // - port: port to listen on
159 // - queue: length of backlog queue to manage - may be zero
160 // - returns success status
161 TCP_server(unsigned short port, unsigned short queue = 0);
162
163 ////////////////////////////////////////////////////////////////////////////
164 // initialisation
165
166 // initialise a socket and set it up to be a listening port
167 // - port: port to listen on
168 // - queue: length of backlog queue to manage - may be zero
169 // - returns success status
170 bool initialise(unsigned short port, unsigned short queue = 0);
171
172 // test whether this is an initialised socket
173 // - returns whether this is initialised
174 // bool initialised(void) const;
175 using IP_socket::initialised;
176
177 // close, i.e. disconnect the socket
178 // - returns a success flag
179 // bool close(void);
180 using IP_socket::close;
181
182 //////////////////////////////////////////////////////////////////////////////
183 // server operation - accepting a connection
184
185 // test for a connection on the object's socket - only applicable if it has been set up as a listening port
186 // - timeout: how long to wait in microseconds if not connected yet
187 // - returns true if a connection is ready to be accepted
188 // bool accept_ready(unsigned timeout = 0);
189 using IP_socket::accept_ready;
190
191 // accept a connection on the object's socket - only applicable if it has been set up as a listening port
192 // - returns the connection as a new socket
193 TCP_connection accept(void);
194
195 ////////////////////////////////////////////////////////////////////////////
196 // error handling
197 // errors are set internally
198 // an error code of 0 is the test for no error, don't rely on the message being an empty string
199 // an error code != 0 means an error, then there will be a message explaining the error
200
201 // if an error is set it stays set - so you must clear it before further operations
202 // void clear_error (void) const;
203 using IP_socket::clear_error;
204
205 // get the error code of the last error
206 // int error(void) const;
207 using IP_socket::error;
208
209 // get the explanatory message of the last error
210 // std::string message(void) const;
211 using IP_socket::message;
212
213 //////////////////////////////////////////////////////////////////////////////
214
215 // deprecated versions of accept_ready and accept
216 bool connection_ready(unsigned timeout = 0);
217 TCP_connection connection(void);
218
219 //////////////////////////////////////////////////////////////////////////////
220 };
221
222 ////////////////////////////////////////////////////////////////////////////////
223 // Client Class: a client is simpler in that there is no listening port - you
224 // just create a connection and get on with it. Thus the client class does the
225 // whole job - create the connection and handle communications to/from it.
226 //
227 // Blocking mode: To use the client in blocking mode, use non-zero timeout for
228 // the initialisation method. In this mode, the connection operation must
229 // complete before the call will return or an error is indicated if the
230 // timeout is reached without completion. This usage was designed for
231 // applications which either just to TCP and nothing else or which do TCP
232 // operations in a separate thread.
233 //
234 // Non-blocking mode: To use the client in non-blocking mode, use a zero
235 // timeout for the initialisation method. Instead, you can ask it if it has
236 // connected once you've initialised it. It is not an error for it to be
237 // initialised but not connected. This usage was designed so that you can poll
238 // the connection periodically to implement a timeout for as long as you like for
239 // the connection to occur without blocking the thread that uses the client.
240 //
241 // In both modes, the send_ready/receive_ready methods can be called with any
242 // timeout including zero.
243
244 class TCP_client : protected IP_socket
245 {
246 public:
247
248 // create an uninitialised client
249 TCP_client(void);
250
251 // client connect to a server
252 // - remote_address: IP name (stlplus.sourceforge.net) or dotted number (216.34.181.96)
253 // - remote_port: port number of remote host
254 // - timeout: if 0, don't wait; if >0 wait for that microseconds for connection to be confirmed
255 TCP_client(const std::string& remote_address, unsigned short remote_port, unsigned timeout = 0);
256
257 // client connect to a server
258 // - remote_address: IP address as a long integer - generated by stlplus::ip_lookup
259 // - remote_port: port number of remote host
260 // - timeout: if 0, don't wait; if >0 wait for that microseconds for connection to be confirmed
261 TCP_client(unsigned long remote_address, unsigned short remote_port, unsigned timeout = 0);
262
263 ////////////////////////////////////////////////////////////////////////////
264 // initialisation, connection
265
266 // function for performing IP lookup (i.e. gethostbyname)
267 // could be standalone but making it a member means that it can use the socket's error handler
268 // i.e. if this fails, the sockets error code will be set - clear it to use the socket again
269 // - remote_address: IP name (stlplus.sourceforge.net) or dotted number (216.34.181.96)
270 // - returns the IP address as a long integer - zero if there's an error
271 // unsigned long ip_lookup(const std::string& remote_address);
272 using IP_socket::ip_lookup;
273
274 // client connect to a server
275 // - remote_address: IP name (stlplus.sourceforge.net) or dotted number (216.34.181.96)
276 // - remote_port: port number of remote host
277 // - timeout: if 0, don't wait; if >0 wait for that microseconds for connection to be confirmed
278 // - returns a success flag
279 bool initialise(const std::string& remote_address, unsigned short remote_port, unsigned timeout = 0);
280
281 // client connect to a server
282 // - remote_address: IP address as a long integer - generated by stlplus::ip_lookup
283 // - remote_port: port number of remote host
284 // - timeout: if 0, don't wait; if >0 wait for that microseconds for connection to be confirmed
285 // - returns a success flag
286 bool initialise(unsigned long remote_address, unsigned short remote_port, unsigned timeout = 0);
287
288 // test whether this is an initialised socket
289 // - returns whether this is initialised
290 // bool initialised(void) const;
291 using IP_socket::initialised;
292
293 // test whether a socket is connected and ready to communicate, returns on successful connect or timeout
294 // - timeout: how long to wait in microseconds if not connected yet
295 // - returns success flag
296 // bool connected(unsigned timeout = 0);
297 using IP_socket::connected;
298
299 // close, i.e. disconnect the socket
300 // - returns a success flag
301 // bool close(void);
302 using IP_socket::close;
303
304 ////////////////////////////////////////////////////////////////////////////
305 // sending/receiving
306
307 // test whether a socket is connected and ready to send data, returns if ready or on timeout
308 // - timeout: how long to wait in microseconds if not connected yet (blocking)
309 // - returns status
310 // bool send_ready(unsigned timeout = 0);
311 using IP_socket::send_ready;
312
313 // send data through the socket - if the data is long only part of it may
314 // be sent. The sent part is removed from the data, so the same string can
315 // be sent again and again until it is empty.
316 // - data: string containing data to be sent - any data successfully sent is removed
317 // - returns success flag
318 // bool send (std::string& data);
319 using IP_socket::send;
320
321 // test whether a socket is connected and ready to receive data, returns if ready or on timeout
322 // - timeout: how long to wait in microseconds if not connected yet (blocking)
323 // - returns status
324 // bool receive_ready(unsigned timeout = 0);
325 using IP_socket::receive_ready;
326
327 // receive data through the socket - if the data is long only part of it
328 // may be received. The received data is appended to the string, building
329 // it up in stages, so the same string can be received again and again
330 // until all information has been received.
331 // - data: string receiving data from socket - any data successfully received is appended
332 // - returns success flag
333 // bool receive (std::string& data);
334 using IP_socket::receive;
335
336 ////////////////////////////////////////////////////////////////////////////
337 // informational
338
339 // the local port number of the connection
340 // - returns the port number, 0 if not bound to a port
341 // unsigned short local_port(void) const;
342 using IP_socket::local_port;
343
344 // the remote address of the connection
345 // - returns the address, 0 if not connected
346 // unsigned long remote_address(void) const;
347 using IP_socket::remote_address;
348
349 // the remote port number of the connection
350 // - returns the port number, 0 if not connected to a port
351 // unsigned short remote_port(void) const;
352 using IP_socket::remote_port;
353
354 ////////////////////////////////////////////////////////////////////////////
355 // error handling
356 // errors are set internally
357 // an error code of 0 is the test for no error, don't rely on the message being an empty string
358 // an error code != 0 means an error, then there will be a message explaining the error
359
360 // if an error is set it stays set - so you must clear it before further operations
361 // void clear_error (void) const;
362 using IP_socket::clear_error;
363
364 // get the error code of the last error
365 // int error(void) const;
366 using IP_socket::error;
367
368 // get the explanatory message of the last error
369 // std::string message(void) const;
370 using IP_socket::message;
371
372 //////////////////////////////////////////////////////////////////////////////
373
374 // deprecated versions
375 unsigned long address(void) const;
376 unsigned short port(void) const;
377
378 //////////////////////////////////////////////////////////////////////////////
379 };
380
381 ////////////////////////////////////////////////////////////////////////////////
382
383 } // end namespace stlplus
384
385 #endif
This page took 0.048515 seconds and 4 git commands to generate.