143 lines
4.5 KiB
C++
143 lines
4.5 KiB
C++
//========= 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
|