Filer jeg kunne forestille mig den kunne være gal i:
IPAddress.h#ifndef IPADDRESS_H_INCLUDED
#define IPADDRESS_H_INCLUDED
#include <string>
#include <vector>
#include "Types.h"
#if defined(_WIN32)
    #include <winsock2.h>
#elif defined(__linux__)
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
#endif
using namespace std;
class IPAddress
{
    public:
        //Opretter IPAddress ud fra entent ip, eller host navn
        IPAddress(string & adr);
        //Opretter IPAdress ud fra en in_addr struct
        IPAddress(struct in_addr adr);
        // Hvor mange addresser der er tilnyttet
        UInt32 numAddresses();
        //Returnere addressen med det givne index i in_addr
        struct in_addr getAddress(UInt32 index);
        //Rteurnere addressen med det givne index som streng
        string getAddressString(UInt32 index);
        //Hvor mange aliaser der er tilknyttet
        UInt32 numAliases();
        //Returnere aliaset med det givne index
        string getAlias(UInt32 index);
        //Returnere der officile navn
        string getOfficialName();
        operator string();
    private:
        //Laver opslaget fra in_addr
        void fromInAddr(struct in_addr adr);
        typedef vector<string> StringVector;
        typedef vector<struct in_addr> InAddrVector;
        StringVector m_aliases;
        InAddrVector m_addresses;
        string m_officialName;
};
#endif // IPADDRESS_H_INCLUDED
IPAddress.cpp#include "IPAddress.h"
#include "NetException.h"
#include "UnknownHostException.h"
#if defined(__linux__)
    extern int h_errno;
#elif defined(_WIN32)
    #include <windows.h>
#endif
IPAddress::IPAddress(string & adr)
{
    struct in_addr adrIn;
    struct hostent * entity;
#if defined(__linux__)
    int error = inet_aton(adr.c_str(), &adrIn);
    if(error == 0)
#elif defined(_WIN32)
    adrIn.S_un.S_addr = inet_addr(adr.c_str());
    if(adrIn.S_un.S_addr == INADDR_NONE && adr != "255.255.255.255")
#endif
    {
        entity = gethostbyname(adr.c_str());
        if(entity == NULL)
        {
        #if defined(__linux__)
            switch(h_errno)
            {
                case HOST_NOT_FOUND:
                    throw UnknownHostException(hstrerror(h_errno));
                    break;
                default:
                    throw NetException(hstrerror(h_errno));
                    break;
            }
        #elif defined(_WIN32)
            LPVOID lpMsgBuf;
            int err = WSAGetLastError();
            FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                          FORMAT_MESSAGE_FROM_SYSTEM |
                          FORMAT_MESSAGE_IGNORE_INSERTS,
                          NULL,
                          err,
                          MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                          (LPSTR) &lpMsgBuf,
                          0,
                          NULL);
            string description = (char*) lpMsgBuf;
            LocalFree(lpMsgBuf);
            switch(err)
            {
                case WSAHOST_NOT_FOUND:
                    throw UnknownHostException(description);
                    break;
                default:
                    throw NetException(description);
                    break;
            }
        #endif
        }
        else
        {
            int i = 0;
            m_officialName = string(entity->h_name);
            while(entity->h_aliases[i])
            {
                string alias = entity->h_aliases[i];
                m_aliases.push_back(alias);
                i++;
            }
            i = 0;
            while(entity->h_addr_list[i])
            {
                struct in_addr inAdr = *((struct in_addr*) entity->h_addr_list[i]);
                m_addresses.push_back(inAdr);
                i++;
            }
        }
    }
    else
        fromInAddr(adrIn);
}
IPAddress::IPAddress(struct in_addr adr)
{
    fromInAddr(adr);
}
UInt32 IPAddress::numAddresses()
{
    return m_addresses.size();
}
struct in_addr IPAddress::getAddress(UInt32 index)
{
    return m_addresses[index];
}
string IPAddress::getAddressString(UInt32 index)
{
    return string(inet_ntoa(m_addresses[index]));
}
UInt32 IPAddress::numAliases()
{
    return m_aliases.size();
}
string IPAddress::getAlias(UInt32 index)
{
    return m_aliases[index];
}
string IPAddress::getOfficialName()
{
    return m_officialName;
}
IPAddress::operator string()
{
    return m_officialName;
}
void IPAddress::fromInAddr(struct in_addr adr)
{
    struct hostent * entity;
    entity = gethostbyaddr((char*)&adr, sizeof(adr), AF_INET);
    if(entity != NULL)
    {
        int i = 0;
        m_officialName = string(entity->h_name);
        while(entity->h_aliases[i])
        {
            string alias = entity->h_aliases[i];
            m_aliases.push_back(alias);
            i++;
        }
        i = 0;
        while(entity->h_addr_list[i])
        {
            struct in_addr inAdr = *((struct in_addr*) entity->h_addr_list[i]);
            m_addresses.push_back(inAdr);
            i++;
        }
    }
    else
    {
        m_addresses.push_back(adr);
        m_officialName = getAddressString(0);
    }
}
TCPSocket.h#ifndef TCPSOCKET_H_INCLUDED
#define TCPSOCKET_H_INCLUDED
#include "IPAddress.h"
class TCPSocket
{
    friend class TCPServerSocket;
    public:
        TCPSocket(IPAddress & adr, UInt16 port, UInt32 timeOut = 0);
        TCPSocket(string & adr, UInt16 port, UInt32 timeOut = 0);
        ~TCPSocket();
        void setTimeOut(UInt32 timeOut);
        void connect();
        SInt32 read(void * buffer, SInt32 size);
        SInt32 write(const void * buffer, SInt32 size);
        void close();
        IPAddress * getAddress();
        UInt16 getPort();
        UInt32 getTimeOut();
    private:
        TCPSocket(int socket, struct sockaddr_in sock_addr, UInt32 timeOut = 0);
        void waitForData();
        IPAddress m_address;
        UInt16 m_port;
        UInt32 m_timeOut;
        int m_socket;
};
#endif // TCPSOCKET_H_INCLUDED
TCPSocket.cpp//TCPSocket.cpp
#include "TCPSocket.h"
#include "NetException.h"
#include "ConnectionLostException.h"
#include "TimerException.h"
#if defined(__linux__)
#include <unistd.h>
#endif
TCPSocket::TCPSocket(int socket, struct sockaddr_in sock_addr, UInt32 timeOut)
  : m_address(sock_addr.sin_addr), m_port(ntohs(sock_addr.sin_port)), m_socket(socket), m_timeOut(timeOut)
{
}
TCPSocket::TCPSocket(IPAddress & adr, UInt16 port, UInt32 timeOut)
    : m_address(adr), m_port(port), m_socket(0), m_timeOut(timeOut)
{
}
TCPSocket::TCPSocket(string & adr, UInt16 port, UInt32 timeOut)
    : m_address(adr), m_port(port), m_socket(0), m_timeOut(timeOut)
{
}
TCPSocket::~TCPSocket()
{
  //Hvis m_socket ikke er 0, er vi stadig forbundet
  if(m_socket != 0)
  {
    close();
  }
}
void TCPSocket::setTimeOut(UInt32 timeOut)
{
  m_timeOut = timeOut;
}
void TCPSocket::connect()
{
  //Denne struktur bruger vi til at forbinde mod
  struct sockaddr_in adr_srvr;
  //Denne tæller bruges til looping
  UInt32 i;
  //Denne variabel bruges til at tjekke for fejl
  int error;
  //Hvis m_socket ikke er 0 er vi allerede forbundet
  if(m_socket != 0)
  {
    throw NetException("Already connected.");
  }
  //Opret en socket
  m_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
#if defined(__linux__)
  if(m_socket == -1)
  {
    throw NetException(strerror(h_errno));
  }
#elif defined(_WIN32)
  if(m_socket == INVALID_SOCKET)
  {
    LPVOID lpMsgBuf;
    int err = WSAGetLastError();
    FormatMessage(
      FORMAT_MESSAGE_ALLOCATE_BUFFER |
      FORMAT_MESSAGE_FROM_SYSTEM |
      FORMAT_MESSAGE_IGNORE_INSERTS,
      NULL,
      err,
      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      (LPTSTR) &lpMsgBuf,
      0,
      NULL
    );
    string description((char*)lpMsgBuf);
    LocalFree( lpMsgBuf );
    throw NetException(description);
  }
#endif
  //Nulstil adressen
  memset(&adr_srvr,0,sizeof(adr_srvr));
  //Sæt adresse familie
  adr_srvr.sin_family = AF_INET;
  //Sæt port
  adr_srvr.sin_port = htons(m_port);
  //Vi bliver ved med at prøve at forbinde til alle adresser
  //eller til det lykkes
  error = -1;
  i = 0;
  while(error == -1 && i < m_address.numAddresses())
  {
    //Prøv med adresse nummer 'i'
    adr_srvr.sin_addr = m_address.getAddress(i);
    //Prøv at forbinde
    error = ::connect(m_socket, (sockaddr*)&adr_srvr, sizeof(adr_srvr));
    //Tæl 'i' op så vi næste gang tager næste adresse
    i++;
  }
  //Hvis 'error' er -1 kunne vi ikke forbinde til nogen adresse
  if(error == -1)
  {
    //Frigiv først vores socket
    close();
    //Kast derefter en exception
#if defined(__linux__)
    throw NetException(strerror(h_errno));
#elif defined(_WIN32)
    LPVOID lpMsgBuf;
    int err = WSAGetLastError();
    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        err,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0,
        NULL
    );
    string description((char*)lpMsgBuf);
    LocalFree( lpMsgBuf );
    throw NetException(description);
#endif
  }
}
SInt32 TCPSocket::read(void * buffer, SInt32 size)
{
  //Denne variabel indeholder antallet af bytes
  //som vi læser
  SInt32 bytesRead;
  //Vent først på data
  waitForData();
  //Hvis vi nåede til denne linje er der data til os
  bytesRead = recv(m_socket,(char*)buffer,size,0);
  //Hvis 'bytesRead' er -1, gik noget galt
  if(bytesRead == -1)
  {
#if defined(__linux__)
    throw NetException(strerror(h_errno));
#elif defined(_WIN32)
    LPVOID lpMsgBuf;
    int err = WSAGetLastError();
    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        err,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0,
        NULL
    );
    string description((char*)lpMsgBuf);
    LocalFree( lpMsgBuf );
    throw NetException(description);
#endif
  }
  //Hvis vi læste 0 bytes er forbindelsen stoppet
  else if(bytesRead == 0)
  {
    throw ConnectionLostException("Connection reset by peer.");
  }
  return bytesRead;
}
SInt32 TCPSocket::write(const void * buffer, SInt32 size)
{
  SInt32 bytesWritten = send(m_socket,(char*)buffer,size,0);
  //Hvis 'bytesWritten' er -1 gik noget galt
  if(bytesWritten == -1)
  {
#if defined(__linux__)
    throw NetException(strerror(h_errno));
#elif defined(_WIN32)
    LPVOID lpMsgBuf;
    int err = WSAGetLastError();
    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        err,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0,
        NULL
    );
    string description((char*)lpMsgBuf);
    LocalFree( lpMsgBuf );
    throw NetException(description);
#endif
  }
  return bytesWritten;
}
void TCPSocket::close()
{
  //Frigiv kun hvis vi har en socket
  if(m_socket != 0)
  {
#if defined(__linux__)
    ::close(m_socket);
#elif defined(_WIN32)
    closesocket(m_socket);
#endif
    m_socket = 0;
  }
}
void TCPSocket::waitForData()
{
  fd_set set;
  struct timeval timeout;
  int err;
  FD_ZERO(&set);
  FD_SET(m_socket,&set);
  //Hvis m_timeOut er større end 0
  if(m_timeOut > 0)
  {
    //Specificér hvor lang tid vi skal vente
    timeout.tv_sec = (unsigned int)(m_timeOut / 1000);
    timeout.tv_usec = (unsigned int)(m_timeOut % 1000) * 1000;
    err = select(FD_SETSIZE,&set,NULL,NULL,&timeout);
  }
  else
  {
    //Vent til der er data eller til forbindelsen bliver lukket
    err = select(FD_SETSIZE,&set,NULL,NULL,NULL);
  }
  //Hvis 'err' er 0 er tiden gået
  if(err == 0)
  {
    throw TimerException("Timer timed out");
  }
  //Eller hvis 'err' er -1, er der gået noget galt
  else if(err == -1)
  {
#if defined(__linux__)
      throw NetException(strerror(h_errno));
#elif defined(_WIN32)
    LPVOID lpMsgBuf;
    int err = WSAGetLastError();
    FormatMessage(
      FORMAT_MESSAGE_ALLOCATE_BUFFER |
      FORMAT_MESSAGE_FROM_SYSTEM |
      FORMAT_MESSAGE_IGNORE_INSERTS,
      NULL,
      err,
      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      (LPTSTR) &lpMsgBuf,
      0,
      NULL
    );
    string description((char*)lpMsgBuf);
    LocalFree( lpMsgBuf );
    throw NetException(description);
#endif
  }
}
IPAddress * TCPSocket::getAddress()
{
  return &m_address;
}
UInt16 TCPSocket::getPort()
{
  return m_port;
}
UInt32 TCPSocket::getTimeOut()
{
  return m_timeOut;
}
Og en copy pastet main.cpp//main.cpp
#include "Net.h"
#include "UnknownHostException.h"
#include "NetException.h"
#include "ConnectionLostException.h"
#include "TCPSocket.h"
#include <iostream>
#if defined(__linux__)
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#endif
using namespace std;
void connectAndRead(string host)
{
  //Denne buffer kommer til at indeholde, hvad vi læser
  char buffer[1024];
  //Denne variabel fortæller os, hvor mange bytes vi læser
  int bytesRead;
  //Lav et socket objekt uden timeout
  TCPSocket sock(host,80);
  //Forbind
  sock.connect();
  //HTTP request
  string toSay = string("GET / HTTP/1.1\\r\\nHost: ") + host + string("\\r\\nConnection: close\\r\\n\\r\\n");
  sock.write(toSay.c_str(),toSay.size());
  try
  {
    //Denne løkke forlades, når forbindelsen lukkes
    while(1)
    {
      //Læs til buffer
      bytesRead = sock.read(buffer,sizeof(buffer));
      //Skriv til standard out
      cout.write(buffer,bytesRead);
      cout.flush();
    }
  } catch (ConnectionLostException & cle)
  {
    //Serveren stoppede forbindelsen. Dette lader os bare forlade den
    //ellers uendelige løkke
    cout << cle << endl;
  }
  sock.close();
}
int main(int argc, char ** argv)
{
  //Tjek om der er parametre
  if(argc == 1)
  {
    cout << "Brug: " << argv[0] << " <IP|host>" << endl;
  }
  else
  {
    //netInit kan kaste exceptions
    try
    {
      //Initialisér net komponenten
      netInit();
      try
      {
        string adrstr(argv[1]);
        //Læs en hjemmeside
        connectAndRead(adrstr);
      } catch (NetException & nex)
      {
        cout << nex << endl;
      }
      //Frigiv net komponenten
      netRelease();
    } catch (NetException ex)
    {
      cerr << "Kunne ikke initialisere net komponenten: " << ex << endl;
    }
  }
  return 0;
}