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