c++ - non-blocking recv returns 0 when disconnected -
i'm trying 'catch' when disconnect happens. don't what's wrong. recv() returns 0, errno set 0 , ioctl returns 0. searching 6 hours on web without success. can tell me what's wrong?
regards.
bool network::setblocking(bool blocking) { // sets blocking or non-blocking mode. int flags = blocking ? 1 : 0; return ioctl(this->sockfd, fionbio, &flags) ? false : true; } networkstatus network::status() { // returns socket status. struct timeval tv; fd_set fd; int result = 0; tv.tv_sec = 3; tv.tv_usec = 0; fd_zero(&fd); fd_set(this->sockfd, &fd); result = select(this->sockfd + 1, &fd, 0, 0, &tv); if(result == -1) { return network_error; } else if(result) { return network_readyread; } else { return network_timeout; } } int network::bytesavailable() { // returns number of bytes available. int bytes = 0; if(ioctl(this->sockfd, fionread, &bytes) < 0 || errno) { return -1; } return bytes; } int network::read(char *buffer, int size) { // reads data socket. return recv(this->sockfd, buffer, size, 0); } ... int main(int argc, char* argv[]) { network net; ... while(true) { switch(net.status()) { ... case network_readyread: { int bytesavailable = net.bytesavailable(); char temp[bytesavailable]; int len = net.read(temp, bytesavailable); printf("len: %d\nerrno: %d\nbytesavailable: %d\n", len, errno, bytesavailable); // len: 0, errno: 0, bytesavailable: 0 break; } } } // status return 0; }
when other side close socket or shutdown(send), @ side select return socket readable, select command return 1 indicating there data read (in fact there no data, signal indicating socket closed), ioctl return 0 bytes available , recv() return 0 , that's how tcp works. in program should take care of bytesavaliable returns 0 and/or read() returns 0. in these cases socket has been closed , should close side , waits (accept) or establish (connect) new connection.
edit: add commnents:
well, not exactly. when recv() = 0, socket closed or shutdown send, when = -1 there error in socket. if socket non-blocking (has o_nonblock set) should check error (errno on unix, wsagetlasterror() on windows) , ewouldblock or eagain indicates there no data available , socket still valid. also, in rare cases, recv() return -1 , error eintr means during recv() operation interrupt (signal) has been received, in case should ignore error (unless waiting such signal) , reissue recv().
ret=recv(socket, buff, length, 0); if (ret > 0) { // data has been received } else if (ret == 0) { // socket has been closed or shutdown send } else { // there error, let's see int error = errno; // or wsagetlasterror() switch (error) { case eagain: case ewouldblock: // socket o_nonblock , there no data available break; case eintr: // interrupt (signal) has been catched // should ingore in cases break; default: // socket has error, no valid anymore return; } } saying that, 1 thing must clear if recv() return 0 or -1 socket not valid anymore , should closed, again, depends on many factors, protocol use keep dialog between sockets, if in non-blocking, etc. example, other side issue shutdown(); in case recv() return 0 still send() through socket without errors.
Comments
Post a Comment