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
173 lines
5.5 KiB
//========= 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
|
|
|