Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

173 lines
5.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #ifndef ITHREADEDTCPSOCKET_H
  8. #define ITHREADEDTCPSOCKET_H
  9. #ifdef _WIN32
  10. #pragma once
  11. #endif
  12. #include "iphelpers.h"
  13. class IThreadedTCPSocket;
  14. class CTCPPacket
  15. {
  16. public:
  17. // Access the contents of the packet.
  18. const char* GetData() const;
  19. int GetLen() const;
  20. // You can attach some user data to the packet.
  21. int GetUserData() const;
  22. void SetUserData( int userData );
  23. // Free resources associated with the packet.
  24. void Release();
  25. public:
  26. friend class CThreadedTCPSocket;
  27. ~CTCPPacket(); // Use Release(), not delete.
  28. int m_UserData;
  29. int m_Len;
  30. char m_Data[1];
  31. };
  32. inline const char* CTCPPacket::GetData() const
  33. {
  34. return m_Data;
  35. }
  36. inline int CTCPPacket::GetLen() const
  37. {
  38. return m_Len;
  39. }
  40. // The application implements this to handle packets that are received.
  41. // Note that the implementation must be thread-safe because these functions can be called
  42. // from various threads.
  43. class ITCPSocketHandler
  44. {
  45. public:
  46. enum
  47. {
  48. SocketError=0,
  49. ConnectionTimedOut
  50. };
  51. // This is called right when the socket becomes ready to have data sent through it and
  52. // before OnPacketReceive is ever called.
  53. virtual void Init( IThreadedTCPSocket *pSocket ) = 0;
  54. // This is called when a packet arrives. NOTE: you are responsible for freeing the packet
  55. // by calling CTCPPacket::Release() on it.
  56. virtual void OnPacketReceived( CTCPPacket *pPacket ) = 0;
  57. // Handle errors inside the socket. After this is called, the socket is no longer alive.
  58. // Note: this might be called from ANY thread (the main thread, the send thread, or the receive thread).
  59. //
  60. // errorCode is one of the enums above (SocketError, ConnectionTimedOut, etc).
  61. virtual void OnError( int errorCode, const char *pErrorString ) = 0;
  62. };
  63. //
  64. // This is the main threaded TCP socket class.
  65. // The way these work is that they have a thread for sending and a thread for receiving data.
  66. //
  67. // The send thread is continually pushing your data out the door.
  68. //
  69. // The receive thread is continually receiving data. When it receives data, it calls your HandlePacketFn
  70. // to allow the user to handle it. Be very careful in your HandlePacketFn, since it is in another thread.
  71. // Anything it accesses should be protected by mutexes and the like.
  72. //
  73. class IThreadedTCPSocket
  74. {
  75. public:
  76. // Cleanup everything and exit.
  77. // Note: if the receive thread is inside your HandlePacketFn returns, this function blocks until that function returns.
  78. virtual void Release() = 0;
  79. // Returns the address of whoever you are connected to.
  80. virtual CIPAddr GetRemoteAddr() const = 0;
  81. // Returns true if the socket is connected and ready to go. If this returns false, then the socket won't
  82. // send or receive data any more. It also means that your ITCPSocketHandler's OnError function has been called.
  83. virtual bool IsValid() = 0;
  84. // Send data. Any thread can call these functions, and they don't block. They make a copy of the data, then
  85. // enqueue it for sending.
  86. virtual bool Send( const void *pData, int len ) = 0;
  87. virtual bool SendChunks( void const * const *pChunks, const int *pChunkLengths, int nChunks ) = 0;
  88. };
  89. // Use these to get incoming connections.
  90. class ITCPConnectSocket
  91. {
  92. public:
  93. // Call this to stop listening for connections and delete the object.
  94. virtual void Release() = 0;
  95. // Keep calling this as long as you want to wait for connections.
  96. //
  97. // If it returns true and pSocket is NULL, it means it hasn't connected yet.
  98. // If it returns true and pSocket is non-NULL, then it has connected.
  99. // If it returns false, then the connection attempt failed and all further Update() calls will return false.
  100. virtual bool Update( IThreadedTCPSocket **pSocket, unsigned long milliseconds=0 ) = 0;
  101. };
  102. // This class is implemented by the app and passed into CreateListener. When the listener makes
  103. // a new connection, it calls CreateNewHandler() to have the app create something that will handle
  104. // the received packets and errors for the new socket.
  105. class IHandlerCreator
  106. {
  107. public:
  108. // This function must return a valid value.
  109. virtual ITCPSocketHandler* CreateNewHandler() = 0;
  110. };
  111. // Use this to listen for TCP connections. The ITCPConnectSocket will keep returning connections
  112. // until you call Release().
  113. ITCPConnectSocket* ThreadedTCP_CreateListener(
  114. IHandlerCreator *pHandlerCreator, // This handles messages from the socket.
  115. const unsigned short port, // Listen on this port.
  116. int nQueueLength = 5 // How many connections
  117. );
  118. // Use this to connect to a remote process. After Update() returns a non-NULL value, you should
  119. // call Release() on the ITCPConnectSocket because it won't ever return another connection.
  120. ITCPConnectSocket* ThreadedTCP_CreateConnector(
  121. const CIPAddr &addr, // Who to connect to.
  122. const CIPAddr &localAddr, // Local address to bind to. Leave uninitialized (pass in CIPAddr()) and it will
  123. // an interface and a port for you. You can also just fill in the port, and it will
  124. // use that port and choose an interface for you.
  125. IHandlerCreator *pHandlerCreator// If it connects, it asks this thing to make a handler for the connection.
  126. );
  127. // Enable or disable timeouts.
  128. void ThreadedTCP_EnableTimeouts( bool bEnable );
  129. // This should be called at init time. If set to true, it'll set the send and recv threads to low priority.
  130. // (Default is true).
  131. void ThreadedTCP_SetTCPSocketThreadPriorities( bool bSetTCPSocketThreadPriorities );
  132. #endif // ITHREADEDTCPSOCKET_H