SocketReactor Event Problem

Please post support and help requests here.
yaerek
Posts: 5
Joined: 30 Dec 2008, 10:35

SocketReactor Event Problem

Postby yaerek » 30 Dec 2008, 10:52

Greetings.
Happy oncoming New Year.

I'm working on an application that depends heavily on sockets and use extensively SocketReactor class; often I have 5 SocketReactor class instances in one program. I ran into the following problem with the SocketReactor:

To serve the TCP requests I use a class (similar to the one in Net/Echo example):

class ServerHandler{
private:
Poco::Net::StreamSocket _socket;
Poco::Net::SocketReactor &_reactor;
Poco::UInt8 *_pBufor;
enum{
BUFOR_SIZE = 1300
};
public:
ServerHandler(Poco::Net::StreamSocket& socket, Poco::Net::SocketReactor& reactor);
~ServerHandler();
void onReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &);
void onShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification> &);
void onError(const Poco::AutoPtr<Poco::Net::ErrorNotification> &);
};

And here is it’s implementation:

ServerHandler::ServerHandler(Poco::Net::StreamSocket& socket, Poco::Net::SocketReactor& reactor): _socket(socket), _reactor(reactor), _pBufor(new Poco::UInt8[BUFOR_SIZE]){
_reactor.addEventHandler(_socket, Poco::NObserver<ServerHandler, Poco::Net::ReadableNotification>(*this, &ServerHandler::onReadable));
_reactor.addEventHandler(_socket, Poco::NObserver<ServerHandler, Poco::Net::ShutdownNotification>(*this, &ServerHandler::onShutdown));
_reactor.addEventHandler(_socket, Poco::NObserver<ServerHandler, Poco::Net::ErrorNotification>(*this, &ServerHandler::onError));
}
ServerHandler::~ServerHandler(){
delete [] _pBufor;
_reactor.removeEventHandler(_socket, Poco::NObserver<ServerHandler, Poco::Net::ReadableNotification>(*this, &ServerHandler::onReadable));
_reactor.removeEventHandler(_socket, Poco::NObserver<ServerHandler, Poco::Net::ShutdownNotification>(*this, &ServerHandler::onShutdown));
_reactor.removeEventHandler(_socket, Poco::NObserver<ServerHandler, Poco::Net::ErrorNotification>(*this, &ServerHandler::onError));
}
void ServerHandler::onReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf){ // receiver, when in the socket event happens
Recived_data Rec; // in the reactor that something ‘came’
int n=_socket.receiveBytes(_pBufor, BUFOR_SIZE); //tu sie odbiera
if(n==0)
delete this;
else{
Rec.recivData(&_pBufor[0],n,_socket);
}
}

In the main class I use the following code:


Poco::Net::ServerSocket svs0;
svs0.bind(Poco::UInt16(_port0));
svs0.listen();
Poco::Net::SocketAcceptor<ServerHandler> acceptor0(svs0,reactor0);
Thread0.start(reactor0);

Actually I use 5 acceptors, reactors and sockets. If the remote peer is killed (not cleanly disconnected) I got Winsock Exception – “connection reset by peer” . This exception is caught by global error handler, but the socket is stuck at this state, and no ServerHandler::onError is invoked. I cannot either close or reset this socket. Why no Socket ErrorNotificaton event is thrown when unclean SocketReactor disconnect happens? Is there some flag I must signal before initializing SocketReactor?

I really appreciate input :)
Yaerek

guenter
Posts: 1194
Joined: 11 Jul 2006, 16:27
Location: Austria

Re: SocketReactor Event Problem

Postby guenter » 05 Jan 2009, 15:45

The behaviour you're observing is due to the select() call, which the SocketReactor uses. I suspect that the exception you get is thrown in receiveBytes(), which you call in onReadable(). This seems fine, as according to various sources, the third argument to select(), on which onError() is based, is only for reporting the arrival of out-of-band data, or for reporting the failure of a nonblocking connect call (Winsock). Normal socket errors, such as connection closed/reset/terminated, etc. is reported as the socket becoming readable, with the following read() or recv() call reporting the error.

I suggest wrapping the call to receiveBytes() in a try/catch block.


Return to “Support”

Who is online

Users browsing this forum: No registered users and 1 guest