[Plib-users] request for change
Brought to you by:
sjbaker
From: Brendan <br...@WP...> - 2003-08-26 15:41:17
|
I just started using plib's NET library and noticed a minor bug... It's not really a bug - it's more a windows xp problem (feature?) that isn't handled properly. i'm using a netSocket derivitive to listen it passes socket handles to a netChannel derivitive to handle connections when a client connects with telnet and then disconnects, the server prints: WARNING: WSAGetLastError() => 10054 i looked up wsa error 10054 WSACONNRESET = 10054 the netChannel class has its own receive function for receiving its special data and handling exeptions ---------------- code ---------------- int netChannel::recv (void * buffer, int size, int flags) { int result = netSocket::recv (buffer, size, flags); if (result > 0) { return result; } else if (result == 0) { close(); return 0; } else if (isNonBlockingError ()) { return 0; } else { this->handleError (result); close(); return -1; } } ------------- /code -------------- this function calls isNonBlockingError() which is defined in netSocket here's some comments that should be in there: (if result > 0) then there was data received, return how much otherwise (if result == 0) then the socket reported action on the connection, but there was no data -> signalling a disconnect, close socket, return 0 otherwise, there was some error with the recv() function as called by netSocket, check if it was a nonblocking error if it wasn't a non-blocking error, which it wasn't, then call the virtual overloadable handleError function (which i have overloaded to print my stuff) so it seems that, since WSAECONNRESET is not a nonblocking error, then my virtual function should be allowed to handle the error however i want it to but somehow this error message is being printed, so i looked to see what exactly isNonBlockingError does: -------------- code ------------ bool netSocket::isNonBlockingError () { #if defined(__CYGWIN__) || !defined (WIN32) switch (errno) { case EWOULDBLOCK: // always == NET_EAGAIN? case EALREADY: case EINPROGRESS: return true; } return false; #else int wsa_errno = WSAGetLastError(); if ( wsa_errno != 0 ) { WSASetLastError(0); ulSetError(UL_WARNING,"WSAGetLastError() => %d",wsa_errno); switch (wsa_errno) { case WSAEWOULDBLOCK: // always == NET_EAGAIN? case WSAEALREADY: case WSAEINPROGRESS: return true; } } return false; #endif } --------------- /code ------------------- AHA! so when netChannel's recv() function gets an error and checks to see if it's a blocking error... it registers a warning with ul saying that there was a winsock error, and causing ul to print the error to the screen it seems like the netChannel class is meant to take care of all socket error handling on its own and that the overloadable handleError() function takes care of errors returned by recv() but the WSACONNRESET error is unhandled... also the cygwin version of the code (the first part of #if bracket) seems like it doesn't record recv errors.. maybe the ulSetError line is unnecessary? a suggestion might be to remove the isNonBlockingError from recv() and instead store the value returned by WSAGetLastError in a variable in the netChannel class then allow the user to call getLastError() to find out why recv() called handleError() then you can keep the isNonBlockingError() function (with ulSetError removed) and just have it check against variable it has stored. Anyway, I hope this is helpful, and the code gets updated -Brendan Batchelder |