]> Dogcows Code - chaz/yoink/blobdiff - src/stlplus/portability/tcp_sockets.hpp
testing new non-autotools build system
[chaz/yoink] / src / stlplus / portability / tcp_sockets.hpp
diff --git a/src/stlplus/portability/tcp_sockets.hpp b/src/stlplus/portability/tcp_sockets.hpp
new file mode 100644 (file)
index 0000000..94b98c5
--- /dev/null
@@ -0,0 +1,385 @@
+#ifndef STLPLUS_TCP_SOCKET\r
+#define STLPLUS_TCP_SOCKET\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+//   Author:    Andy Rushton\r
+//   Copyright: (c) Southampton University 1999-2004\r
+//              (c) Andy Rushton           2004-2009\r
+//   License:   BSD License, see ../docs/license.html\r
+\r
+//   A platform-independent (Unix and Windows anyway) interface to TCP sockets\r
+\r
+////////////////////////////////////////////////////////////////////////////////\r
+\r
+#include "portability_fixes.hpp"\r
+#include "ip_sockets.hpp"\r
+#include <string>\r
+\r
+namespace stlplus\r
+{\r
+\r
+  //////////////////////////////////////////////////////////////////////////////\r
+  // Server Classes: A server creates a listening port which waits for incoming\r
+  // connections. This is placed on the port number appropriate for the service\r
+  // - for example, a Telnet server would typically use port 23. For a new\r
+  // service you should of course use any port not allocated to a standard\r
+  // service. I believe that RFC 1700 defines the standard service port numbers.\r
+  // When an incoming connection is made, the server accepts it and in the\r
+  // process creates a new connection on a different port. This leaves the\r
+  // standard port listening for further connections. In effect, the server\r
+  // farms out the handling of the connections themselves and only takes\r
+  // responsibility for accepting the connection. This is reflected in the class\r
+  // structure. A TCP_server performs the listening and accepting roles, but\r
+  // creates a TCP_connection to handle the accepted connection.\r
+  //////////////////////////////////////////////////////////////////////////////\r
+\r
+  //////////////////////////////////////////////////////////////////////////////\r
+  // connection class created by TCP_server when a connection is accepted\r
+  // this is then used to perform any communications with the remote client\r
+\r
+  class TCP_connection : protected IP_socket\r
+  {\r
+  private:\r
+    // constructor to actually initialise the class - can only be constructed by TCP_server\r
+    friend class TCP_server;\r
+    TCP_connection(const IP_socket& socket);\r
+\r
+  public:\r
+\r
+    ////////////////////////////////////////////////////////////////////////////\r
+    // constructors/destructors\r
+\r
+    // create an uninitialised connection\r
+    TCP_connection(void);\r
+\r
+    ////////////////////////////////////////////////////////////////////////////\r
+    // initialisation, connection control\r
+    // Note: TCP connections can only be initialised by a TCP server\r
+\r
+    // test whether this is an initialised socket\r
+    // - returns whether this is initialised\r
+    // bool initialised(void) const;\r
+    using IP_socket::initialised;\r
+\r
+    // close, i.e. disconnect the socket\r
+    // - returns a success flag\r
+    // bool close(void);\r
+    using IP_socket::close;\r
+\r
+    ////////////////////////////////////////////////////////////////////////////\r
+    // sending/receiving\r
+\r
+    // test whether a socket is connected and ready to send data, returns if ready or on timeout\r
+    // - timeout: how long to wait in microseconds if not connected yet (blocking)\r
+    // - returns status\r
+    // bool send_ready(unsigned timeout = 0);\r
+    using IP_socket::send_ready;\r
+\r
+    // send data through the socket - if the data is long only part of it may\r
+    // be sent. The sent part is removed from the data, so the same string can\r
+    // be sent again and again until it is empty.\r
+    // - data: string containing data to be sent - any data successfully sent is removed\r
+    // - returns success flag\r
+    // bool send (std::string& data);\r
+    using IP_socket::send;\r
+\r
+    // test whether a socket is connected and ready to receive data, returns if ready or on timeout\r
+    // - timeout: how long to wait in microseconds if not connected yet (blocking)\r
+    // - returns status\r
+    // bool receive_ready(unsigned timeout = 0);\r
+    using IP_socket::receive_ready;\r
+\r
+    // receive data through the socket - if the data is long only part of it\r
+    // may be received. The received data is appended to the string, building\r
+    // it up in stages, so the same string can be received again and again\r
+    // until all information has been received.\r
+    // - data: string receiving data from socket - any data successfully received is appended\r
+    // - returns success flag\r
+    // bool receive (std::string& data);\r
+    using IP_socket::receive;\r
+\r
+    ////////////////////////////////////////////////////////////////////////////\r
+    // informational\r
+\r
+    // the local port number of the connection\r
+    // - returns the port number, 0 if not bound to a port\r
+    // unsigned short local_port(void) const;\r
+    using IP_socket::local_port;\r
+\r
+    // the remote address of the connection\r
+    // - returns the address, 0 if not connected\r
+    // unsigned long remote_address(void) const;\r
+    using IP_socket::remote_address;\r
+\r
+    // the remote port number of the connection\r
+    // - returns the port number, 0 if not connected to a port\r
+    // unsigned short remote_port(void) const;\r
+    using IP_socket::remote_port;\r
+\r
+    ////////////////////////////////////////////////////////////////////////////\r
+    // error handling\r
+    // errors are set internally\r
+    // an error code of 0 is the test for no error, don't rely on the message being an empty string\r
+    // an error code != 0 means an error, then there will be a message explaining the error\r
+\r
+    // if an error is set it stays set - so you must clear it before further operations\r
+    // void clear_error(void) const;\r
+    using IP_socket::clear_error;\r
+\r
+    // get the error code of the last error\r
+    // int error(void) const;\r
+    using IP_socket::error;\r
+\r
+    // get the explanatory message of the last error\r
+    // std::string message(void) const;\r
+    using IP_socket::message;\r
+\r
+    ////////////////////////////////////////////////////////////////////////////\r
+\r
+    // deprecated version of remote_port\r
+    unsigned short port(void) const;\r
+\r
+    ////////////////////////////////////////////////////////////////////////////\r
+  };\r
+\r
+  //////////////////////////////////////////////////////////////////////////////\r
+  // server class that does the listening on the designated port\r
+  // incoming connections can be queued up to a maximum queue length specified\r
+  // in the constructor/initialise\r
+\r
+  class TCP_server : protected IP_socket\r
+  {\r
+  public:\r
+\r
+    // create an uninitialised server\r
+    TCP_server(void);\r
+\r
+    // initialise a socket and set it up to be a listening port\r
+    // - port: port to listen on\r
+    // - queue: length of backlog queue to manage - may be zero\r
+    // - returns success status\r
+    TCP_server(unsigned short port, unsigned short queue = 0);\r
+\r
+    ////////////////////////////////////////////////////////////////////////////\r
+    // initialisation\r
+\r
+    // initialise a socket and set it up to be a listening port\r
+    // - port: port to listen on\r
+    // - queue: length of backlog queue to manage - may be zero\r
+    // - returns success status\r
+    bool initialise(unsigned short port, unsigned short queue = 0);\r
+\r
+    // test whether this is an initialised socket\r
+    // - returns whether this is initialised\r
+    // bool initialised(void) const;\r
+    using IP_socket::initialised;\r
+\r
+    // close, i.e. disconnect the socket\r
+    // - returns a success flag\r
+    // bool close(void);\r
+    using IP_socket::close;\r
+\r
+    //////////////////////////////////////////////////////////////////////////////\r
+    // server operation - accepting a connection\r
+\r
+    // test for a connection on the object's socket - only applicable if it has been set up as a listening port\r
+    // - timeout: how long to wait in microseconds if not connected yet\r
+    // - returns true if a connection is ready to be accepted\r
+    // bool accept_ready(unsigned timeout = 0);\r
+    using IP_socket::accept_ready;\r
+\r
+    // accept a connection on the object's socket - only applicable if it has been set up as a listening port\r
+    // - returns the connection as a new socket\r
+    TCP_connection accept(void);\r
+\r
+    ////////////////////////////////////////////////////////////////////////////\r
+    // error handling\r
+    // errors are set internally\r
+    // an error code of 0 is the test for no error, don't rely on the message being an empty string\r
+    // an error code != 0 means an error, then there will be a message explaining the error\r
+\r
+    // if an error is set it stays set - so you must clear it before further operations\r
+    // void clear_error (void) const;\r
+    using IP_socket::clear_error;\r
+\r
+    // get the error code of the last error\r
+    // int error(void) const;\r
+    using IP_socket::error;\r
+\r
+    // get the explanatory message of the last error\r
+    // std::string message(void) const;\r
+    using IP_socket::message;\r
+\r
+    //////////////////////////////////////////////////////////////////////////////\r
+\r
+    // deprecated versions of accept_ready and accept\r
+    bool connection_ready(unsigned timeout = 0);\r
+    TCP_connection connection(void);\r
+\r
+    //////////////////////////////////////////////////////////////////////////////\r
+  };\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+  // Client Class: a client is simpler in that there is no listening port - you\r
+  // just create a connection and get on with it. Thus the client class does the\r
+  // whole job - create the connection and handle communications to/from it.\r
+  //\r
+  // Blocking mode: To use the client in blocking mode, use non-zero timeout for\r
+  // the initialisation method. In this mode, the connection operation must\r
+  // complete before the call will return or an error is indicated if the\r
+  // timeout is reached without completion. This usage was designed for\r
+  // applications which either just to TCP and nothing else or which do TCP\r
+  // operations in a separate thread.\r
+  //\r
+  // Non-blocking mode: To use the client in non-blocking mode, use a zero\r
+  // timeout for the initialisation method. Instead, you can ask it if it has\r
+  // connected once you've initialised it. It is not an error for it to be\r
+  // initialised but not connected. This usage was designed so that you can poll\r
+  // the connection periodically to implement a timeout for as long as you like for\r
+  // the connection to occur without blocking the thread that uses the client.\r
+  //\r
+  // In both modes, the send_ready/receive_ready methods can be called with any\r
+  // timeout including zero.\r
+\r
+  class TCP_client : protected IP_socket\r
+  {\r
+  public:\r
+\r
+    // create an uninitialised client\r
+    TCP_client(void);\r
+\r
+    // client connect to a server\r
+    // - remote_address: IP name (stlplus.sourceforge.net) or dotted number (216.34.181.96)\r
+    // - remote_port: port number of remote host\r
+    // - timeout: if 0, don't wait; if >0 wait for that microseconds for connection to be confirmed\r
+    TCP_client(const std::string& remote_address, unsigned short remote_port, unsigned timeout = 0);\r
+\r
+    // client connect to a server\r
+    // - remote_address: IP address as a long integer - generated by stlplus::ip_lookup\r
+    // - remote_port: port number of remote host\r
+    // - timeout: if 0, don't wait; if >0 wait for that microseconds for connection to be confirmed\r
+    TCP_client(unsigned long remote_address, unsigned short remote_port, unsigned timeout = 0);\r
+\r
+    ////////////////////////////////////////////////////////////////////////////\r
+    // initialisation, connection\r
+\r
+    // function for performing IP lookup (i.e. gethostbyname)\r
+    // could be standalone but making it a member means that it can use the socket's error handler\r
+    // i.e. if this fails, the sockets error code will be set - clear it to use the socket again\r
+    // - remote_address: IP name (stlplus.sourceforge.net) or dotted number (216.34.181.96)\r
+    // - returns the IP address as a long integer - zero if there's an error\r
+    // unsigned long ip_lookup(const std::string& remote_address);\r
+    using IP_socket::ip_lookup;\r
+\r
+    // client connect to a server\r
+    // - remote_address: IP name (stlplus.sourceforge.net) or dotted number (216.34.181.96)\r
+    // - remote_port: port number of remote host\r
+    // - timeout: if 0, don't wait; if >0 wait for that microseconds for connection to be confirmed\r
+    // - returns a success flag\r
+    bool initialise(const std::string& remote_address, unsigned short remote_port, unsigned timeout = 0);\r
+\r
+    // client connect to a server\r
+    // - remote_address: IP address as a long integer - generated by stlplus::ip_lookup\r
+    // - remote_port: port number of remote host\r
+    // - timeout: if 0, don't wait; if >0 wait for that microseconds for connection to be confirmed\r
+    // - returns a success flag\r
+    bool initialise(unsigned long remote_address, unsigned short remote_port, unsigned timeout = 0);\r
+\r
+    // test whether this is an initialised socket\r
+    // - returns whether this is initialised\r
+    // bool initialised(void) const;\r
+    using IP_socket::initialised;\r
+\r
+    // test whether a socket is connected and ready to communicate, returns on successful connect or timeout\r
+    // - timeout: how long to wait in microseconds if not connected yet\r
+    // - returns success flag\r
+    // bool connected(unsigned timeout = 0);\r
+    using IP_socket::connected;\r
+\r
+    // close, i.e. disconnect the socket\r
+    // - returns a success flag\r
+    // bool close(void);\r
+    using IP_socket::close;\r
+\r
+    ////////////////////////////////////////////////////////////////////////////\r
+    // sending/receiving\r
+\r
+    // test whether a socket is connected and ready to send data, returns if ready or on timeout\r
+    // - timeout: how long to wait in microseconds if not connected yet (blocking)\r
+    // - returns status\r
+    // bool send_ready(unsigned timeout = 0);\r
+    using IP_socket::send_ready;\r
+\r
+    // send data through the socket - if the data is long only part of it may\r
+    // be sent. The sent part is removed from the data, so the same string can\r
+    // be sent again and again until it is empty.\r
+    // - data: string containing data to be sent - any data successfully sent is removed\r
+    // - returns success flag\r
+    // bool send (std::string& data);\r
+    using IP_socket::send;\r
+\r
+    // test whether a socket is connected and ready to receive data, returns if ready or on timeout\r
+    // - timeout: how long to wait in microseconds if not connected yet (blocking)\r
+    // - returns status\r
+    // bool receive_ready(unsigned timeout = 0);\r
+    using IP_socket::receive_ready;\r
+\r
+    // receive data through the socket - if the data is long only part of it\r
+    // may be received. The received data is appended to the string, building\r
+    // it up in stages, so the same string can be received again and again\r
+    // until all information has been received.\r
+    // - data: string receiving data from socket - any data successfully received is appended\r
+    // - returns success flag\r
+    // bool receive (std::string& data);\r
+    using IP_socket::receive;\r
+\r
+    ////////////////////////////////////////////////////////////////////////////\r
+    // informational\r
+\r
+    // the local port number of the connection\r
+    // - returns the port number, 0 if not bound to a port\r
+    // unsigned short local_port(void) const;\r
+    using IP_socket::local_port;\r
+\r
+    // the remote address of the connection\r
+    // - returns the address, 0 if not connected\r
+    // unsigned long remote_address(void) const;\r
+    using IP_socket::remote_address;\r
+\r
+    // the remote port number of the connection\r
+    // - returns the port number, 0 if not connected to a port\r
+    // unsigned short remote_port(void) const;\r
+    using IP_socket::remote_port;\r
+\r
+    ////////////////////////////////////////////////////////////////////////////\r
+    // error handling\r
+    // errors are set internally\r
+    // an error code of 0 is the test for no error, don't rely on the message being an empty string\r
+    // an error code != 0 means an error, then there will be a message explaining the error\r
+\r
+    // if an error is set it stays set - so you must clear it before further operations\r
+    // void clear_error (void) const;\r
+    using IP_socket::clear_error;\r
+\r
+    // get the error code of the last error\r
+    // int error(void) const;\r
+    using IP_socket::error;\r
+\r
+    // get the explanatory message of the last error\r
+    // std::string message(void) const;\r
+    using IP_socket::message;\r
+\r
+    //////////////////////////////////////////////////////////////////////////////\r
+\r
+    // deprecated versions\r
+    unsigned long address(void) const;\r
+    unsigned short port(void) const;\r
+\r
+    //////////////////////////////////////////////////////////////////////////////\r
+  };\r
+\r
+  ////////////////////////////////////////////////////////////////////////////////\r
+\r
+} // end namespace stlplus\r
+\r
+#endif\r
This page took 0.027434 seconds and 4 git commands to generate.