c++ - Multiple connections from same host cause socket disconnection issues -


i'm writting c++ app linux. uses sockets tcp communication. read data remote hosts follows (a bit simplified topic's needs):

packet connection::receiverawdata() {     int length = recv(socketdescriptor, receivebuffer, maxbuf, 0);     if(length < 0)     {         std::cout << getconnectiondetails() << " - nothing read.\n";          return packet(); //empty packet object (with no data)     }     else if(length == 0)     {         std::cout << getconnectiondetails() << " - disconnected suddenly!\n";         //do closed connection     }      return packet(receivebuffer, length); } 

getconnectiondetails() shows me adress , port number (like this: xx.xx.xx.xx:yy) know message specific connection (since if they're same host they'll still have different port numbers). couts debuging purpose.

the thing is, doesn't work quite when close 1 of connections same host (ie. after making 3 different connection application, of them come same machine). when close them in reversed order (from newest oldest) works expected - shows "xx.xx.xx.xx:yy - disconnected suddenly!" in app's console. when try oldest newest, keep getting "xx.xx.xx.xx:yy - nothing read." every connection, though these connections should closed!

what's going on? recv() supposed return 0 when remote host closed connection, why doesn't happen when close connection (from remote host side) oldest or "middle" (neither oldest nor newest)?

it doesn't occur when close connections different machines (so no machine makes more 1 connection app) - order of these operations don't matter then, works fine should.

edit: more code can see how set connection sockets:

//create "empty" socket object associated given port number connection::connection(portnumberformat portnum) : address(), port(portnum), socketdescriptor(socket(af_inet, sock_stream, 0)), isconnected(false), islistening(false), isshuttingdown(false) {     if(socketdescriptor < 0)         throw std::string("fatal error: cannot create socket! error was: " + std::string( strerror(errno) )); }  //create socket object using specified socket descriptor , mark connected server //available on specified address , port connection::connection(socketdescriptor sock, char *addr, portnumberformat portnum) : address(addr), port(portnum), socketdescriptor(sock), isconnected(true), islistening(false), isshuttingdown(false) {     settimeouts(); }  connection::~connection() {     if(socketdescriptor < 0) return;     if(!isshuttingdown) signalshutdown();     close(socketdescriptor); }  //turn socket listening mode binding specified port void connection::startlisten() {     if(isconnected || islistening || socketdescriptor < 0)         throw std::string("socket can not set listening!");      struct sockaddr_in binddata;     int dummy = 1;     memset(&binddata, 0, sizeof(binddata));     binddata.sin_family = af_inet;     binddata.sin_addr.s_addr = inaddr_any;     binddata.sin_port = htons(port);     setsockopt(socketdescriptor, sol_socket, so_reuseaddr, &dummy, sizeof(dummy)); //release socket asap on closing     if(bind(socketdescriptor, (struct sockaddr*)&binddata, sizeof(binddata)) < 0)         throw std::string("fatal error: cannot bind socket listening! error was: " + std::string( strerror(errno) ));     if(listen(socketdescriptor, maxconn) < 0)         throw std::string("fatal error: cannot listen on bound socket! error was: " + std::string( strerror(errno) ));     islistening = true; }  //get new connection object represents external client connection //this method block until client connects or socket shutdown occurs connection connection::getclientconnection() {     if(!islistening || socketdescriptor < 0)         throw std::string("can't connection non-listening socket!");      struct sockaddr_in clientdata;     socklen_t len = sizeof(clientdata);     socketdescriptor clientsocket = accept(socketdescriptor, (struct sockaddr*)&clientdata, &len);     if(isshuttingdown) //an shutdown occured     {         if(clientsocket < 0)             throw std::string("information: listening connection shutting down peacefully.");         //else...         close(clientsocket); //just sure         throw std::string("warning: listening connection shutting down. client connection has been discarded.");     }     if(clientsocket < 0)         throw std::string("fatal error: cannot open client connection socket! error was: " + std::string( strerror(errno) ));     return connection(clientsocket, inet_ntoa(clientdata.sin_addr), ntohs(clientdata.sin_port)); }  //invalidates socket , prepares closed void connection::signalshutdown() {     if(socketdescriptor < 0) return;     isshuttingdown = true;     shutdown(socketdescriptor, shut_rdwr); }  inline void connection::settimeouts() {     struct timeval timeout;           timeout.tv_sec = 2;     timeout.tv_usec = 0;      if(setsockopt(socketdescriptor, sol_socket, so_rcvtimeo, (void*)&timeout, sizeof(timeout)) < 0         || setsockopt(socketdescriptor, sol_socket, so_sndtimeo, (void*)&timeout, sizeof(timeout)) < 0)     {         //do     } }  std::string connection::getconnectiondetails() {     return std::string(address + ":" + std::to_string(port)); } 

listening connection created using first constructor (port number only), call startlisten() on it. connections hosts returned external code getclientconnection() method (they created using second constructor). these our troublemakers.


Comments