Slot selection () Cut-off handling
I am currently trying to fix a bug on the proxy I wrote regarding the socket () call. I am using Poco C ++ libraries (using SocketReactor) and the problem is actually in Poco's code, which might be a bug but I haven't gotten a confirmation from them yet.
What happens when the connection is abruptly terminated by the socket select () call returns immediately, what do I believe it should do? Anyway, it returns all disconnected sockets in the readable file descriptor set, but the problem is that the "Socket not connected" exception is thrown when Poco tries to fire the onReadable event handler, where I would put code to handle it. Given that the exception is silently caught and the onReadable event is never fired, the select () call continues to return immediately, resulting in an infinite loop in the SocketReactor.
I was considering modifying Poco's code so that instead of throwing an exception without exception, it fires a new event called onDisconnected or something similar so that the cleanup can be done.
My question is, are there any neat ways to determine if a socket was closed abnormally using select () calls? I was thinking about using an exception message to determine when it happened, but it seems messy to me.
a source to share
You seem to be right, Remy. I was able to distinguish if the socket was disabled by the following code (this was added to Poco / Net / src / SocketImpl.cpp):
bool SocketImpl::isConnected()
{
int bytestoread;
int rc;
fd_set fdRead;
FD_ZERO(&fdRead);
FD_SET(_sockfd, &fdRead);
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 250000;
rc = ::select(int(_sockfd) + 1, &fdRead, (fd_set*) 0, (fd_set*) 0, &tv);
ioctl(FIONREAD, &bytestoread);
return !((bytestoread == 0) && (rc == 1));
}
In my opinion, this checks if a socket is being read using a select () call, and then checks the actual number of bytes available on that socket. If the socket reports that it is readable but the bytes are 0, then the socket is not actually connected.
While this answers my question here, it unfortunately didn't solve my Poco problem as I can't figure out how to fix it in Poco's SocketReactor code. I tried to create a new event called DisconnectNotification, but unfortunately I cannot name it as this same error occurs as for ReadNotification on a closed socket.
a source to share
I had the same problem. The only way to get around this is to manage the exit code of the client applications. The solution I used was to send a shutdown signal before the reactor was finished on the client side. Then on the server, you just close the socket.
//Client:
//Handler Class: onWrite
Packet p = Packet::Shutdown();
if (p.fn == "shutdown")
{
_reactor.stop();
delete this;
}
//Server
//Accepter Class: onRead
if (p.fn == "shutdown")
{
printf("%s has disconnected", _username.c_str());
_socket.close();
delete this;
}
a source to share