1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 | #ifndef STLPLUS_IP_SOCKET #define STLPLUS_IP_SOCKET //////////////////////////////////////////////////////////////////////////////// // Author: Andy Rushton // Copyright: (c) Southampton University 1999-2004 // (c) Andy Rushton 2004 onwards // License: BSD License, see ../docs/license.html // A platform-independent (Unix and Windows anyway) interface to Internet-Protocol sockets //////////////////////////////////////////////////////////////////////////////// #include "portability_fixes.hpp" #include <string> namespace stlplus { ////////////////////////////////////////////////////////////////////////////// // internals // use a PIMPL interface to hide the platform-specifics in the implementation class IP_socket_internals; //////////////////////////////////////////////////////////////////////////// // Types of socket supported enum IP_socket_type {undefined_socket_type = -1, TCP = 0, UDP = 1}; ////////////////////////////////////////////////////////////////////////////// // Socket class class IP_socket { public : //////////////////////////////////////////////////////////////////////////// // constructors/destructors // create an uninitialised socket IP_socket( void ); // create an initialised socket // - type: create either a TCP or UDP socket IP_socket(IP_socket_type type); // destroy the socket, closing it if open ~IP_socket( void ); // copying is implemented as aliasing IP_socket( const IP_socket&); IP_socket& operator =( const IP_socket&); //////////////////////////////////////////////////////////////////////////// // initialisation // initialise the socket // - type: create either a TCP or UDP socket // - returns success status bool initialise(IP_socket_type type); // test whether this is an initialised socket // - returns whether this is initialised bool initialised( void ) const ; // close, i.e. disconnect the socket // - returns a success flag bool close( void ); ////////////////////////////////////////////////////////////////////////////// // Socket configuration // function for performing IP lookup (i.e. gethostbyname) // could be standalone but making it a member means that it can use the socket's error handler // i.e. if this fails, the sockets error code will be set - clear it to use the socket again // - remote_address: IP name (stlplus.sourceforge.net) or dotted number (216.34.181.96) // - returns the IP address as a long integer - zero if there's an error unsigned long ip_lookup( const std:: string & remote_address); // test whether a socket is ready to communicate // - readable: test whether socket is ready to read // - writeable: test whether a socket is ready to write // - timeout: if socket is not ready, time to wait before giving up - in micro-seconds - 0 means don't wait // returns false if not ready or error - use error() method to tell - true if ready bool select( bool readable, bool writeable, unsigned timeout = 0); // bind the socket to a port so that it can receive from specific address - typically used by a client // - remote_address: IP number of remote server to send/receive to/from // - local_port: port on local machine to bind to the address // - returns success flag bool bind( unsigned long remote_address, unsigned short local_port); // bind the socket to a port so that it can receive from any address - typically used by a server // - local_port: port on local machine to bind to the address // - returns success flag bool bind_any( unsigned short local_port); // set this socket up to be a listening port // socket must be bound to a port already // - queue: length of backlog queue to manage - may be zero meaning no queue // - returns success status bool listen( unsigned short queue = 0); // test for a connection on the socket // only applicable if it has been set up as a listening port // - timeout: how long to wait in microseconds if not connected yet // - returns true if a connection is ready to be accepted bool accept_ready( unsigned timeout = 0) const ; // accept a connection on the socket // only applicable if it has been set up as a listening port // - returns the connection as a new socket IP_socket accept( void ); // create a connection - usually used by a client // TCP: client connect to a remote server // UDP: setup remote address and port for sends // - remote_address: IP number already looked up using ip_lookup // - remote_port: port to connect to // - returns a success flag bool connect( unsigned long remote_address, unsigned short remote_port); // test whether a socket is connected and ready to communicate, returns on successful connect or timeout // - timeout: how long to wait in microseconds if not connected yet // - returns true if connected and ready to communicate, false if not ready or error bool connected( unsigned timeout = 0); //////////////////////////////////////////////////////////////////////////// // sending/receiving // test whether a socket is connected and ready to send data, returns if ready or on timeout // - timeout: how long to wait in microseconds if not connected yet (blocking) // - returns status bool send_ready( unsigned timeout = 0); // send data through a connection-based (TCP) socket // if the data is long only part of it may be sent. The sent part is // removed from the data, so the same string can be sent again and again // until it is empty. // - data: string containing data to be sent - any data successfully sent is removed // - returns success flag bool send(std:: string & data); // send data through a connectionless (UDP) socket // the data will be sent as a single packet // - packet: string containing data to be sent - any data successfully sent is removed // - remote_address: address of the remote host to send to - optional if the socket has been connected to remote // - remote_port: port of the remote host to send to - optional if the socket has been connected to remote // - returns success flag bool send_packet(std:: string & packet, unsigned long remote_address, unsigned short remote_port); // send data through a connectionless (UDP) socket // the data will be sent as a single packet // only works if the socket has been connected to remote // - packet: string containing data to be sent - any data successfully sent is removed // - returns success flag bool send_packet(std:: string & packet); // test whether a socket is connected and ready to receive data, returns if ready or on timeout // - timeout: how long to wait in microseconds if not connected yet (blocking) // - returns status bool receive_ready( unsigned wait = 0); // receive data through a connection-based (TCP) socket // if the data is long only part of it may be received. The received data // is appended to the string, building it up in stages, so the same string // can be received again and again until all information has been // received. // - data: string receiving data from socket - any data successfully received is appended // - returns success flag bool receive(std:: string & data); // receive data through a connectionless (UDP) socket // - packet: string receiving data from socket - any data successfully received is appended // - remote_address: returns the address of the remote host received from // - remote_port: returns the port of the remote host received from // - returns success flag bool receive_packet(std:: string & packet, unsigned long & remote_address, unsigned short & remote_port); // variant of above which does not give back the address and port of the sender // receive data through a connectionless (UDP) socket // - packet: string receiving data from socket - any data successfully received is appended // - returns success flag bool receive_packet(std:: string & packet); //////////////////////////////////////////////////////////////////////////// // informational // gets the type of socket // - returns undefined_socket_type, TCP or UDP IP_socket_type type( void ) const ; // the local port number of the connection // returns the port number, 0 if not bound to a port unsigned short local_port( void ) const ; // the remote address of the connection // returns the address, 0 if not connected unsigned long remote_address( void ) const ; // the remote port number of the connection // returns the port number, 0 if not connected to a port unsigned short remote_port( void ) const ; //////////////////////////////////////////////////////////////////////////// // error handling // errors are set internally // an error code of 0 is the test for no error, don't rely on the message being an empty string // an error code != 0 means an error, then there will be a message explaining the error // indicate an error - mostly used internally, you can set your own errors - use a negative code void set_error ( int error, const std:: string & message) const ; // if an error is set it stays set - so you must clear it before further operations void clear_error ( void ) const ; // get the error code of the last error int error( void ) const ; // get the explanatory message of the last error std:: string message( void ) const ; //////////////////////////////////////////////////////////////////////////// private : friend class IP_socket_internals; IP_socket_internals* m_impl; }; } // end namespace stlplus #endif |