PageRenderTime 50ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/ClassMaster2014/barahon/Transcend_0.3_UnixSource/minorGems/network/Socket.h

https://gitlab.com/garheade/linux_camp
C Header | 273 lines | 52 code | 68 blank | 153 comment | 3 complexity | 2e9114c9e14c19a587bffd7f45024d35 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /*
  2. * Modification History
  3. *
  4. * 2001-January-9 Jason Rohrer
  5. * Created.
  6. *
  7. * 2001-January-28 Jason Rohrer
  8. * Added a static framework init function.
  9. *
  10. * 2001-November-13 Jason Rohrer
  11. * Changed timeout parameter to signed, since -1 is a possible argument.
  12. *
  13. * 2002-March-29 Jason Rohrer
  14. * Added Fortify inclusion.
  15. *
  16. * 2002-August-2 Jason Rohrer
  17. * Added functon for getting remote host address.
  18. *
  19. * 2003-February-3 Jason Rohrer
  20. * Added a function for getting the local host address from a socket.
  21. *
  22. * 2003-August-12 Jason Rohrer
  23. * Added more verbose comment about receive timeout parameter.
  24. * Added a function for flushing socket sends.
  25. *
  26. * 2003-November-20 Jason Rohrer
  27. * Made flush function robust against bogus receive return values.
  28. *
  29. * 2004-December13 Jason Rohrer
  30. * Added a breakConnection function.
  31. *
  32. * 2005-July-5 Jason Rohrer
  33. * Added port number when getting address of remote host.
  34. */
  35. #include "minorGems/common.h"
  36. #ifndef SOCKET_CLASS_INCLUDED
  37. #define SOCKET_CLASS_INCLUDED
  38. #include "minorGems/network/HostAddress.h"
  39. #include "minorGems/system/Time.h"
  40. #ifdef FORTIFY
  41. #include "minorGems/util/development/fortify/fortify.h"
  42. #endif
  43. /**
  44. * Network socket. Does not contain an interface for listening to connections
  45. * (see SocketServer for these interfaces) or for establishing connections
  46. * (see SocketClient for these interfaces).
  47. *
  48. * Note: Implementation for the functions defined here is provided
  49. * separately for each platform (in the mac/ linux/ and win32/
  50. * subdirectories).
  51. *
  52. * @author Jason Rohrer
  53. */
  54. class Socket {
  55. public:
  56. /**
  57. * Constructor for a socket.
  58. *
  59. * Should not be called directly. Use SocketClient or SocketServer
  60. * to obtain an outbound or inbound socket connection.
  61. */
  62. Socket();
  63. // destroying a Socket closes the connection
  64. ~Socket();
  65. /**
  66. * Initializes the socket framework. Must be called
  67. * once by program before sockets are used. Note
  68. * that SocketClient and SocketServer both should call
  69. * init automatically when they are first used.
  70. *
  71. * @return 0 on success, or -1 on failure.
  72. */
  73. static int initSocketFramework();
  74. /**
  75. * Gets whether the socket framework has been initialized.
  76. *
  77. * @return true if the framework has been initialized.
  78. */
  79. static char isFrameworkInitialized();
  80. /**
  81. * Sends bytes through this socket.
  82. *
  83. * @param inBuffer the buffer of bytes to send.
  84. * @param inNumBytes the number of bytes to send.
  85. *
  86. * @return the number of bytes sent successfully,
  87. * or -1 for a socket error.
  88. */
  89. int send( unsigned char *inBuffer, int inNumBytes );
  90. /**
  91. * Receives bytes from this socket.
  92. *
  93. * @param inBuffer the buffer where received bytes will be put.
  94. * Must be pre-allocated memory space.
  95. * @param inNumBytes the number of bytes to read from the socket.
  96. * @param inTimeout the timeout for this receive operation in
  97. * milliseconds. Set to -1 for an infinite timeout.
  98. * -2 is returned from this call in the event of a timeout.
  99. *
  100. * @return the number of bytes read successfully,
  101. * or -1, -2 for a socket error or timeout, respectively.
  102. */
  103. int receive( unsigned char *inBuffer, int inNumBytes,
  104. long inTimeout );
  105. /**
  106. * Flushes sent data through the socket.
  107. *
  108. * Intended to be called before deleting the socket to ensure
  109. * that data goes through. The mechanism used by this function
  110. * does not guarantee that data goes through, but it works
  111. * better than simply closing the socket on many platforms.
  112. *
  113. * The method used by this call works best if the remote
  114. * host closes the connection. For example, if we send the
  115. * remote host a "connection closing" indicator, then
  116. * call writeFlushBeforeClose, and the remote host closes
  117. * the connection upon receiving the indicator, all of our
  118. * sent data will be received by the remote host after
  119. * writeFlushBeforeClose returns (assuming that the maximum
  120. * time is long enough for the remote host to actually close
  121. * the connection).
  122. *
  123. * Good maximum times should be in the several-second range,
  124. * though the Apache system uses 30 seconds. For slow connections,
  125. * this might be necessary.
  126. *
  127. * This call will cause any received data to be discarded.
  128. *
  129. * This call DOES NOT close the socket. The socket must be deleted
  130. * as usual after this call returns.
  131. *
  132. * @param inMaxTimeInMilliseconds the maximum time to wait
  133. * in milliseconds. This call may block slightly longer than
  134. * this if the remote host is still sending data.
  135. */
  136. void sendFlushBeforeClose( int inMaxTimeInMilliseconds );
  137. /**
  138. * Forces this socket's connection to break, causing any blocked
  139. * send or receive operations to fail.
  140. *
  141. * Note that this operation is inherently not thread-safe, so
  142. * some external mechanism must be used to ensure that the socket
  143. * is not destroyed by another thread before breakConnection is called.
  144. * The SocketManager class is one such external mechanism.
  145. */
  146. void breakConnection();
  147. /**
  148. * Gets the host connected to the other end of this socket.
  149. *
  150. * @return the address of the remote host, or NULL if obtaining
  151. * the address fails. The port of the returned address
  152. * will always be set to the port that the host is connecting from.
  153. * Must be destroyed by caller if non-NULL.
  154. */
  155. HostAddress *getRemoteHostAddress();
  156. /**
  157. * Gets the local address attached to this socket.
  158. *
  159. * Getting the local address from a socket is more
  160. * accurate than non-connected methods (for example, the methods
  161. * used in HostAddress.h implementations.
  162. *
  163. * @return the address of the local host, or NULL if obtaining
  164. * the address fails. The port of the returned address
  165. * will always be set to 0.
  166. * Must be destroyed by caller if non-NULL.
  167. */
  168. HostAddress *getLocalHostAddress();
  169. /**
  170. * Used by platform-specific implementations.
  171. */
  172. void *mNativeObjectPointer;
  173. private:
  174. static char sInitialized;
  175. char mIsConnectionBroken;
  176. };
  177. inline Socket::Socket()
  178. : mIsConnectionBroken( false ) {
  179. }
  180. inline char Socket::isFrameworkInitialized() {
  181. return sInitialized;
  182. }
  183. inline void Socket::sendFlushBeforeClose( int inMaxTimeInMilliseconds ) {
  184. unsigned char *tempBuffer = new unsigned char[1];
  185. int numRead = -2;
  186. int timeout = 1000;
  187. if( timeout > inMaxTimeInMilliseconds ) {
  188. timeout = inMaxTimeInMilliseconds;
  189. }
  190. long totalTimeout = 0;
  191. unsigned long startSec;
  192. unsigned long startMsec;
  193. Time::getCurrentTime( &startSec, &startMsec );
  194. // keep reading data from socket until we get an error
  195. // or wait too long (pass our max timeout)
  196. while( numRead != -1 && totalTimeout < inMaxTimeInMilliseconds ) {
  197. numRead =
  198. this->receive( tempBuffer, 1, timeout );
  199. // track total time whether the receive timed out or not
  200. totalTimeout =
  201. (long)( Time::getMillisecondsSince( startSec, startMsec ) );
  202. }
  203. delete [] tempBuffer;
  204. }
  205. #endif