Ciao e grazie della tua risposta ora mi è più chiaro. Ogni giorno capisco sempre qualcosa in più.
Oggi ho fatto delle prove come mi hai detto tu passando new_sock come copia. Il problema è che se lo passo come copia la funzione serviceroutine non funziona e errno sulla socket mi restituisce un "Bad file descriptor" ora credo che questo sia dovuto a come è fatta la classe socket.
Ti dico che questa l'ho trovata in internet e non l'ho compresa fino in fondo. Quindi ti chiederei se puoi darmi una mano a comprenderla.


codice:
// Definition of the Socket class

#ifndef Socket_class
#define Socket_class

#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <string>
#include <arpa/inet.h>


const int MAXHOSTNAME = 200;
const int MAXCONNECTIONS = 5;
const int MAXRECV = 500;

using namespace std;

class Socket
{
public:
    Socket();
    virtual ~Socket();

    // Server initialization
    /**
    *\brief Imposta il socket e le sue opzioni
    *\return true se l'operazione ha avuto successo
    */
    bool create();
    /**
    *\brief Effettua il binding in caso di server
    *\param [in] port contiene la porta sulla quale effettuare il binding
    *\return true se l'operazione ha avuto successo
    */
    bool bind ( const long port );
    /**
    *\brief Imposta il socket in modalità ascolto.
    *\return true se l'operazione ha avuto successo
    */
    bool listen() const;
    /**
    *\brief permette di accettare connessioni in ingresso sulla porta sulla quale si è in ascolto
    *\param [out] Socket& contiene il nuovo socket per gestire la connessione
    *\return true se l'operazione ha avuto successo
    */
    bool accept ( Socket& ) const;

    // Client initialization
    /**
    *\brief Permette di connettersi ad un server
    *\param [in] host contiene l'indirizzo al quale connettersi
    *\param [in] port contiene la porta sulla quale connettersi
    *\return true se l'operazione ha avuto successo
    */
    bool connect ( const std::string host, const long port );

    // Data Transimission
    /**
    *\brief permette di inviare informazioni attraverso il socket
    *\param [in] s puntatore all'array di caratteri che contiene l'informazione da inviare
    *\param [in] len contiene la lunghezza dell'array
    *\return true se l'operazione ha avuto successo
    */
    bool send ( unsigned char * s, int len ) const;
    /**
    *\brief Permette la lettura di informazioni dal socket
    *\param [out] s contiene l'informazione letta dal socket
    *\return il numero di byte letti.
    */
    int recv ( unsigned char * s ) const;

    /**
    *\brief Metodo che permette di impostare il socket come non bloccante
    *\param [in] Se true imposta il socket come non bloccante
    */
    void set_non_blocking ( const bool );

    /**
    *\brief Metodo che serve per identificare se il socket è ancora valido
    *\return true in caso il socket sia ancora valido
    */
    bool is_valid() const
    {
        return m_sock != -1;
    }

    void chiudi();
private:

    int m_sock;
    sockaddr_in m_addr;


};


#endif
Socket.cpp
codice:
// Implementation of the Socket class.


#include "Socket.h"
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <iostream>



Socket::Socket() :
    m_sock ( -1 )
{

    memset ( &m_addr,
             0,
             sizeof ( m_addr ) );

}

Socket::~Socket()
{
    if ( is_valid() )
        ::close ( m_sock );
}

bool Socket::create()
{
    m_sock = socket ( AF_INET,
                      SOCK_STREAM,
                      0 );

    if ( ! is_valid() )
        return false;


    // TIME_WAIT - argh
    int on = 1;
    if ( setsockopt ( m_sock, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 )
        return false;


    return true;

}



bool Socket::bind ( const long port )
{

    if ( ! is_valid() )
    {
        return false;
    }



    m_addr.sin_family = AF_INET;
    m_addr.sin_addr.s_addr = INADDR_ANY;
    m_addr.sin_port = htons ( port );

    int bind_return = ::bind ( m_sock,
                               ( struct sockaddr * ) &m_addr,
                               sizeof ( m_addr ) );


    if ( bind_return == -1 )
    {
        return false;
    }

    return true;
}


bool Socket::listen() const
{
    if ( ! is_valid() )
    {
        return false;
    }

    int listen_return = ::listen ( m_sock, MAXCONNECTIONS );


    if ( listen_return == -1 )
    {
        return false;
    }

    return true;
}


bool Socket::accept ( Socket& new_socket ) const
{
    int addr_length = sizeof ( m_addr );
    new_socket.m_sock = ::accept ( m_sock, ( sockaddr * ) &m_addr, ( socklen_t * ) &addr_length );

    if ( new_socket.m_sock <= 0 )
        return false;
    else
        return true;
}


bool Socket::send ( unsigned char * s, int len ) const
{
    int status = ::send ( m_sock, s, len, MSG_NOSIGNAL );
    if ( status == -1 )
    {
        return false;
    }
    else
    {
        return true;
    }
}


int Socket::recv ( unsigned char * s ) const
{
    unsigned char buf [ MAXRECV + 1 ];

    memset ( buf, 0, MAXRECV + 1 );

    int status = ::recv ( m_sock, buf, MAXRECV, 0 );
    if(-1 == status)
           {
             switch(errno)
               {
               case EAGAIN :// no messages
                 break;
               case EBADF :
                 cerr << "Bad file descriptor" << endl;
                 break;
               case ECONNRESET :
                 cerr << "Connection reset" << endl;
                 break;
               case EINTR :
                 cerr << "Signal interrupt" << endl;
                 break;
               case ENOTCONN :
                 cerr << "Not connected" << endl;
                 break;
               case ENOTSOCK :
                 cerr << "Not a socket" << endl;
                 break;
               case EOPNOTSUPP :
                 cerr << "Not supported" << endl;
                 break;
               case ETIMEDOUT :
                 cerr << "Timed out" << endl;
                 break;
               default :
                 cerr<<"Unknown" <<endl;
                 break;
			}
		}

    if ( status == -1 )
    {
        std::cout << "status == -1   errno == " << errno << "  in Socket::recv\n";
        return 0;
    }
    else if ( status == 0 )
    {
        return 0;
    }
    else
    {
        memcpy(s,buf,status);
        return status;
    }
}



bool Socket::connect ( const std::string host, const long port )
{
    if ( ! is_valid() ) return false;

    m_addr.sin_family = AF_INET;
    m_addr.sin_port = htons ( port );

    int status = inet_pton ( AF_INET, host.c_str(), &m_addr.sin_addr );


    if ( errno == EAFNOSUPPORT ) return false;

    status = ::connect ( m_sock, ( sockaddr * ) &m_addr, sizeof ( m_addr ) );

    if ( status == 0 )
        return true;
    else
        return false;
}

void Socket::set_non_blocking ( const bool b )
{

    int opts;

    opts = fcntl ( m_sock,
                   F_GETFL );

    if ( opts < 0 )
    {
        return;
    }

    if ( b )
        opts = ( opts | O_NONBLOCK );
    else
        opts = ( opts & ~O_NONBLOCK );

    fcntl ( m_sock,
            F_SETFL,opts );

}

void Socket::chiudi()
{
    close(m_sock);
}
La classe l'ho presa da qui http://tldp.org/LDP/LG/issue74/tougher.html