I have code that implements Poco SocketReactor, as described from Echo example.
class TSPConnectionHandler
{
public:
TSPConnectionHandler(const StreamSocket& socket, SocketReactor& reactor) : _socket(socket),
_reactor(reactor)
{
_reactor.addEventHandler(_socket, Poco::NObserver<TSPConnectionHandler, ReadableNotification>(*this, &TSPConnectionHandler::onSocketReadable));
_reactor.addEventHandler(_socket, Poco::NObserver<TSPConnectionHandler, WritableNotification>(*this, &TSPConnectionHandler::onSocketWritable));
_reactor.addEventHandler(_socket, Poco::NObserver<TSPConnectionHandler, ShutdownNotification>(*this, &TSPConnectionHandler::onSocketShutdown));
_reactor.addEventHandler(_socket, Poco::NObserver<TSPConnectionHandler, ErrorNotification>(*this, &TSPConnectionHandler::onSocketError));
_reactor.addEventHandler(_socket, Poco::NObserver<TSPConnectionHandler, TimeoutNotification>(*this, &TSPConnectionHandler::onSocketTimeout));
}
virtual ~TSPConnectionHandler()
{
_reactor.removeEventHandler(_socket, Poco::NObserver<TSPConnectionHandler, ReadableNotification>(*this, &TSPConnectionHandler::onSocketReadable));
_reactor.removeEventHandler(_socket, Poco::NObserver<TSPConnectionHandler, WritableNotification>(*this, &TSPConnectionHandler::onSocketWritable));
_reactor.removeEventHandler(_socket, Poco::NObserver<TSPConnectionHandler, ShutdownNotification>(*this, &TSPConnectionHandler::onSocketShutdown));
_reactor.removeEventHandler(_socket, Poco::NObserver<TSPConnectionHandler, ErrorNotification>(*this, &TSPConnectionHandler::onSocketError));
_reactor.removeEventHandler(_socket, Poco::NObserver<TSPConnectionHandler, TimeoutNotification>(*this, &TSPConnectionHandler::onSocketTimeout));
}
void onSocketReadable(const Poco::AutoPtr<ReadableNotification>& pNf)
{
cout << "READable !!" << endl;
try
{
vector<char> m_buffer;
m_buffer.resize(1024, '\0');
LONG32 m_buflen = _socket.receiveBytes(&m_buffer[0], 1024);
if (m_buflen == 0)
{
cout << "Connection reset by peer normally" << endl;
delete this;
}
_socket.sendBytes(&m_buffer[0], m_buflen);
}
catch(Poco::Net::NetException& e)
{
cout << "socket read exception: " << e.displayText() << endl;
delete this;
}
}
void onSocketWritable(const Poco::AutoPtr<WritableNotification>& pNf)
{
cout << "WRITEable !!" << endl;
}
void onSocketShutdown(const Poco::AutoPtr<ShutdownNotification>& pNf)
{
cout << "SHUTDOWN!!!!!!!!!!!!" << endl;
delete(this);
}
void onSocketError(const Poco::AutoPtr<ErrorNotification>& pNf)
{
cout << "Error!!" << endl;
}
void onSocketTimeout(const Poco::AutoPtr<TimeoutNotification>& pNf)
{
cout << "Timeout!!" << endl;
}
private:
StreamSocket _socket;
SocketReactor& _reactor;
};
It starts normally somewhere else in program using this code:
Poco::Net::ServerSocket tcpsock("9495");
Poco::Net::SocketReactor reactor;
Poco::Net::SocketAcceptor<TSPConnectionHandler> acceptor(tcpsock, reactor);
Poco::Thread thread;
thread.start(reactor);
waitForTerminationRequest();
reactor.stop();
thread.join();
return Application::EXIT_OK;
Also I have python client to test it:
import socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('localhost', 9495))
data = raw_input ( "Something:" )
client_socket.send(data)
data = client_socket.recv(1024)
print "RECIEVED:" , data
client_socket.close()
And I got list of questions that I don't understand how to resolve:
- after python string "client_socket.connect(('localhost', 9495))" is done, server starts to spam "onSocketWritable", how to stop it? I understand I have to be notified if socket become writable, but why do it continue doing that while all socket's life? If that is normal situation, what for was designed WritableNotification?
- if I will start python in debug mode and close it before "client_socket.close()", server gets exception and will be deleted throw "socket read exception: ". But errornotification and shutdownnotification will not be dispatched. Why? I never saw them dispatched anyhow.
- If I will let "client_socket.close()" be done, on server side I will receive ReadableNotification and will leave throw "Connection reset by peer normally". But still there will be no ShutdownNotification. Why?