summaryrefslogtreecommitdiff
path: root/utils/vmpi/IThreadedTCPSocket.h
diff options
context:
space:
mode:
Diffstat (limited to 'utils/vmpi/IThreadedTCPSocket.h')
-rw-r--r--utils/vmpi/IThreadedTCPSocket.h173
1 files changed, 173 insertions, 0 deletions
diff --git a/utils/vmpi/IThreadedTCPSocket.h b/utils/vmpi/IThreadedTCPSocket.h
new file mode 100644
index 0000000..904dc7f
--- /dev/null
+++ b/utils/vmpi/IThreadedTCPSocket.h
@@ -0,0 +1,173 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef ITHREADEDTCPSOCKET_H
+#define ITHREADEDTCPSOCKET_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+
+#include "iphelpers.h"
+
+
+class IThreadedTCPSocket;
+
+
+class CTCPPacket
+{
+public:
+ // Access the contents of the packet.
+ const char* GetData() const;
+ int GetLen() const;
+
+ // You can attach some user data to the packet.
+ int GetUserData() const;
+ void SetUserData( int userData );
+
+ // Free resources associated with the packet.
+ void Release();
+
+public:
+ friend class CThreadedTCPSocket;
+ ~CTCPPacket(); // Use Release(), not delete.
+
+ int m_UserData;
+ int m_Len;
+ char m_Data[1];
+};
+
+
+inline const char* CTCPPacket::GetData() const
+{
+ return m_Data;
+}
+
+
+inline int CTCPPacket::GetLen() const
+{
+ return m_Len;
+}
+
+
+// The application implements this to handle packets that are received.
+// Note that the implementation must be thread-safe because these functions can be called
+// from various threads.
+class ITCPSocketHandler
+{
+public:
+
+ enum
+ {
+ SocketError=0,
+ ConnectionTimedOut
+ };
+
+ // This is called right when the socket becomes ready to have data sent through it and
+ // before OnPacketReceive is ever called.
+ virtual void Init( IThreadedTCPSocket *pSocket ) = 0;
+
+ // This is called when a packet arrives. NOTE: you are responsible for freeing the packet
+ // by calling CTCPPacket::Release() on it.
+ virtual void OnPacketReceived( CTCPPacket *pPacket ) = 0;
+
+ // Handle errors inside the socket. After this is called, the socket is no longer alive.
+ // Note: this might be called from ANY thread (the main thread, the send thread, or the receive thread).
+ //
+ // errorCode is one of the enums above (SocketError, ConnectionTimedOut, etc).
+ virtual void OnError( int errorCode, const char *pErrorString ) = 0;
+};
+
+
+//
+// This is the main threaded TCP socket class.
+// The way these work is that they have a thread for sending and a thread for receiving data.
+//
+// The send thread is continually pushing your data out the door.
+//
+// The receive thread is continually receiving data. When it receives data, it calls your HandlePacketFn
+// to allow the user to handle it. Be very careful in your HandlePacketFn, since it is in another thread.
+// Anything it accesses should be protected by mutexes and the like.
+//
+class IThreadedTCPSocket
+{
+public:
+ // Cleanup everything and exit.
+ // Note: if the receive thread is inside your HandlePacketFn returns, this function blocks until that function returns.
+ virtual void Release() = 0;
+
+ // Returns the address of whoever you are connected to.
+ virtual CIPAddr GetRemoteAddr() const = 0;
+
+ // Returns true if the socket is connected and ready to go. If this returns false, then the socket won't
+ // send or receive data any more. It also means that your ITCPSocketHandler's OnError function has been called.
+ virtual bool IsValid() = 0;
+
+ // Send data. Any thread can call these functions, and they don't block. They make a copy of the data, then
+ // enqueue it for sending.
+ virtual bool Send( const void *pData, int len ) = 0;
+ virtual bool SendChunks( void const * const *pChunks, const int *pChunkLengths, int nChunks ) = 0;
+};
+
+
+
+// Use these to get incoming connections.
+class ITCPConnectSocket
+{
+public:
+ // Call this to stop listening for connections and delete the object.
+ virtual void Release() = 0;
+
+ // Keep calling this as long as you want to wait for connections.
+ //
+ // If it returns true and pSocket is NULL, it means it hasn't connected yet.
+ // If it returns true and pSocket is non-NULL, then it has connected.
+ // If it returns false, then the connection attempt failed and all further Update() calls will return false.
+ virtual bool Update( IThreadedTCPSocket **pSocket, unsigned long milliseconds=0 ) = 0;
+};
+
+
+// This class is implemented by the app and passed into CreateListener. When the listener makes
+// a new connection, it calls CreateNewHandler() to have the app create something that will handle
+// the received packets and errors for the new socket.
+class IHandlerCreator
+{
+public:
+ // This function must return a valid value.
+ virtual ITCPSocketHandler* CreateNewHandler() = 0;
+};
+
+
+// Use this to listen for TCP connections. The ITCPConnectSocket will keep returning connections
+// until you call Release().
+ITCPConnectSocket* ThreadedTCP_CreateListener(
+ IHandlerCreator *pHandlerCreator, // This handles messages from the socket.
+ const unsigned short port, // Listen on this port.
+ int nQueueLength = 5 // How many connections
+ );
+
+
+// Use this to connect to a remote process. After Update() returns a non-NULL value, you should
+// call Release() on the ITCPConnectSocket because it won't ever return another connection.
+ITCPConnectSocket* ThreadedTCP_CreateConnector(
+ const CIPAddr &addr, // Who to connect to.
+ const CIPAddr &localAddr, // Local address to bind to. Leave uninitialized (pass in CIPAddr()) and it will
+ // an interface and a port for you. You can also just fill in the port, and it will
+ // use that port and choose an interface for you.
+ IHandlerCreator *pHandlerCreator// If it connects, it asks this thing to make a handler for the connection.
+ );
+
+
+// Enable or disable timeouts.
+void ThreadedTCP_EnableTimeouts( bool bEnable );
+
+// This should be called at init time. If set to true, it'll set the send and recv threads to low priority.
+// (Default is true).
+void ThreadedTCP_SetTCPSocketThreadPriorities( bool bSetTCPSocketThreadPriorities );
+
+
+#endif // ITHREADEDTCPSOCKET_H