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