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