POCO - 我可以使用 SocketReactor 作为客户端吗?
POCO - can I use SocketReactor as a client?
当人们运行TCP服务器时,我看到很多SocketActor与SocketAcceptor一起使用的例子。
但是,我想作为客户端连接到现有的TCP服务器,但希望能够处理SocketReactor公开的事件,例如onSocketReadable,onSocketWritable,onSocketShutdown,onSocketError和onSocketTimeout。
POCO 库可以做到这一点吗?我把下面的代码放在一起,但没有触发任何事件。如果这种方法不起作用,还有其他建议吗?基本上,我将从服务器接收实时的tcp消息流,并且还将消息发送回服务器以执行某些任务。
class ITCHProvider
{
private:
Poco::Net::SocketAddress _sa;
Poco::Net::StreamSocket _sock;
Poco::Net::SocketStream _stream;
Poco::Net::SocketReactor _reactor;
public:
ITCHProvider() :
_sa("host", 1234),
_sock(),
_stream(_sock),
_reactor()
{
_reactor.addEventHandler(_sock, Poco::NObserver<ITCHProvider, Poco::Net::ReadableNotification>(*this, &ITCHProvider::onSocketReadable));
_reactor.addEventHandler(_sock, Poco::NObserver<ITCHProvider, Poco::Net::WritableNotification>(*this, &ITCHProvider::onSocketWritable));
_reactor.addEventHandler(_sock, Poco::NObserver<ITCHProvider, Poco::Net::ShutdownNotification>(*this, &ITCHProvider::onSocketShutdown));
_reactor.addEventHandler(_sock, Poco::NObserver<ITCHProvider, Poco::Net::ErrorNotification>(*this, &ITCHProvider::onSocketError));
_reactor.addEventHandler(_sock, Poco::NObserver<ITCHProvider, Poco::Net::TimeoutNotification>(*this, &ITCHProvider::onSocketTimeout));
_sock.connect(_sa);
}
~ITCHProvider()
{
close();
}
void onSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf)
{
LOG(INFO) << "READable !!";
}
void onSocketWritable(const Poco::AutoPtr<Poco::Net::WritableNotification>& pNf)
{
LOG(INFO) << "WRITEable !!";
}
void onSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf)
{
LOG(INFO) << "SHUTDOWN!!!!!!!!!!!!";
}
void onSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf)
{
LOG(INFO) << "Error!!";
}
void onSocketTimeout(const Poco::AutoPtr<Poco::Net::TimeoutNotification>& pNf)
{
LOG(INFO) << "Timeout!!";
}
// Close down the connection properly.
void close() {
try {
_sock.shutdown();
}
catch (...) {
LOG(INFO) << "closing failed.";
}
}
};
可以做到,但请注意 (a) 在实际运行反应堆之前不会发生任何事情,并且 (b) 反应堆将旋转直到明确停止,因此最好在单独的线程中运行它;
下面是一个简单示例:
// server-side handler
class EchoServiceHandler {
public:
EchoServiceHandler(StreamSocket& socket, SocketReactor& reactor): _socket(socket), _reactor(reactor) {
_reactor.addEventHandler(_socket, Observer<EchoServiceHandler, ReadableNotification>(*this, &EchoServiceHandler::onReadable));
}
~EchoServiceHandler() {
_reactor.removeEventHandler(_socket, Observer<EchoServiceHandler, ReadableNotification>(*this, &EchoServiceHandler::onReadable));
}
void onReadable(ReadableNotification* pNf) {
pNf->release();
char buffer[8];
int n = _socket.receiveBytes(buffer, sizeof(buffer));
if (n > 0) {
_socket.sendBytes(buffer, n);
}
else {
_socket.shutdownSend();
delete this;
}
}
private:
StreamSocket _socket;
SocketReactor& _reactor;
};
您的原始代码,稍作修改:
class ITCHProvider : public Poco::Runnable
{
private:
Poco::Net::StreamSocket _sock;
Poco::Net::SocketReactor _reactor;
public:
ITCHProvider(const SocketAddress& sa) : _sock(sa) {
_reactor.addEventHandler(_sock, Poco::NObserver<ITCHProvider, Poco::Net::ReadableNotification>(*this, &ITCHProvider::onSocketReadable));
_reactor.addEventHandler(_sock, Poco::NObserver<ITCHProvider, Poco::Net::WritableNotification>(*this, &ITCHProvider::onSocketWritable));
_reactor.addEventHandler(_sock, Poco::NObserver<ITCHProvider, Poco::Net::ShutdownNotification>(*this, &ITCHProvider::onSocketShutdown));
_reactor.addEventHandler(_sock, Poco::NObserver<ITCHProvider, Poco::Net::ErrorNotification>(*this, &ITCHProvider::onSocketError));
_reactor.addEventHandler(_sock, Poco::NObserver<ITCHProvider, Poco::Net::TimeoutNotification>(*this, &ITCHProvider::onSocketTimeout));
std::string data = "Hello reactor world!";
_sock.sendBytes(data.data(), (int)data.length());
}
~ITCHProvider() { close(); }
void run() { _reactor.run(); }
void stop() { _reactor.stop(); }
void onSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
std::cout << "READable !!" << std::endl;
char data[1025] = { 0 };
if (_sock.receiveBytes(data, 1024) > 0) {
std::cout << data << std::endl;
}
}
void onSocketWritable(const Poco::AutoPtr<Poco::Net::WritableNotification>& pNf) {
std::cout << "WRITEable !!" << std::endl;
}
void onSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf) {
std::cout << "SHUTDOWN!!!!!!!!!!!!" << std::endl;
}
void onSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf) {
std::cout << "Error!!" << std::endl;
}
void onSocketTimeout(const Poco::AutoPtr<Poco::Net::TimeoutNotification>& pNf) {
std::cout << "Timeout!!" << std::endl;
}
void close() {
try {
_sock.shutdown();
}
catch (...) {
std::cout << "closing failed." << std::endl;
}
}
};
现在,让我们运行上述操作:
SocketAddress ssa;
ServerSocket ss(ssa);
SocketReactor reactor;
SocketAcceptor<EchoServiceHandler> acceptor(ss, reactor);
Thread server;
server.start(reactor);
ITCHProvider provider(SocketAddress("127.0.0.1", ss.address().port()));
Thread client;
client.start(provider);
Thread::sleep(1000);
reactor.stop();
provider.stop();
server.join();
client.join();
输出(为清楚起见,可写和超时通知静音):
READable !!
Hello reactor world!
SHUTDOWN!!!!!!!!!!!!
相关文章:
- "unknown ca"自生成的 CA、证书和客户端/服务器
- 如何将函数集合传递给客户端类,以便将它们当作客户端类本身的成员使用
- 使用调试/崩溃报告将应用程序部署到客户端
- 如何在本地机器上运行c++和javascript客户端代码(hackerbank风格)
- 如何通过套接字将文本文件的内容从服务器发送到客户端
- 从服务器传输到客户端的消息不会出现
- OpenSSL TLS服务器-使用客户端证书白名单
- 当服务中的事件被触发时,如何将响应从服务发送回客户端?
- 我可以与 python 服务器而不是 c++ 客户端建立 tcp/ip 套接字吗?
- 提升 Asio TCP 服务器 处理多个客户端
- boost::asio UDP 广播客户端仅接收"fast"数据包
- 如何绑定 C++ gRPC 客户端的网络接口
- C++套接字客户端到 Python 服务器未创建连接
- 用于解析 win64 堆栈跟踪的命令行客户端(可以访问符号服务器)
- 将相机数据从服务器实时流式传输到客户端
- 如何将 Firebase 与基于 Linux 的客户端应用配合使用,以便与服务器进行双向消息通信
- GRPC C++ TLS 客户端 grpc::SslCredentials() 方法不返回
- 计算出有多少客户端可以连接到我正在使用的一些tcp服务器代码
- 如何暂停插孔音频客户端
- 不将数据 socket.io c++(客户端)发送到 nodejs(服务器)socket.io