Line data Source code
1 : /// Socket.hpp
2 : ///
3 : /// @author Paul Grenz
4 : ///
5 : /// The "SystemSocket" class wraps the basic socket functionality as
6 : /// exposed by the system.
7 : ///
8 : ////////////////////////////////////////////////////////////////////////////////
9 :
10 : #ifndef PCF_SYSTEM_SOCKET_HPP
11 : #define PCF_SYSTEM_SOCKET_HPP
12 :
13 : #include <stdexcept>
14 : #include <exception>
15 : #include <errno.h>
16 : #include <string>
17 : #include <vector>
18 : #ifdef WIN32
19 : #include <winsock2.h>
20 : #else
21 : #include <sys/socket.h>
22 : #include <netinet/in.h>
23 : #include <netdb.h>
24 : #include <arpa/inet.h>
25 : #include <fcntl.h>
26 : #endif
27 :
28 : namespace pcf
29 : {
30 : class SystemSocket
31 : {
32 : // We have a special exception defined here.
33 : public:
34 : class Error : public std::runtime_error
35 : {
36 : public:
37 0 : Error( const std::string &szMsg ) : std::runtime_error( szMsg ) {}
38 : };
39 :
40 : // This class holds some information about an interface.
41 : public:
42 : class Interface
43 : {
44 : public:
45 0 : Interface( const std::string &szName, const std::string &szIp,
46 : const std::string &szBroadcast )
47 0 : : m_szName( szName ), m_szIp( szIp ), m_szBroadcast( szBroadcast ) {}
48 0 : ~Interface() {}
49 0 : std::string getName() const
50 : {
51 0 : return m_szName;
52 : }
53 : std::string getIp() const
54 : {
55 : return m_szIp;
56 : }
57 : std::string getBroadcast() const
58 : {
59 : return m_szBroadcast;
60 : }
61 : private:
62 : std::string m_szName;
63 : std::string m_szIp;
64 : std::string m_szBroadcast;
65 : };
66 :
67 : // Constants.
68 : public:
69 : enum Type
70 : {
71 : UnknownType = -1,
72 : Stream = 0,
73 : Datagram = 1,
74 : enumMulticast = 2
75 : };
76 :
77 : enum
78 : {
79 : enumMaxHostName = 1024,
80 : enumMaxConnections = 1024,
81 : enumMaxRecv = 2048
82 : };
83 : /*
84 : enum Error
85 : {
86 : // The 'no error' value must stay 0
87 : // to be compatible with the system errors.
88 : enumNoError = 0,
89 : enumAlreadyBound = -EEXIST,
90 : enumAddressInUse = -EADDRINUSE,
91 : enumAddressNotAvailable = -EADDRNOTAVAIL,
92 : enumAddressNotSupported = -EAFNOSUPPORT,
93 : enumAlreadyConnected = -EISCONN,
94 : enumBusy = -EBUSY,
95 : enumConnectionAborted = -ECONNABORTED,
96 : enumConnectionBusy = -EINPROGRESS,
97 : enumConnectionInProgress = -EALREADY,
98 : enumConnectionRefused = -ECONNREFUSED,
99 : enumDescriptorNotSocket = -ENOTSOCK,
100 : enumEmptyPathname = -EISDIR,
101 : enumHostUnreachable = -EHOSTUNREACH,
102 : enumInterruptRecv = -EINTR,
103 : enumInvalidParameter = -EINVAL,
104 : enumInvalidSocketDescriptor = -EBADF,
105 : enumIoError = -EIO,
106 : enumLocalShutdown = -EPIPE,
107 : enumMaxDescriptorsUsed = -EMFILE,
108 : enumMessageTooBig = -EDQUOT,
109 : enumNetworkDown = -ENETDOWN,
110 : enumNetworkUnreachable = -ENETUNREACH,
111 : enumNoAccess = -EACCES,
112 : enumNoBuffers = -ENOBUFS,
113 : enumNoOobData = -ENODATA,
114 : enumNotConnected = -ENOTCONN,
115 : enumNotEnoughMemory = -ENOMEM,
116 : enumOperationNotSupported = -EOPNOTSUPP,
117 : enumPartialDataRecv = -EFBIG,
118 : enumPartialDataSent = -EMSGSIZE,
119 : enumPathDoesNotExist = -ENOENT,
120 : enumPathIsNotDirectory = -ENOTDIR,
121 : enumPathNameTooLong = -ENAMETOOLONG,
122 : enumPeerShutdown = -ECONNRESET,
123 : enumProtocolError = -EPROTO,
124 : enumReadOnlyFileSystem = -EROFS,
125 : enumSocketAlreadyConnected = -EISCONN,
126 : enumSocketNotBound = -EDESTADDRREQ,
127 : enumSymbolicLoopExists = -ELOOP,
128 : enumTimeoutFieldTooBig = -EDOM,
129 : enumTimedOut = -ETIMEDOUT,
130 : enumWouldBlock = -EAGAIN,
131 : enumWrongAddressType = -EPROTOTYPE,
132 : enumUnknownError = -999999
133 : };
134 : */
135 : // Constructor/destructor
136 : public:
137 : SystemSocket();
138 : SystemSocket( const Type &tType,
139 : const int &nPort,
140 : const std::string &szHost );
141 : virtual ~SystemSocket();
142 : SystemSocket( const SystemSocket &rhs );
143 : const SystemSocket &operator= ( const SystemSocket &rhs );
144 :
145 : // Methods
146 : public:
147 : virtual void accept( SystemSocket &socNew );
148 : virtual void bind();
149 : virtual void close();
150 : virtual void connect();
151 : static sockaddr_in convertStrToAddr( const std::string &szHost );
152 : virtual void create();
153 : /// This function creates a sockaddr_in struct based on the arguments.
154 : static sockaddr_in createSockAddr( const int &nPort,
155 : const std::string &szHost = std::string( "" ) );
156 : /// Disables the algorithm that conglomerates lots of
157 : /// small sends into a large one.
158 : void disableNagle( const bool &oDisable );
159 : /// Returns the socket descriptor.
160 : int getFd() const;
161 : /// Returns the host set in the constructor.
162 : std::string getHost() const;
163 : /// Get the interface named 'szName'.
164 : static Interface getInterface( const std::string &szName );
165 : // This returns the local interfaces as a vector.
166 : /// The return value is the number of interfaces found.
167 : static int getInterfaces( std::vector<Interface> &vecInterfaces );
168 : /// This is the last error that occurred when manipluating the socket.
169 : int getLastError() const;
170 : virtual void listen();
171 : /// Gets the standard host name for the current machine.
172 : static std::string getLocalHostName();
173 : /// Returns the option set for the socket.
174 : void getOption( const int &nLevel,
175 : const int &nOption,
176 : void *pvOptionValue,
177 : socklen_t &nOptionLength );
178 : /// Returns the port set in the constructor.
179 : int getPort() const;
180 : /// Returns the type set in the constructor.
181 : Type getType() const;
182 : /// Returns true if the socket is bound to a port.
183 : bool isBound() const;
184 : /// Returns true if the nagle algorithm is disabled, false otherwise.
185 : bool isNagleDisabled() const;
186 : /// Returns true if the listen or connect was successful, false otherwise.
187 : bool isValid() const;
188 : virtual void join();
189 : virtual std::string recv();
190 : virtual std::string recvFrom();
191 : virtual void recvChunk( char *pcData,
192 : int &nNumBytes );
193 : /// Receives a fixed-size chunk. Returns any error encountered. nNumBytes will
194 : /// be modified to reflect the number of bytes received.
195 : virtual void recvChunkFrom( char *pcData,
196 : int &nNumBytes );
197 : virtual void send( const std::string &szData );
198 : virtual void sendTo( const std::string &szData );
199 : virtual void sendChunk( char *pcData,
200 : int &nNumBytes );
201 : virtual void sendChunkTo( char *pcData,
202 : int &nNumBytes );
203 : /// Set the connect timeout in milliseconds.
204 : void setConnectTimeout( const int &nTimeout );
205 : void setNonBlocking( const bool &oIsNonBlocking );
206 : void setOption( const int &nLevel,
207 : const int &nOption,
208 : void *pvOptionValue,
209 : const socklen_t &nOptionLength );
210 : void setRecvTimeout( const int &nMillis );
211 :
212 : // Member variables
213 : private:
214 : /// The type of socket this is.
215 : SystemSocket::Type m_tType;
216 : /// The last error that occurred when manipulating the socket.
217 : int m_nLastError;
218 : /// The socket file descriptor.
219 : int m_nSocket;
220 : /// The timeout set for the 'connect' call.
221 : int m_nConnectTimeout;
222 : /// Stored host used.
223 : std::string m_szHost;
224 : /// Stored port used.
225 : int m_nPort;
226 : /// Are we using the nagle algorithm?
227 : bool m_oIsNagleDisabled;
228 : /// have we bound this socket to a port?
229 : bool m_oIsBound;
230 :
231 : }; // class SystemSocket
232 : } // namespace pcf
233 :
234 : ////////////////////////////////////////////////////////////////////////////////
235 :
236 : #endif // PCF_SYSTEM_SOCKET_HPP
|