![]() |
VR-Link API Documentation for HLA Evolved
|
00001 /********************************************************************* 00002 ** Copyright (c) 1992-2010 VT MAK 00003 ** All rights reserved. 00004 *********************************************************************/ 00009 #pragma once 00010 00011 #include <vlutil/vlInet.h> 00012 #include <vlutil/vlInetAddr.h> 00013 #include <vlutil/vlInetAddrUtils.h> 00014 #include <vlutil/vlInetDevice.h> 00015 #include <vlutil/vlInetEndpoint.h> 00016 #include <vlutil/vlThreadSafe.h> 00017 #include <vlutil/vlString.h> 00018 #include <deque> 00019 #include <map> 00020 00021 #ifdef DtUSE_UTILITIES_NAMESPACE 00022 namespace DtUSE_UTILITIES_NAMESPACE 00023 { 00024 #endif 00025 00032 #define DtRead ((DtU32) 0x01) 00033 00034 #define DtWrite ((DtU32) 0x02) 00035 00036 #define DtReadWrite (DtRead | DtWrite) 00037 00038 00039 00040 00041 00042 00043 #define DtBindToDestAddr ((DtU32) 0x08) 00044 00045 00046 00047 00048 #define DtQuiet ((DtU32) 0x10) 00049 00054 #define DtSockOptStrictMulticastBinding ((DtU32) 0x20) 00055 00056 #ifdef _WIN32 00057 #define DtSockOptNonBlocking ((DtU32) 0x40) // MSG_DONTWAIT not supported 00058 #else // !_WIN32 00059 // Not sure if MSG_DONTWAIT is supported on Solaris, Irix, etc... 00060 #define DtSockOptNonBlocking ((DtU32) MSG_DONTWAIT) 00061 #endif 00062 00063 00064 #define DtSockOptNoDelay ((DtU32) 0x80) 00065 00066 00067 00068 00069 00070 00071 00072 #define DtSockAsyncRead ((DtU32) 0x100) 00073 #define DtSockAsyncWrite ((DtU32) 0x200) 00074 #define DtAsyncReadWrite (DtSockAsyncRead | DtSockAsyncWrite) 00075 #define DtSockWriteable ((DtU32)DtWrite | DtSockAsyncWrite) 00076 #define DtSockReadable ((DtU32)DtRead | DtSockAsyncRead) 00077 00078 00079 #define DtSockOptAddrReuse ((DtU32) 0x400) 00080 #define DtSockOptPortReuse ((DtU32) 0x800) 00081 #define DtSockOptAllReuse (DtSockOptAddrReuse | DtSockOptPortReuse) 00082 00083 00084 #define DtSockDisablePreProcCallbacks ((DtU32) 0x1000) 00085 #define DtSockDisablePostProcCallbacks ((DtU32) 0x2000) 00086 #define DtSockDisableCallbacks (DtSockDisablePreProcCallbacks || DtSockDisablePostProcCallbacks) 00087 // By default client sockets will be configured for blocking mode, read-write 00088 // operation, address and port reuse enabled (UDP), NODELAY (TCP) operation. 00089 #define DtDefaultSockOpts (DtU32)(DtReadWrite | DtSockOptAllReuse | DtSockOptNoDelay) 00090 00093 class DtInetSocket; 00094 00102 // STOPPED HERE -- use shared_ptr for buffers see Boost documentation on reference-counted buffers 00103 typedef std::vector<char> DtInetBuffer; 00104 typedef std::vector<DtInetBuffer*> DtInetBufferChain; 00105 typedef std::pair<void*, DtInetBuffer*> DtInetBuffQueueEntry; 00106 typedef DtThreadSafe<std::deque<DtInetBuffQueueEntry> > DtInetThreadSafeQueue; 00107 00110 enum DtInetSockState 00111 { 00112 DtInetSockState_ERROR = -1, 00113 DtInetSockState_NOT_INITIALIZED = 0, 00114 DtInetSockState_INITIALIZED, 00115 DtInetSockState_OPEN, 00116 DtInetSockState_LISTENING, 00117 DtInetSockState_INPROGRESS, 00118 DtInetSockState_CONN_REFUSED, 00119 DtInetSockState_CONNECTED, 00120 DtInetSockState_TIMEDOUT, 00121 DtInetSockState_DISCONNECTED, 00122 DtInetSockState_CLOSED 00123 00124 }; 00125 00127 enum DtInetSockRcvStatus 00128 { 00129 DtInetSockRcv_UNBUNDLED_PACKET = -5, 00130 DtInetSockRcv_BUFFER_TOO_SMALL = -4, 00131 DtInetSockRcv_FILTERED_BY_PORT = -3, 00132 DtInetSockRcv_FILTERED_PACKET = -2, 00133 DtInetSockRcv_ERROR = -1, 00134 DtInetSockRcv_NO_PACKET = 0, 00135 // Any value greater than NO_PACKET represents 00136 // the number of bytes received 00137 DtInetSockRcv_MAX_RETVAL = INT_MAX 00138 00139 }; 00140 00142 enum DtInetSockFlushStatus 00143 { 00144 DtInetSockFlush_ERROR = -1, 00145 DtInetSockFlush_MORE_TO_FLUSH = 0, 00146 DtInetSockFlush_FLUSH_COMPLETE = 1 00147 00148 }; 00149 00151 enum DtInetSockProcessingType 00152 { 00153 DtInetSockProcess_PRE_RECV, 00154 DtInetSockProcess_POST_RECV, 00155 DtInetSockProcess_PRE_SEND, 00156 DtInetSockProcess_POST_SEND 00157 }; 00158 00170 typedef int (*DtInetSocketProcessingCallback)( DtInetSocket* sock, int size, 00171 DtInetBufferChain& buffChain, 00172 DtInetEndpoint& ep, void* usr); 00174 class DtInetSocketProcessingCbInfo 00175 { 00176 public: 00177 00178 DtInetSocketProcessingCbInfo( DtInetSocketProcessingCallback cb, void* usr, 00179 int order ) 00180 { 00181 myCb = cb; 00182 myUsr = usr; 00183 myCallOrder = order; 00184 } 00185 00186 DtInetSocketProcessingCallback myCb; 00187 void* myUsr; 00188 int myCallOrder; 00189 }; 00190 typedef std::multimap<int, DtInetSocketProcessingCbInfo*> DtInetSockCallbackList; 00191 00193 00199 class DT_DLL_VLUTIL DtInetSocket 00200 { 00201 public: 00202 00206 DtInetSocket(); 00207 00209 virtual ~DtInetSocket(); 00210 00217 virtual bool setDestination( const DtInetEndpoint& dest ) = 0; 00218 virtual const DtInetEndpoint& destination() const; 00219 00224 virtual const DtInetEndpoint& localEndpoint() const; 00225 00229 virtual bool setLocalPort( DtU16 port ); 00230 virtual DtU16 localPort() const; 00231 00243 virtual bool bindToDevice( const DtInetDevice* hostIf = NULL ) = 0; 00244 00250 virtual const DtInetDevice* hostIf() const; 00251 00256 virtual bool openSocket() = 0; 00257 00262 virtual bool closeSocket() = 0; 00263 00272 virtual bool connectToDestination() = 0; 00273 00279 00282 virtual int send( caddr_t packet, size_t size, DtU32 flags = 0 ) = 0; 00283 virtual int sendTo( caddr_t packet, size_t size, 00284 DtInetEndpoint& dest, DtU32 flags = 0 ) = 0; 00285 00289 virtual int sendChain( DtInetBufferChain& packets, DtU32 flags = 0 ) = 0; 00290 00291 virtual int sendChainTo( DtInetBufferChain& packets, 00292 DtInetEndpoint& dest, DtU32 flags = 0 ) = 0; 00294 00304 00307 virtual DtInetSockRcvStatus recv( caddr_t buff, size_t buffSize, 00308 DtU32 flags = 0 ) = 0; 00309 00314 virtual DtInetSockRcvStatus recvToChain( DtInetBufferChain& packets, 00315 DtU32 flags = 0 ) = 0; 00316 00319 virtual DtInetSockRcvStatus recvFrom( caddr_t buff, size_t buffSize, 00320 DtInetEndpoint& src, DtU32 flags = 0 ) = 0; 00321 00322 virtual DtInetSockRcvStatus recvToChainFrom( DtInetBufferChain& packets, 00323 DtInetEndpoint& src, DtU32 flags = 0 ) = 0; 00325 00327 virtual DtInetSockState state(); 00328 00335 virtual bool isOk(); 00336 00338 virtual DtU32 protocol() const; 00339 00341 virtual DtInetUtils::DtInetAddrFamily family() const; 00342 00344 virtual int descriptor() const = 0; 00345 00352 virtual bool setSocket( const DtInetEndpoint& dest, DtU16 localPort = 0, 00353 DtInetDevice* hostIf = NULL, DtU32 flags = DtDefaultSockOpts ) = 0; 00354 00362 virtual bool setNonBlockingOption( bool onOrOff ) = 0; 00363 virtual bool setReuseAddressOption( bool onOrOff ) = 0; 00364 virtual bool setSendBufferSize( DtU32 size ) = 0; 00365 virtual bool setReceiveBufferSize( DtU32 size ) = 0; 00366 virtual bool setDoNotRouteOption( bool onOrOff ) = 0; 00367 virtual bool setSendLowWatermark( DtU32 size ) = 0; 00368 virtual bool setReceiveLowWatermark( DtU32 size ) = 0; 00369 00370 virtual bool isNonBlocking() const; 00371 virtual bool isNoDelay() const; 00372 virtual bool getReuseAddressOption() = 0; 00373 virtual bool getDoNotRouteOption() = 0; 00374 virtual DtU32 getSendBufferSize() = 0; 00375 virtual DtU32 getReceiveBufferSize() = 0; 00376 virtual DtU32 getBytesAvailable() = 0; 00377 virtual DtU32 getSendLowWatermark() = 0; 00378 virtual DtU32 getReceiveLowWatermark() = 0; 00380 00383 virtual bool isIPv4() const; 00384 virtual bool isIPv6() const; 00385 virtual bool isTcp() const; 00386 virtual bool isUdp() const; 00388 00390 virtual int getLastError(); 00391 virtual DtString getLastErrorString(); 00392 virtual bool isErrorWouldBlockOrTryAgain(); 00393 virtual void clearError(); 00394 00396 virtual int getTerminationCode(); 00397 virtual DtString getTerminationString(); 00398 00405 virtual DtU64 totalBytesSent() const; 00406 virtual DtU64 totalPacketsSent() const; 00407 virtual DtU64 totalBytesReceived() const; 00408 virtual DtU64 totalPacketsReceived() const; 00409 00411 virtual void clearStats(); 00412 00419 virtual bool addProcessingCallback( DtInetSockProcessingType kind, 00420 DtInetSocketProcessingCallback cb, void* usr, int callSequence = -1 ); 00421 00422 virtual bool removeProcessingCallback( DtInetSockProcessingType kind, 00423 DtInetSocketProcessingCallback cb ); 00424 00425 protected: 00426 virtual bool findAndRemoveCallback( DtInetSockCallbackList& cbList, 00427 DtInetSocketProcessingCallback cb ); 00428 00429 private: 00431 DtInetSocket( const DtInetSocket& orig ); 00432 00434 DtInetSocket& operator=(const DtInetSocket& orig); 00435 00436 protected: 00437 DtInetEndpoint myLocalEndpoint; 00438 DtInetEndpoint myRemoteEndpoint; 00439 00440 DtInetDevice* myHostIf; 00441 00442 DtInetSockState myState; 00443 00444 DtU32 myFlags; 00445 bool myAsync; 00446 bool myNonBlockingEnabled; 00447 bool myNoDelayEnabled; 00448 bool myStartImmediately; 00449 00450 int myErrorCode; 00451 DtString myErrorString; 00452 00453 int myTerminationCode; 00454 DtString myTerminationString; 00455 00456 DtInetSockCallbackList myPreRecvCallbacks; 00457 DtInetSockCallbackList myPostRecvCallbacks; 00458 DtInetSockCallbackList myPreSendCallbacks; 00459 DtInetSockCallbackList myPostSendCallbacks; 00460 00461 // For internal statistics only 00462 DtU64 mySentByteCount; 00463 DtU64 mySentPacketCount; 00464 DtU64 myReceivedByteCount; 00465 DtU64 myReceivedPacketCount; 00466 00467 }; 00468 // end of class DtInetSocket 00469 00470 inline DtU64 DtInetSocket::totalBytesSent() const 00471 { 00472 return mySentByteCount; 00473 } 00474 00475 inline DtU64 DtInetSocket::totalPacketsSent() const 00476 { 00477 return mySentPacketCount; 00478 } 00479 00480 inline DtU64 DtInetSocket::totalBytesReceived() const 00481 { 00482 return myReceivedByteCount; 00483 } 00484 00485 inline DtU64 DtInetSocket::totalPacketsReceived() const 00486 { 00487 return myReceivedPacketCount; 00488 } 00489 00490 inline void DtInetSocket::clearStats() 00491 { 00492 mySentByteCount = 0; 00493 mySentPacketCount = 0; 00494 myReceivedByteCount = 0; 00495 myReceivedPacketCount = 0; 00496 } 00497 00498 inline bool DtInetSocket::findAndRemoveCallback( DtInetSockCallbackList& cbList, 00499 DtInetSocketProcessingCallback cb ) 00500 { 00501 bool found = false; 00502 DtInetSockCallbackList::iterator iter = cbList.begin(); 00503 while ( !found && iter != cbList.end() ) 00504 { 00505 if ( cb == iter->second->myCb ) 00506 { 00507 DtDELETE(iter->second); 00508 cbList.erase( iter ); 00509 found = true; 00510 } 00511 else 00512 { 00513 ++iter; 00514 } 00515 } 00516 00517 return found; 00518 } 00519 00520 #ifdef DtUSE_UTILITIES_NAMESPACE 00521 } 00522 #endif 00523 00524 00525