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