i wrote a basic network programming set of C++ classes (there's nothing more than a tcp_socket a udp_socket and an ip_address wrap class class). I'm having some troubles with a I/O multiplexed server. Let me explain:
The scenario is in a way like this:
class base_socket
{
//code for all sockets methods (both tcp and udp this class throws
//errors and derived classes will cathc them.
~base_socket() { ::close(sock_fd); }
};
class udp_socket : public base_socket
{
//code for the udp_socket
virtual ~udp_socket();
};
class tcp_socket : public base_socket
{
//code for the tcp_socket
virtual ~tcp_socket();
};
over this scheme, depending on the application's context, I've added an ulterior level of abstraction: something like
class client_t : public tcp_socket
{
//code for dependent client tasks
};
The main program code is something like this
int main(int argc , char *[] argv)
{
int maxfd;
fd_set rset;
std::vector<base_socket> clientsV;
while(1)
{
FD_ZERO( &rset);
FD_SET( {/*listening socket fd*/, &rset);
if( clientsV.size() > 0)
maxfd = // socket fd with max value between sockets
else
maxfd = //listen socket
for (auto it = clientsV.begin() ; it != clientsV.end(); ++it)
FD_SET( /*client's socket fd*/, &rset);
select( maxfd+1, &rset, NULL, NULL, NULL) < 0);
if( FD_ISSET( /*listeing_socket*/, &rset))
{
client_t * newclient = new client_t();
listening_socket.accept(newclient);
newClient->send_message("HELO");
clientsV.push_back(*newClient);
}
}
}
This works for the first client but when a second client comes it gets the HELO response but on the second clientsV.push_back(*newClient) the first connection is closed(). Any idea on what's going wrong?
Your clientsV
member should be a std::vector<base_socket*>
(i.e. keeping the pointer references). You have a chance that a temporary client_t
object is being created and destroyed during push_back
if it needs to relocate existing elements to a different area (See Why does vector::push_back and emplace_back call value_type::constructor twice?).
When this happens, the ~client_t()
is called and the socket is now closed.
Also, you have a memory leak. You are allocating a pointer with new
but you store the dereferenced copy. You should really just be storing the pointer as-is (and manage delete
ing it when needed).