tcp.hpp
1: #ifndef TCP_HPP
2: #define TCP_HPP
3: /*------------------------------------------------------------------------------
4:
5: Author: Andy Rushton
6: Copyright: (c) Andy Rushton, 2004
7: License: BSD License, see ../docs/license.html
8:
9: A platform-independent (Unix and Windows anyway) interface to TCP
10:
11: ------------------------------------------------------------------------------*/
12: #include "os_fixes.hpp"
13: #include "smart_ptr.hpp"
14: #include <string>
15:
16: ////////////////////////////////////////////////////////////////////////////////
17: // Internals
18:
19: class TCP_connection_data;
20: class TCP_server_data;
21: class TCP_client_data;
22:
23: ////////////////////////////////////////////////////////////////////////////////
24: // Server Classes: A server creates a listening port which waits for incoming
25: // connections. This is placed on the port number appropriate for the service
26: // - for example, a Telnet server would typically use port 23. For a new
27: // service you should of course use any port not allocated to a standard
28: // service. I believe that RFC 1700 defines the standard service port numbers.
29: // When an incoming connection is made, the server accepts it and in the
30: // process creates a new connection on a different port. This leaves the
31: // standard port listening for further connections. In effect, the server
32: // farms out the handling of the connections themselves and only takes
33: // responsibility for accepting the connection. This is reflected in the class
34: // structure. A TCP_server performs the listening and accepting roles, but
35: // creates a TCP_connection to handle the accepted connection.
36:
37: class TCP_connection
38: {
39: public:
40: TCP_connection(void);
41: ~TCP_connection(void);
42:
43: TCP_connection(const TCP_connection&);
44: TCP_connection& operator=(const TCP_connection&);
45:
46: int error(void) const;
47: std::string message(void) const;
48: bool initialised(void) const;
49: unsigned long address(void) const;
50: unsigned short port(void) const;
51: bool send_ready(unsigned wait);
52: bool send (std::string& data);
53: bool receive_ready(unsigned wait);
54: bool receive (std::string& data);
55: bool close(void);
56:
57: protected:
58: friend class TCP_connection_data;
59: friend class TCP_server_data;
60: smart_ptr<TCP_connection_data> m_data;
61: };
62:
63: class TCP_server
64: {
65: public:
66: TCP_server(void);
67: TCP_server(unsigned short port, unsigned short queue);
68: ~TCP_server(void);
69:
70: TCP_server(const TCP_server&);
71: TCP_server& operator=(const TCP_server&);
72:
73: bool initialise(unsigned short port, unsigned short queue);
74: bool initialised(void) const;
75: int error(void) const;
76: std::string message(void) const;
77: bool close(void);
78:
79: bool connection_ready(unsigned wait);
80: TCP_connection connection(void);
81:
82: private:
83: friend class TCP_server_data;
84: smart_ptr<TCP_server_data> m_data;
85: };
86:
87: ////////////////////////////////////////////////////////////////////////////////
88: // Client Class: a client is simpler in that there is no listening port - you
89: // just create a connection and get on with it. Thus the client class does the
90: // whole job - create the connection and handle communications to/from it.
91: //
92: // Blocking mode: To use the client in blocking mode, use non-zero timeout for
93: // the initialisation method. In this mode, the connection operation must
94: // complete before the call will return or an error is indicated if the
95: // timeout is reached without completion. This usage was designed for
96: // applications which either just to TCP and nothing else or which do TCP
97: // operations in a separate thread.
98: //
99: // Non-blocking mode: To use the client in non-blocking mode, use a zero
100: // timeout for the initialisation method. Instead, you can ask it if it has
101: // connected once you've initialised it. It is not an error for it to be
102: // initialised but not connected. This usage was designed so that you can poll
103: // the connection periodically to implement a wait for as long as you like for
104: // the connection to occur without blocking the thread that uses the client.
105: //
106: // In both modes, the send_ready/receive_ready methods can be called with any
107: // timeout including zero.
108:
109: class TCP_client
110: {
111: public:
112: TCP_client(void);
113: TCP_client(const std::string& address, unsigned short port, unsigned int timeout=0);
114: ~TCP_client(void);
115:
116: TCP_client(const TCP_client&);
117: TCP_client& operator=(const TCP_client&);
118:
119: int error(void) const;
120: std::string message(void) const;
121: bool initialise(const std::string& address, unsigned short port, unsigned int timeout=0);
122: bool initialised(void) const;
123: bool connected(void);
124: unsigned long address(void) const;
125: unsigned short port(void) const;
126: bool send_ready(unsigned wait = 0);
127: bool send (std::string& data);
128: bool receive_ready(unsigned wait = 0);
129: bool receive (std::string& data);
130: bool close(void);
131:
132: private:
133: friend class TCP_client_data;
134: smart_ptr<TCP_client_data> m_data;
135: };
136:
137: ////////////////////////////////////////////////////////////////////////////////
138: #endif