HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_NetSocket.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_NetSocket.h ( UT Library, C++)
7  *
8  * COMMENTS:
9  * Simple Network socket definition. Non-Blocking by default.
10  *
11  */
12 
13 #ifndef __UT_NetSocket__
14 #define __UT_NetSocket__
15 
16 #include "UT_API.h"
17 #include <SYS/SYS_Time.h>
18 
19 // For fd_set, you will need to #include <SYS/SYS_Socket.h>
20 #ifdef WIN32
21 struct fd_set;
22 #endif
23 
24 class UT_String;
25 class UT_WorkBuffer;
26 
27 
29 {
30 public:
31  enum
32  {
33  UT_CONNECT_SUCCESS = 0,
34 
35  UT_WOULD_BLOCK = -1,
36  UT_BAD_ADDRESS = -2,
37  UT_CONNECT_FAILED = -3,
38  UT_ERROR_OCCURED = -4,
39  UT_WRONG_SOCKET = -5,
40  UT_NO_CONNECTION = -6
41  };
42 
43  enum
44  {
45  UT_SHUTDOWN_RECEIVE = 0,
46  UT_SHUTDOWN_SEND = 1,
47  UT_SHUTDOWN_BOTH = 2
48  };
49 
50  /// Convertes the enum of UT_CONNECT_SUCCESS, etc, into an english
51  /// error message roughly matching the enum's name. Be careful
52  /// as this uses different errors different locations.
53  static const char *getErrorName(int code);
54 
55  static int getPortByService(const char *service, const char *proto="tcp",
56  int default_port = 0);
57 
58  static void getHostName(char *name, int max);
59 
60  // Get the host address of the form xxx.xxx.xxx.xxx. Returns 1 on success
61  static int getHostAddress(unsigned char address[4],
62  const char *hostname = 0);
63 
64  // Obtains the actual machine name of the host specified by
65  // alias name. Return true on success. If alias = 0, obtains local machine.
66  static bool getHostNameByAlias(UT_String &host, const char *alias = NULL);
67 
68  // Try to map a port number into the range of unprivileged port numbers.
69  static int mapToUnprivilegedPort(int port);
70 
71  // This convenience method can be called from external programs to send
72  // a command on a socket port and wait for a response. If the host name
73  // is null, the local host will be used. If remap_privileged_ports is
74  // true, the given port might be remapped to increase the likelihood
75  // of it being opened. False will be returned if the socket could not be
76  // opened.
77  static bool sendCommandAndGetResult(int port,
78  const char *command,
79  UT_WorkBuffer &response,
80  const char *host_name = 0,
81  bool remap_privileged_ports = true);
82 
83  static bool nonBlockingSendCommandAndGetResult(int port,
84  const char *command,
85  UT_WorkBuffer &response,
86  const char *host_name = 0,
87  bool remap_privileged_ports = true);
88 
89  /// Creates a new listen socket on the specified port. A port of 0
90  /// will auto-choose a free port. Be careful overusing that, however,
91  /// as Windows in particular has very few ports available by default.
92  /// portisonlyhint will attempt to bind to the given port but if
93  /// it fails (ie, already in use) will revert to using 0 to select
94  /// a free port. The caller should thus double check the actual
95  /// bound port if they care.
96  static UT_NetSocket *newSocket(int port, bool blocking = false,
97  bool portisonlyhint = false);
98  static UT_NetSocket *newSocketFromAddr(
99  const char *address,
100  int port,
101  bool blocking = false,
102  int localport = -1,
103  int forcesocket=0);
104  static void fdZero(fd_set *set);
105  static void fdSet(int fd, fd_set *set);
106  static void fdClr(int fd, fd_set *set);
107  static int fdIsSet(int fd, fd_set *set);
108 
109  /// Performs a select() call on the socket.
110  ///
111  ///
112  /// Note, it turns out there is a discrepancy between how select() works on
113  /// Linux vs. Windows.
114  ///
115  /// On Windows, the select() call selects for reading the sockets even if
116  /// they were closed by the remote counterparts. The rationale is that
117  /// trying to read from such a socket returns zero, which is a signal that
118  /// the connection was closed.
119  ///
120  /// On Linux/OSX, select() call does not select such sockets for reading.
121  /// The rationale is that there cannot be any more data for reading on
122  /// closed sockets.
123  ///
124  ///
125  /// WARNING: the following select will not work on UT_PipeSocket instance
126  /// for write and error sets because there is no system call that probes
127  /// these states. UT_PipeSocket derives from UT_NetSocket, so be careful
128  ///
129  /// Use it only on sockets!
130  static int select(int fd, fd_set *r_set, fd_set *w_set,
131  fd_set *e_set, SYS_TimeVal *tv,
132  bool forcesocket=false);
133  // Simplified select which takes a timeout in milliseconds
134  static int selectInMS(int maxfd,
135  fd_set *r_set,
136  fd_set *w_set,
137  fd_set *e_set,
138  int timeoutms = 0,
139  bool forcesocket = false);
140 
141  bool isSocketSelected(fd_set &set);
142  // Adds this socket to the given fd set.
143  void addToFDSet(fd_set *set, int &maxfd);
144 
145  // Destructor. Closes connection if open.
146  virtual ~UT_NetSocket();
147 
148  virtual int64 getMemoryUsage(bool inclusive) const;
149 
150  // *******************************************************
151  // Connection routines
152 
153  // Determines if any connection requests are pending, and creates a
154  // new socket for that connection (SERVER SOCKET ONLY).
155  virtual UT_NetSocket *accept(int blocking, int &condition);
156 
157  // Connects to the server named in the constructor (CLIENT SOCKET ONLY)
158  // If timeout is greater than zero, the connection time is going to be
159  // no longer than the amount specified. If connection succeeds within
160  // the time specified, UT_CONNECT_SUCCESS is returned. If timeout is
161  // zero, a blocking connectoin is carried out, and if fails UT_WOULD_BLOCK
162  // or UT_CONNECT_FAILED is returned.
163  virtual int connect(int timeout_ms = 0);
164 
165  // closes the socket (client or server).
166  virtual int close();
167 
168  virtual int shutdown(int type);
169 
170  // *******************************************************
171  // I/O Routines (client or server)
172 
173  // writes len bytes to the socket.
174  virtual int write(const void *data,int len,int *numWritten = 0);
175 
176  // peeks to see if any data is available. Timeout is specified in ms.
177  // Returns 1 if there is data to be read, 0 if not, and less
178  // than 0 if error.
179  virtual int dataAvailable(int timeout=0);
180 
181  // Attempts to read len bytes. Actual number of read bytes is
182  // returned in numRead.
183  // If read ever succeeds, UT_CONNECT_SUCCESS is returned.
184  // If any error ever occurs during a read, UT_ERROR_OCCURED is returned.
185  // If specified timeout_ms is non-negative then read will block
186  // for at most that many miliseconds, and then it will return
187  // UT_WOULD_BLOCK if still no data has been read.
188  // If UT_WOULD_BLOCK is returned, numRead may be non-zero to
189  // show that some data was read prior to the block.
190  // If specified timeout_ms is less than zero, a blocking socket will
191  // block (wait) till data is available, and a non blocking socket
192  // will return right away with UT_WOULD_BLOCK code.
193  virtual int read(void *data, int len, int *numRead = 0,
194  int timeout_ms = -1);
195 
196  // Read all available data into a work buffer.
197  virtual int read(UT_WorkBuffer &data, int timeout_ms = -1,
198  bool wait_for_null_terminator = false);
199 
200  // Reads len bytes & doesn't remove them from the queue
201  virtual int peek(void *data, int len, int timeout_ms = -1);
202 
203  // Flushes the read or write queue.
204  virtual int flushRead();
205  virtual int flushWrite();
206 
207 
208  void terminateOnConnectionLost(bool term = true);
209 
210  // ********************************************************
211  // Miscellaneous routines.
212 
213  // returns the address name and port of the host, or the connected
214  // host (in the case of a UT_NetSocket returned by accept().)
215 
216  const char *getAddress() const
217  { return myAddressName ? myAddressName:""; }
218 
219  int getPort() const
220  { return myAddressPort; }
221 
222  // Returns information about the other end of the socket. "host" buffer
223  // must be at least 20 characters longs.
224  virtual int getRemoteSocket(char *host, int &port) const;
225 
226  // Sets the socket to blocking or non blocking
227  virtual int setBlocking(bool blocking);
228  bool isBlocking() const { return myIsBlocking; }
229 
230  void setNoDelay(int usenodelay);
231 
232  // true if the socket is valid.
233  virtual int isValid();
234 
235  // true if the socket is connected.
236  int isConnected();
237 
238  // returns the file descriptor for the socket... beware!
239  int getSocket() const;
240 
241  uint32 getRemoteIP4() const { return myRemoteIP4; }
242  bool getRemoteIP4(int ip[4]);
243  uint32 getLocalIP4() const;
244  bool getLocalIP4(int ip[4]);
245 
246 protected:
247  // Because virtuals shouldn't be called in destructors, we have a
248  // non-virtual close method.
249  int closeInetSocket();
250 
251  // The actual net-socket constructors
252  UT_NetSocket(UT_NetSocket *netsocket, int socket, bool blocking);
253  UT_NetSocket(int port, bool blocking = false, bool portisonlyhint=false);
254  UT_NetSocket(const char *address, int port, bool blocking = false,
255  int localport = -1);
256 
257  // Default constructor used by shmsocket stuff
258  UT_NetSocket(); // Default
259 
260  // Helper method for waiting for data on the socket or a timeout.
261  // It is really a wrapper for data available with extra error checks
262  // Returns UT_NO_CONNECTION, UT_ERROR_OCCURED if error,
263  // UT_WOULD_BLOCK if timeout expired, or UT_CONNECTION_SUCCESS if
264  // specified timeout <= 0 or if data is available before timeout expired.
265  int waitForDataOrTimeout( int timeout_ms );
266 
267 private:
268  // helper method that implements a timed-out connection for sockets
269  // (especially, NOT FOR PIPES ON NT!)
270  // Returns the errno of the socket (eg, 0 if OK, ETIMEDOUT if timeout, ...)
271  int connectOrTimeout(struct sockaddr_in *address,
272  int address_length, int timeout_ms);
273 
274  // platform dependent code for API
275  // Returns 0 if OK, or errno if failed
276  int doConnect(struct sockaddr_in *address,
277  int address_length, bool check_err);
278 
279  // probes the activity of this socket for read, write, error readines
280  // (whichever is not NULL) and sets the given argument appropriately.
281  // Returns 0 if timeout, 1 if OK, negative if error.
282  // NB: this call is used by UT_NetPacket::connect() during the connection
283  // process. It is applicable only to UT_NetSocket, and is not
284  // to UT_PipeSocket which derives from UT_NetSocket. The reason is
285  // that pipe cannot test fd_write or fd_error, which may be essential
286  // during connection process implemented by this class. UT_PipeSocket
287  // has own connect() method that does not use checkConnectStatus()
288  int checkDataStatus(bool *fd_read, bool *fd_write,
289  bool *fd_error, int timeout_ms);
290 
291  // abstracted host by alias part that is common to Linux and NT
292  // On Linux this method must be surrounded by locks.
293  static bool commonGetHostNameByAlias( UT_String &host,
294  const char *alias );
295 
296 protected:
297 
300  int mySocket;
301  uint32 myRemoteIP4; // Remote IP address
302 
303  //flags
304  unsigned char myIsServer :1,
305  myConnected :1,
306  myShmFlag :1, // Am I a shared memory socket?
307  myTermOnLost :1, // exit if connection broken.
308  myIsBlocking :1;
309 };
310 
312 {
313 public:
314  UT_AutoSocketDeleter(UT_NetSocket *socket) : mySocket(socket) {}
315  ~UT_AutoSocketDeleter() { delete mySocket; }
316 private:
317  UT_NetSocket *mySocket;
318 };
319 
320 #endif
struct timeval SYS_TimeVal
Definition: SYS_Time.h:27
uint32 myRemoteIP4
Definition: UT_NetSocket.h:301
uint32 getRemoteIP4() const
Definition: UT_NetSocket.h:241
int getPort() const
Definition: UT_NetSocket.h:219
char * myAddressName
Definition: UT_NetSocket.h:298
#define UT_API
Definition: UT_API.h:13
void read(T &in, bool &v)
Definition: ImfXdr.h:611
long long int64
Definition: SYS_Types.h:107
GLbitfield GLuint64 timeout
Definition: glcorearb.h:1598
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:133
const char * getAddress() const
Definition: UT_NetSocket.h:216
bool isBlocking() const
Definition: UT_NetSocket.h:228
GLboolean * data
Definition: glcorearb.h:130
GLuint const GLchar * name
Definition: glcorearb.h:785
virtual void close()
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
void write(T &out, bool v)
Definition: ImfXdr.h:332
UT_AutoSocketDeleter(UT_NetSocket *socket)
Definition: UT_NetSocket.h:314
unsigned int uint32
Definition: SYS_Types.h:36