This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

| Socket Classes Submitted by

It all started when I wanted to write my own e-mail client program, just for the fun of it. After searching the net for a while (not long), I figured I needed to implement the POP3 and SMTP protocols (client side). These protocols are both layered on top of TCP/IP. The easiest way to access a TCP/IP network is the well known "Berkeley Sockets". On Windows, this takes the form of "Winsock".
You will find in this code of the day a C++ socket wrapper. It provides basic connection/binding mechanisms and I/O streams to easily transmit/receive data. This is the section I would mostly like to have feedback. You will also find wrappers for the infamous SOCKADDR structure and it's Internet variant, SOCKADDR_IN. Finally, there is also a simple and incomplete POP3 client implementation that I used to test the socket class. To test it, simply edit the file "main.cpp" to enter your server's address, username and password.
Have a nice day! Thierry

Currently browsing [socket.zip] (6,762 bytes) - [socket.h] - (6,072 bytes)

    ////////////////////////////////////////////////////////////////////////////////////////
    //
    // Socket
    // Copyright (C) 2000  Thierry Tremblay
    //
    // http://frogengine.net-connect.net/
    //
    ////////////////////////////////////////////////////////////////////////////////////////

    #ifndef TT_SOCKET_H
    #define TT_SOCKET_H

    #include <iostream>

    ////////////////////////////////////////////////////////////////////////////////////////
    //
    // WINSOCK_VERSION: This control which version of winsock is used
    //
    ////////////////////////////////////////////////////////////////////////////////////////

    #ifndef WINSOCK_VERSION
    #define WINSOCK_VERSION    1
    #endif

    #if !(WINSOCK_VERSION >=1 && WINSOCK_VERSION <= 2)
    #error Winsock version not supported
    #endif

    ////////////////////////////////////////////////////////////////////////////////////////
    //
    // Headers
    //
    ////////////////////////////////////////////////////////////////////////////////////////

    #if WINSOCK_VERSION == 1
    #include <winsock.h>
    #else
    #define INCL_WINSOCK_API_TYPEDEFS 1
    #include <winsock2.h>
    #endif

    ////////////////////////////////////////////////////////////////////////////////////////
    //
    // NetworkAddress - This is an interface to a socket address
    //
    ////////////////////////////////////////////////////////////////////////////////////////

    class NetworkAddress
    {
    public:
       virtual ~NetworkAddress() {}

       bool  operator==( const NetworkAddress& other ) const;
       bool  operator!=( const NetworkAddress& other ) const;

       virtual  operator void*() const = 0;
       operator sockaddr*() const                   { return GetSockAddr(); }

       virtual NetworkAddress* Clone() const = 0;
       virtual int             GetFamily() const = 0;
       virtual int             GetSize() const = 0;
       virtual sockaddr*       GetSockAddr() const = 0;
    };

    ////////////////////////////////////////////////////////////////////////////////////////
    //
    // Socket
    //
    ////////////////////////////////////////////////////////////////////////////////////////

    class Socket
    {
    public:

       // Construction / destruction
       Socket( int iAddressFamily = AF_INET, int type = SOCK_STREAM, int protocol = IPPROTO_TCP );
       Socket( SOCKET socket );
       virtual ~Socket();

       // Connection handling
       bool     Accept( Socket** ppSocket, NetworkAddress* pAddress = 0 ) const;
       bool     Bind( const NetworkAddress& address ) const;
       bool     Close();
       bool     Connect( const NetworkAddress& address ) const;
       bool     Listen( int queueSize ) const;

       // Transmission
       int      Receive( char* pBuffer, int lenBuffer, int flags = 0 ) const;
       int      Send( const char* pBuffer, int lenBuffer, int flags = 0 ) const;
       int      ReceiveFrom( char* pBuffer, int lenBuffer, NetworkAddress& address, int flags = 0 ) const;
       int      SendTo( const char* pBuffer, int lenBuffer, const NetworkAddress& address, int flags = 0 ) const;

       // Timeout management
       int      GetReceiveTimeout() const              { return m_recvTimeout; }
       int      GetSendTimeout() const                 { return m_sendTimeout; }
       void     SetReceiveTimeout( int seconds )       { m_recvTimeout = seconds; }
       void     SetSendTimeout( int seconds )          { m_sendTimeout = seconds; }

       // State management
       int      GetLastError() const                   { return m_lastError; }
       bool     IsExceptionPending( int timeout = -1, int usec = 0 ) const;
       bool     IsReadReady( int timeout = -1, int usec = 0 ) const;
       bool     IsWriteReady( int timeout = -1, int usec = 0 ) const;
       bool     SetBlocking( bool bBlocking );

       // Address management
       NetworkAddress*         CreateAddress() const;
       const NetworkAddress&   GetLocalAddress() const;
       const NetworkAddress&   GetRemoteAddress() const;

       // Stream access
       std::istream&           GetInputStream();
       std::ostream&           GetOutputStream();
       std::iostream&          GetIOStream();

    private:

       static bool             s_bInitialized;

       SOCKET                  m_socket;
       mutable int             m_lastError;
       int                     m_addressFamily;
       int                     m_sendTimeout;
       int                     m_recvTimeout;
       mutable NetworkAddress* m_pLocalAddress;
       mutable NetworkAddress* m_pRemoteAddress;

       ////////////////////////////////////////////////////////////////////////////////////////
       // StreamBuffer
       ////////////////////////////////////////////////////////////////////////////////////////

       class StreamBuffer : public std::basic_streambuf<char>
       {
       public:
          StreamBuffer( Socket& socket );
          ~StreamBuffer();

       protected:
          virtual int overflow( int c = EOF );
          virtual int underflow();
          virtual int sync();

       private:
          int         FlushOutput();

          Socket&     m_socket;
          char        m_inputBuffer[512];
          char        m_outputBuffer[512];
       };

       ////////////////////////////////////////////////////////////////////////////////////////
       // Socket Streams
       ////////////////////////////////////////////////////////////////////////////////////////

       class ISocketStream : public std::basic_istream<char>
       {
       public:
          ISocketStream( Socket& socket ) : std::basic_istream<char>( new StreamBuffer( socket ) ) {}
          ~ISocketStream() { delete rdbuf(); }
       };

       class OSocketStream : public std::basic_ostream<char>
       {
       public:
          OSocketStream( Socket& socket ) : std::basic_ostream<char>( new StreamBuffer( socket ) ) {}
          ~OSocketStream() { delete rdbuf(); }
       };

       class IOSocketStream : public std::basic_iostream<char>
       {
       public:
          IOSocketStream( Socket& socket ) : std::basic_iostream<char>( new StreamBuffer( socket ) ) {}
          ~IOSocketStream() { delete rdbuf(); }
       };

       ISocketStream*    m_pIStream;
       OSocketStream*    m_pOStream;
       IOSocketStream*   m_pIOStream;
    };

    #endif

Currently browsing [socket.zip] (6,762 bytes) - [internet.h] - (1,767 bytes)

    ////////////////////////////////////////////////////////////////////////////////////////
    //
    // Socket
    // Copyright (C) 2000  Thierry Tremblay
    //
    // http://frogengine.net-connect.net/
    //
    ////////////////////////////////////////////////////////////////////////////////////////

    #ifndef TT_INTERNET_H
    #define TT_INTERNET_H

    #include "socket.h"

    ////////////////////////////////////////////////////////////////////////////////////////
    //
    // InternetAddress
    //
    ////////////////////////////////////////////////////////////////////////////////////////

    class InternetAddress : public NetworkAddress, public sockaddr_in
    {
    public:
       InternetAddress( unsigned addr = INADDR_ANY, int port = 0 );
       InternetAddress( const char* szHostName, const char* szService, const char* szProtocol = "tcp" );
       InternetAddress( const char* szHostName, int port = 0 );
       InternetAddress( const sockaddr_in& sa );

       // Get methods
       bool            GetHostName( char* buffer, int lenBuffer ) const;
       int             GetPort() const        { return ntohs( sin_port ); }

       // Set methods
       void            SetAddress( const char* szHostName );
       void            SetPort( const char* szService, const char* szProtocol = "tcp" );
       void            SetPort( int port )    { sin_port = htons( port ); }

       // NetworkAddress interface
       operator void*() const                 { return (sockaddr_in*) this; }

       NetworkAddress* Clone() const          { return new InternetAddress( *this ); }
       int             GetFamily() const      { return sin_family; }
       int             GetSize() const        { return sizeof(sockaddr_in); }
       sockaddr*       GetSockAddr() const    { return (sockaddr*)((sockaddr_in*)this); }
    };

    #endif

Currently browsing [socket.zip] (6,762 bytes) - [main.cpp] - (585 bytes)

    ////////////////////////////////////////////////////////////////////////////////////////
    //
    // Socket
    // Copyright (C) 2000  Thierry Tremblay
    //
    // http://frogengine.net-connect.net/
    //
    ////////////////////////////////////////////////////////////////////////////////////////

    #include "pop3.h"

    int main( int argc, char* argv[] )
    {
       POP3Protocol pop3;

       int nbMessage, totalSize;

       pop3.Open( "pop.server.com" );
       pop3.Login( "username", "password" );
       pop3.GetNbMessages( &nbMessage, &totalSize );
       pop3.Quit();
       pop3.Close();

       return 0;
    }

Currently browsing [socket.zip] (6,762 bytes) - [pop3.cpp] - (2,184 bytes)

    ////////////////////////////////////////////////////////////////////////////////////////
    //
    // Socket
    // Copyright (C) 2000  Thierry Tremblay
    //
    // http://frogengine.net-connect.net/
    //
    ////////////////////////////////////////////////////////////////////////////////////////

    #include "pop3.h"

    ////////////////////////////////////////////////////////////////////////////////////////
    //
    // POP3Protocol
    //
    ////////////////////////////////////////////////////////////////////////////////////////

    POP3Protocol::POP3Protocol()
    :  m_socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ),
       m_stream( m_socket.GetIOStream() )
    {
    }

    POP3Protocol::~POP3Protocol()
    {
    }

    bool POP3Protocol::Close()
    {
       return m_socket.Close();
    }

    bool POP3Protocol::GetNbMessages( int* pNbMessage, int* pTotalSize )
    {
       m_stream << "STAT\r" << std::endl;
       m_stream.getline( m_buffer, sizeof(m_buffer) );
       if (!LastCommandOK())
          return false;

       if (sscanf( m_buffer, "+OK %d %d", pNbMessage, pTotalSize ) != 2)
          return false;

       return true;
    }

    bool POP3Protocol::LastCommandOK()
    {
       return strncmp( m_buffer, "+OK", 3 ) == 0;
    }

    bool POP3Protocol::Login( const char* szUser, const char* szPassword )
    {
       m_stream << "USER " << szUser << "\r" << std::endl;
       m_stream.getline( m_buffer, sizeof(m_buffer) );
       if (!LastCommandOK())
          return false;

       m_stream << "PASS " << szPassword << "\r" << std::endl;
       m_stream.getline( m_buffer, sizeof(m_buffer) );
       if (!LastCommandOK())
          return false;

       return true;
    }

    bool POP3Protocol::Open( const char* szHost, int port )
    {
       if (!m_socket.Connect( InternetAddress( szHost, 110 )) )
          return false;

       m_socket.SetReceiveTimeout( 10 );

       m_stream.getline( m_buffer, sizeof(m_buffer) );
       if (!LastCommandOK())
       {
          m_socket.Close();
          return false;
       }

       return true;
    }

    bool POP3Protocol::Quit()
    {
       m_stream << "QUIT\r" << std::endl;
       m_stream.getline( m_buffer, sizeof(m_buffer) );
       if (!LastCommandOK())
       {
          m_socket.Close();
          return false;
       }

       return true;
    }

Currently browsing [socket.zip] (6,762 bytes) - [pop3.h] - (1,288 bytes)

    ////////////////////////////////////////////////////////////////////////////////////////
    //
    // Socket
    // Copyright (C) 2000  Thierry Tremblay
    //
    // http://frogengine.net-connect.net/
    //
    ////////////////////////////////////////////////////////////////////////////////////////

    #ifndef TT_POP3_H
    #define TT_POP3_H

    #include "socket.h"
    #include "internet.h"

    ////////////////////////////////////////////////////////////////////////////////////////
    //
    // POP3Protocol
    //
    // Reference: RFC 1725
    //
    ////////////////////////////////////////////////////////////////////////////////////////

    class POP3Protocol
    {
    public:
       POP3Protocol();
       ~POP3Protocol();

       // Connects to a POP3 server
       bool  Open( const char* szHost, int port = 110 );

       // Closes the connection
       bool  Close();

       // Returns if last command succeeded or failed
       bool  LastCommandOK();

       // Login
       bool  Login( const char* szUser, const char* szPassword );

       // Quit
       bool  Quit();

       // Get the number of messages available and their total size
       bool  GetNbMessages( int* pNbMessage, int* pTotalSize );

    private:

       char              m_buffer[1024];
       Socket            m_socket;
       std::iostream&    m_stream;
    };

    #endif

Currently browsing [socket.zip] (6,762 bytes) - [socket.cpp] - (11,250 bytes)

    ////////////////////////////////////////////////////////////////////////////////////////
    //
    // Socket
    // Copyright (C) 2000  Thierry Tremblay
    //
    // http://frogengine.net-connect.net/
    //
    ////////////////////////////////////////////////////////////////////////////////////////

    #include "socket.h"
    #include "internet.h"
    #include <cassert>

    ////////////////////////////////////////////////////////////////////////////////////////
    //
    // Automatically link the proper library
    //
    ////////////////////////////////////////////////////////////////////////////////////////

    #ifdef _MSC_VER

    #if WINSOCK_VERSION == 1
    #pragma comment( lib, "wsock32" )
    #elif WINSOCK_VERSION == 2
    #pragma comment( lib, "ws2_32" );
    #endif

    #endif

    ////////////////////////////////////////////////////////////////////////////////////////
    //
    // NetworkAddress - This is an interface to a socket address
    //
    ////////////////////////////////////////////////////////////////////////////////////////

    bool NetworkAddress::operator==( const NetworkAddress& other ) const
    {
       int size = GetSize();

       if (size != other.GetSize())
          return false;

       return memcmp( *this, other, size ) == 0;
    }

    bool NetworkAddress::operator!=( const NetworkAddress& other ) const
    {
       int size = GetSize();

       if (size != other.GetSize())
          return true;

       return memcmp(*this, other, size) != 0;
    }

    ////////////////////////////////////////////////////////////////////////////////////////
    //
    // Socket
    //
    ////////////////////////////////////////////////////////////////////////////////////////

    bool Socket::s_bInitialized = false;

    Socket::Socket( int iAddressFamily, int type, int protocol )
    :  m_socket(INVALID_SOCKET),
       m_lastError(0),
       m_addressFamily(iAddressFamily),
       m_recvTimeout(-1),
       m_sendTimeout(-1),
       m_pLocalAddress(0),
       m_pRemoteAddress(0),
       m_pIStream(0),
       m_pOStream(0),
       m_pIOStream(0)
    {
       if (!s_bInitialized)
       {
          WSADATA data;
          WORD version;

    #if WINSOCK_VERSION == 1
          version = MAKEWORD(1,1);
    #elif WINSOCK_VERSION == 2
          version = MAKEWORD(2,2);
    #endif

          m_lastError = WSAStartup( version, &data );
          if (m_lastError == 0)
             s_bInitialized = true;
       }

       if (m_lastError == 0)
       {
          m_socket = socket( iAddressFamily, type, protocol );
          if (m_socket == INVALID_SOCKET)
          {
             m_lastError = WSAGetLastError();
          }
       }
    }

    Socket::Socket( SOCKET socket )
    :  m_socket(socket),
       m_lastError(0),
       m_addressFamily(AF_UNSPEC),
       m_recvTimeout(-1),
       m_sendTimeout(-1),
       m_pLocalAddress(0),
       m_pRemoteAddress(0),
       m_pIStream(0),
       m_pOStream(0),
       m_pIOStream(0)
    {
       // Discover address family
       BYTE address[1024];
       int lenAddress = sizeof(address);

       if (getsockname( m_socket, (sockaddr*)address, &lenAddress ) == SOCKET_ERROR)
       {
          m_lastError = WSAGetLastError();
       }
       else
       {
          m_addressFamily = ((SOCKADDR*)address)->sa_family;
       }
    }

    Socket::~Socket()
    {
       if (m_pIStream)
          delete m_pIStream;

       if (m_pOStream)
          delete m_pOStream;

       if (m_pIOStream)
          delete m_pIOStream;

       if (m_socket != INVALID_SOCKET)
          Close();

       if (m_pLocalAddress)
          delete m_pLocalAddress;

       if (m_pRemoteAddress)
          delete m_pRemoteAddress;
    }

    bool Socket::Accept( Socket** ppSocket, NetworkAddress* pAddress ) const
    {
       SOCKET socket;

       if (pAddress)
       {
          assert( pAddress->GetFamily() == m_addressFamily );

          int size = pAddress->GetSize();
          socket = accept( m_socket, *pAddress, &size );
       }
       else
       {
          socket = accept( m_socket, 0, 0 );
       }

       if (socket == INVALID_SOCKET)
       {
          *ppSocket = 0;
          m_lastError = WSAGetLastError();
          return false;
       }

       *ppSocket = new Socket( socket );
       return true;
    }

    bool Socket::Bind( const NetworkAddress& address ) const
    {
       if (bind( m_socket, address, address.GetSize() ) == SOCKET_ERROR)
       {
          m_lastError = WSAGetLastError();
          return false;
       }
       return true;
    }

    bool Socket::Close()
    {
       if (closesocket(m_socket) == SOCKET_ERROR)
       {
          m_lastError = WSAGetLastError();
          return false;
       }
       m_socket = INVALID_SOCKET;
       return true;
    }

    bool Socket::Connect( const NetworkAddress& address ) const
    {
       if (connect( m_socket, address, address.GetSize() ) == SOCKET_ERROR)
       {
          m_lastError = WSAGetLastError();
          return false;
       }
       return true;
    }

    NetworkAddress* Socket::CreateAddress() const
    {
       if (m_addressFamily == AF_INET)
          return new InternetAddress();

       // Unsupported address family
       assert(0);

       return 0;
    }

    std::istream& Socket::GetInputStream()
    {
       if (m_pIStream==0)
       {
          m_pIStream = new ISocketStream( *this );
          if (m_pOStream)
             m_pIStream->tie( m_pOStream );
       }

       return *m_pIStream;
    }

    std::ostream& Socket::GetOutputStream()
    {
       if (m_pOStream==0)
       {
          m_pOStream = new OSocketStream( *this );
          if (m_pIStream)
             m_pIStream->tie( m_pOStream );
       }

       return *m_pOStream;
    }

    std::iostream& Socket::GetIOStream()
    {
       if (m_pIOStream==0)
       {
          m_pIOStream = new IOSocketStream( *this );
       }

       return *m_pIOStream;
    }

    const NetworkAddress& Socket::GetLocalAddress() const
    {
       if (m_pLocalAddress==0)
          m_pLocalAddress = CreateAddress();

       int lenAddress = m_pLocalAddress->GetSize();
       if (getsockname( m_socket, m_pLocalAddress->GetSockAddr(), &lenAddress ) == SOCKET_ERROR)
       {
          m_lastError = WSAGetLastError();
       }

       return *m_pLocalAddress;
    }

    const NetworkAddress& Socket::GetRemoteAddress() const
    {
       if (m_pRemoteAddress==0)
          m_pRemoteAddress = CreateAddress();

       int lenAddress = m_pRemoteAddress->GetSize();
       if (getpeername( m_socket, m_pRemoteAddress->GetSockAddr(), &lenAddress ) == SOCKET_ERROR)
       {
          m_lastError = WSAGetLastError();
       }

       return *m_pRemoteAddress;
    }

    bool Socket::IsExceptionPending( int sec, int usec ) const
    {
       fd_set fds;

       FD_ZERO( &fds );
       FD_SET( m_socket, &fds );

       timeval tv;
       tv.tv_sec  = sec;
       tv.tv_usec = usec;

       int result = select( m_socket+1, 0, 0, &fds, &tv );

       if (result == 0 || result == SOCKET_ERROR)
       {
          m_lastError = WSAGetLastError();
          return false;
       }

       return true;
    }

    bool Socket::IsReadReady( int sec, int usec ) const
    {
       fd_set fds;

       FD_ZERO( &fds );
       FD_SET( m_socket, &fds );

       timeval tv;
       tv.tv_sec  = sec;
       tv.tv_usec = usec;

       int result = select( m_socket+1, &fds, 0, 0, &tv );

       if (result == 0 || result == SOCKET_ERROR)
       {
          m_lastError = WSAGetLastError();
          return false;
       }

       return true;
    }

    bool Socket::IsWriteReady( int sec, int usec ) const
    {
       fd_set fds;

       FD_ZERO( &fds );
       FD_SET( m_socket, &fds );

       timeval tv;
       tv.tv_sec  = sec;
       tv.tv_usec = usec;

       int result = select( m_socket+1, 0, &fds, 0, &tv );

       if (result == 0 || result == SOCKET_ERROR)
       {
          m_lastError = WSAGetLastError();
          return false;
       }

       return true;
    }

    bool Socket::Listen( int queueSize ) const
    {
       if (listen( m_socket, queueSize ) == SOCKET_ERROR)
       {
          m_lastError = WSAGetLastError();
          return false;
       }
       return true;
    }

    int Socket::Receive( char* pBuffer, int lenBuffer, int flags ) const
    {
       if (m_recvTimeout >= 0 && !IsReadReady( m_recvTimeout ))
          return 0;

       int nbRecv = recv( m_socket, pBuffer, lenBuffer, flags );
       if (nbRecv == SOCKET_ERROR)
       {
          int error = WSAGetLastError();

          if (error == WSAEMSGSIZE)
             return lenBuffer;

          m_lastError = error;
          return 0;
       }
       return nbRecv;
    }

    int Socket::ReceiveFrom( char* pBuffer, int lenBuffer, NetworkAddress& address, int flags ) const
    {
       if (m_recvTimeout >= 0 && !IsReadReady( m_recvTimeout ))
          return 0;

       assert( address.GetFamily() == m_addressFamily );

       int addressSize = address.GetSize();
       int nbRecv = recvfrom( m_socket, pBuffer, lenBuffer, flags, address, &addressSize );
       if (nbRecv == SOCKET_ERROR)
       {
          int error = WSAGetLastError();

          if (error == WSAEMSGSIZE)
             return lenBuffer;

          m_lastError = error;
          return 0;
       }
       return nbRecv;
    }

    int Socket::Send( const char* pBuffer, int lenBuffer, int flags ) const
    {
       if (m_sendTimeout >= 0 && !IsWriteReady( m_sendTimeout ))
          return 0;

       int nbSent = send( m_socket, pBuffer, lenBuffer, flags );
       if (nbSent == SOCKET_ERROR)
       {
          m_lastError = WSAGetLastError();
          return 0;
       }
       return nbSent;
    }

    int Socket::SendTo( const char* pBuffer, int lenBuffer, const NetworkAddress& address, int flags ) const
    {
       if (m_sendTimeout >= 0 && !IsWriteReady( m_sendTimeout ))
          return 0;

       int nbSent = sendto( m_socket, pBuffer, lenBuffer, flags, address, address.GetSize() );
       if (nbSent == SOCKET_ERROR)
       {
          m_lastError = WSAGetLastError();
          return 0;
       }
       return nbSent;
    }

    bool Socket::SetBlocking( bool bBlocking )
    {
       ULONG param = bBlocking ? 1 : 0;

       if (ioctlsocket( m_socket, FIONBIO, ¶m ) == SOCKET_ERROR)
       {
          m_lastError = WSAGetLastError();
          return false;
       }
       return true;
    }

    ////////////////////////////////////////////////////////////////////////////////////////
    //
    // Socket::StreamBuffer
    //
    ////////////////////////////////////////////////////////////////////////////////////////

    Socket::StreamBuffer::StreamBuffer( Socket& socket )
    :  m_socket( socket )
    {
       char* pBeginInput = m_inputBuffer;
       char* pEndInput   = m_inputBuffer + sizeof(m_inputBuffer);

       setg( pBeginInput, pEndInput, pEndInput );
       setp( m_outputBuffer, m_outputBuffer + sizeof(m_outputBuffer) );
    }

    Socket::StreamBuffer::~StreamBuffer()
    {
       FlushOutput();
    }

    int Socket::StreamBuffer::FlushOutput()
    {
       // Return 0 if nothing to flush or success
       // Return EOF if couldnt flush

       if (pptr() < pbase())
          return 0;

       if (!m_socket.Send( pbase(), pptr() - pbase() ))
          return EOF;

       setp( m_outputBuffer, m_outputBuffer + sizeof(m_outputBuffer) );

       return 0;
    }

    int Socket::StreamBuffer::overflow( int c )
    {
       if (c == EOF)
          return FlushOutput();

       *pptr() = c;
       pbump(1);

       if (c == '\n' || pptr() >= epptr())
       {
          if (FlushOutput() == EOF)
             return EOF;
       }

       return c;
    }

    int Socket::StreamBuffer::sync()
    {
       return FlushOutput();
    }

    int Socket::StreamBuffer::underflow()
    {
       if (gptr() < egptr())
          return *(unsigned char*)gptr();

       int nbRead = m_socket.Receive( m_inputBuffer, sizeof(m_inputBuffer) );

       if (nbRead == 0)
          return EOF;

       setg( eback(), eback(), eback() + nbRead );

       return *(unsigned char*)gptr();
    }

Currently browsing [socket.zip] (6,762 bytes) - [internet.cpp] - (2,315 bytes)

    ////////////////////////////////////////////////////////////////////////////////////////
    //
    // Socket
    // Copyright (C) 2000  Thierry Tremblay
    //
    // http://frogengine.net-connect.net/
    //
    ////////////////////////////////////////////////////////////////////////////////////////

    #include "internet.h"

    ////////////////////////////////////////////////////////////////////////////////////////
    //
    // InternetAddress
    //
    ////////////////////////////////////////////////////////////////////////////////////////

    InternetAddress::InternetAddress( unsigned addr, int port )
    {
       sin_family      = AF_INET;
       sin_addr.s_addr = htonl( addr );
       sin_port        = htons( port );
    }

    InternetAddress::InternetAddress( const char* szHostName, const char* szService, const char* szProtocol )
    {
       SetAddress( szHostName );
       SetPort( szService, szProtocol );
    }

    InternetAddress::InternetAddress( const char* szHostName, int port )
    {
       SetAddress( szHostName );
       sin_port = htons( port );
    }

    InternetAddress::InternetAddress( const sockaddr_in& sa )
    {
       *(sockaddr_in*)this = sa;
    }

    bool InternetAddress::GetHostName( char* buffer, int lenBuffer ) const
    {
       if (sin_addr.s_addr == INADDR_ANY)
       {
          if (gethostname( buffer, lenBuffer ) == SOCKET_ERROR)
          {
             buffer[0] = 0;
             return false;
          }
       }
       else
       {
          const HOSTENT* pHost = gethostbyaddr( (const char*)&sin_addr, sizeof(sin_addr), AF_INET);
          if (pHost == 0 || pHost->h_name == 0)
          {
             buffer[0] = 0;
             return false;
          }

          strncpy( buffer, pHost->h_name, lenBuffer );
       }

       return true;
    }

    void InternetAddress::SetAddress( const char* szHostName )
    {
       sin_family      = AF_INET;
       sin_addr.s_addr = inet_addr( szHostName );

       if (sin_addr.s_addr == INADDR_NONE)
       {
          const HOSTENT* pHost = gethostbyname( szHostName );
          if (pHost != 0)
          {
             sin_addr = *(IN_ADDR*)pHost->h_addr_list[0];
          }
       }
    }

    void InternetAddress::SetPort( const char* szService, const char* szProtocol )
    {
       sin_port = 0;

       const SERVENT* pService = getservbyname( szService, szProtocol );

       if (pService != 0)
       {
          sin_port = pService->s_port;
       }
    }

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.