Il distruttore di Socket chiude la connessione quando Run() termina, pertanto tutte le connessione associate a quello specifico socket vengono interrotte. Per impedire che il socket interno a Socket sia chiuso è possibile inserire un reference counter, ma dato che usi un compilatore C++11, a mio avviso la soluzione più elegante è usare un move constructor.
In questo modo i dati interni saranno spostati da un Socket all'altro senza problemi.
Penrtanto io modificherei la classe così:
In Socket.h
codice:
class Socket {
Socket();
// no costruttore di copia
Socket(const Socket& ) = delete;
// no operatore di assegnamento
Socket& operator=(const Socket& ) = delete;
// costruttore di spostamento
Socket(Socket&& rhs);
// operatore di spostamento
Socket& operator=(Socket&& rhs);
...
};
In socket.cpp
codice:
// costruttore di spostamento. Sposta i dati da rhs a *this
Socket::Socket(Socket&& rhs) : m_sock(rhs.m_sock) {
//invalida rhs.m_sock;
rhs.m_sock=-1;
// copia da rhs.m_addr a this->m_addr
memcpy(&m_addr,rhs.m_addr,(sizeof(m_addr));
// annulla rhs.m_addr
memset(&m_addr,0,sizeof(m_addr));
}
// operatore di spostamento
Socket& Socket::operator=(Socket&& rhs) {
if (&rhs != this) {
m_sock = rhs.m_sock;
//invalida rhs.m_sock;
rhs.m_sock=-1;
// copia da rhs.m_addr a this->m_addr
memcpy(&m_addr,rhs.m_addr,(sizeof(m_addr));
// annulla rhs.m_addr
memset(&m_addr,0,sizeof(m_addr));
}
return *this;
}
In Server::Run()
codice:
// per evidenziare meglio
thread_serventi[n_thread] = move(
thread(
&Server::serviceRoutine,this,move(new_sock)
)
);
Nuovo prototipo di Server::serviceRoutine()
codice:
void Server::serviceRoutine(Socket sock)