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.
162 lines
4.3 KiB
162 lines
4.3 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
// |
|
//=============================================================================// |
|
|
|
#ifndef IPHELPERS_H |
|
#define IPHELPERS_H |
|
|
|
|
|
#include "ichannel.h" |
|
|
|
|
|
// Loops that poll sockets should Sleep for this amount of time between iterations |
|
// so they don't hog all the CPU. |
|
#define LOOP_POLL_INTERVAL 5 |
|
|
|
|
|
// Useful for putting the arguments into a printf statement. |
|
#define EXPAND_ADDR( x ) (x).ip[0], (x).ip[1], (x).ip[2], (x).ip[3], (x).port |
|
|
|
|
|
// This is a simple wrapper layer for UDP sockets. |
|
class CIPAddr |
|
{ |
|
public: |
|
CIPAddr(); |
|
CIPAddr( const int inputIP[4], const int inputPort ); |
|
CIPAddr( int ip0, int ip1, int ip2, int ip3, int ipPort ); |
|
|
|
void Init( int ip0, int ip1, int ip2, int ip3, int ipPort ); |
|
bool operator==( const CIPAddr &o ) const; |
|
bool operator!=( const CIPAddr &o ) const; |
|
|
|
// Setup to send to the local machine on the specified port. |
|
void SetupLocal( int inPort ); |
|
|
|
public: |
|
|
|
unsigned char ip[4]; |
|
unsigned short port; |
|
}; |
|
|
|
|
|
|
|
// The chunk walker provides an easy way to copy data out of the chunks as though it were a |
|
// single contiguous chunk of memory.s |
|
class CChunkWalker |
|
{ |
|
public: |
|
CChunkWalker( void const * const *pChunks, const int *pChunkLengths, int nChunks ); |
|
|
|
int GetTotalLength() const; |
|
void CopyTo( void *pOut, int nBytes ); |
|
|
|
private: |
|
|
|
void const * const *m_pChunks; |
|
const int *m_pChunkLengths; |
|
int m_nChunks; |
|
|
|
int m_iCurChunk; |
|
int m_iCurChunkPos; |
|
|
|
int m_TotalLength; |
|
}; |
|
|
|
|
|
// This class makes loop that wait on something look nicer. ALL loops using this class |
|
// should follow this pattern, or they can wind up with unforeseen delays that add a whole |
|
// lot of lag. |
|
// |
|
// CWaitTimer waitTimer( 5.0 ); |
|
// while ( 1 ) |
|
// { |
|
// do your thing here like Recv() from a socket. |
|
// |
|
// if ( waitTimer.ShouldKeepWaiting() ) |
|
// Sleep() for some time interval like 5ms so you don't hog the CPU |
|
// else |
|
// BREAK HERE |
|
// } |
|
class CWaitTimer |
|
{ |
|
public: |
|
CWaitTimer( double flSeconds ); |
|
|
|
bool ShouldKeepWaiting(); |
|
|
|
private: |
|
unsigned long m_StartTime; |
|
unsigned long m_WaitMS; |
|
}; |
|
|
|
|
|
// Helper function to get time in milliseconds. |
|
unsigned long SampleMilliseconds(); |
|
|
|
|
|
class ISocket |
|
{ |
|
public: |
|
|
|
// Call this when you're done. |
|
virtual void Release() = 0; |
|
|
|
|
|
// Bind the socket so you can send and receive with it. |
|
// If you bind to port 0, then the system will select the port for you. |
|
virtual bool Bind( const CIPAddr *pAddr ) = 0; |
|
virtual bool BindToAny( const unsigned short port ) = 0; |
|
|
|
|
|
// Broadcast some data. |
|
virtual bool Broadcast( const void *pData, const int len, const unsigned short port ) = 0; |
|
|
|
// Send a packet. |
|
virtual bool SendTo( const CIPAddr *pAddr, const void *pData, const int len ) = 0; |
|
virtual bool SendChunksTo( const CIPAddr *pAddr, void const * const *pChunks, const int *pChunkLengths, int nChunks ) = 0; |
|
|
|
// Receive a packet. Returns the length received or -1 if no data came in. |
|
// If pFrom is set, then it is filled in with the sender's IP address. |
|
virtual int RecvFrom( void *pData, int maxDataLen, CIPAddr *pFrom ) = 0; |
|
|
|
// How long has it been since we successfully received a packet? |
|
virtual double GetRecvTimeout() = 0; |
|
}; |
|
|
|
// Create a connectionless socket that you can send packets out of. |
|
ISocket* CreateIPSocket(); |
|
|
|
// This sets up the socket to receive multicast data on the specified group. |
|
// By default, localInterface is INADDR_ANY, but if you want to specify a specific interface |
|
// the data should come in through, you can. |
|
ISocket* CreateMulticastListenSocket( |
|
const CIPAddr &addr, |
|
const CIPAddr &localInterface = CIPAddr() |
|
); |
|
|
|
|
|
// Setup a CIPAddr from the string. The string can be a dotted IP address or |
|
// a hostname, and it can be followed by a colon and a port number like "1.2.3.4:3443" |
|
// or "myhostname.valvesoftware.com:2342". |
|
// |
|
// Note: if the string does not contain a port, then pOut->port will be left alone. |
|
bool ConvertStringToIPAddr( const char *pStr, CIPAddr *pOut ); |
|
|
|
// Do a DNS lookup on the IP. |
|
// You can optionally get a service name back too. |
|
bool ConvertIPAddrToString( const CIPAddr *pIn, char *pOut, int outLen ); |
|
|
|
|
|
void IP_GetLastErrorString( char *pStr, int maxLen ); |
|
|
|
void SockAddrToIPAddr( const struct sockaddr_in *pIn, CIPAddr *pOut ); |
|
void IPAddrToSockAddr( const CIPAddr *pIn, struct sockaddr_in *pOut ); |
|
|
|
|
|
#endif |
|
|
|
|