1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
// --------------------------------------------------------------------------
//
// File
// Name: SocketStream.h
// Purpose: I/O stream interface for sockets
// Created: 2003/07/31
//
// --------------------------------------------------------------------------
#ifndef SOCKETSTREAM__H
#define SOCKETSTREAM__H
#include <climits>
#ifdef HAVE_SYS_POLL_H
# include <sys/poll.h>
#endif
#include "BoxTime.h"
#include "IOStream.h"
#include "Socket.h"
#ifdef WIN32
typedef SOCKET tOSSocketHandle;
#define INVALID_SOCKET_VALUE (tOSSocketHandle)(-1)
#else
typedef int tOSSocketHandle;
#define INVALID_SOCKET_VALUE -1
#endif
// --------------------------------------------------------------------------
//
// Class
// Name: SocketStream
// Purpose: Stream interface for sockets
// Created: 2003/07/31
//
// --------------------------------------------------------------------------
class SocketStream : public IOStream
{
public:
SocketStream();
SocketStream(int socket);
SocketStream(const SocketStream &rToCopy);
~SocketStream();
void Open(Socket::Type Type, const std::string& rName, int Port = 0);
void Attach(int socket);
virtual int Read(void *pBuffer, int NBytes, int Timeout = IOStream::TimeOutInfinite);
virtual void Write(const void *pBuffer, int NBytes,
int Timeout = IOStream::TimeOutInfinite);
// Why not inherited from IOStream? Never mind, we want to enforce
// supplying a timeout for network operations anyway.
virtual void Write(const std::string& rBuffer, int Timeout)
{
IOStream::Write(rBuffer, Timeout);
}
virtual void Close();
virtual bool StreamDataLeft();
virtual bool StreamClosed();
virtual void Shutdown(bool Read = true, bool Write = true);
virtual bool GetPeerCredentials(uid_t &rUidOut, gid_t &rGidOut);
protected:
void MarkAsReadClosed() {mReadClosed = true;}
void MarkAsWriteClosed() {mWriteClosed = true;}
void CheckForMissingTimeout(int Timeout);
// Converts a timeout in milliseconds (or IOStream::TimeOutInfinite)
// into one that can be passed to poll() (also in milliseconds), also
// compensating for time elapsed since the wait should have started,
// if known.
int PollTimeout(int timeout, box_time_t start_time)
{
if (timeout == IOStream::TimeOutInfinite)
{
return INFTIM;
}
if (start_time == 0)
{
return timeout; // no adjustment possible
}
box_time_t end_time = start_time + MilliSecondsToBoxTime(timeout);
box_time_t now = GetCurrentBoxTime();
box_time_t remaining = end_time - now;
if (remaining < 0)
{
return 0; // no delay
}
else if (BoxTimeToMilliSeconds(remaining) > INT_MAX)
{
return INT_MAX;
}
else
{
return (int) BoxTimeToMilliSeconds(remaining);
}
}
bool Poll(short Events, int Timeout);
private:
tOSSocketHandle mSocketHandle;
bool mReadClosed;
bool mWriteClosed;
protected:
off_t mBytesRead;
off_t mBytesWritten;
std::string mPeerSocketDesc;
public:
off_t GetBytesRead() const {return mBytesRead;}
off_t GetBytesWritten() const {return mBytesWritten;}
void ResetCounters() {mBytesRead = mBytesWritten = 0;}
bool IsOpened() { return mSocketHandle != INVALID_SOCKET_VALUE; }
/**
* Only for use by NiceSocketStream!
*/
tOSSocketHandle GetSocketHandle();
};
#endif // SOCKETSTREAM__H
|