我正在使用POCO反应堆模式来处理传入的TCP连接。 连接可能需要几秒钟到几分钟,具体取决于请求类型,如下所示:

  try{
    ServerSocket serverSocket(port);
    reactor = new SocketReactor();
    ParallelSocketAcceptor<BFSTcpServiceHandler,SocketReactor> acceptor(serverSocket, *reactor);
    //Start Reactor
    reactor->run();
  }catch(Exception&e){
    LOG(ERROR)<<"ERROR in initializing TCPServer:"<<e.message();
    return;
  }

这是处理程序:

BFSTcpServiceHandler::BFSTcpServiceHandler(StreamSocket& _socket,
    SocketReactor& _reactor): socket(_socket),reactor(_reactor) {
  //Set Keeep Alive for socket
  socket.setKeepAlive(false);

  //Register Callbacks
  reactor.addEventHandler(socket, NObserver<BFSTcpServiceHandler,
    ReadableNotification>(*this, &BFSTcpServiceHandler::onReadable));
  /*reactor.addEventHandler(socket, NObserver<BFSTcpServiceHandler,
    WritableNotification>(*this, &BFSTcpServiceHandler::onWriteable));*/
  reactor.addEventHandler(socket, NObserver<BFSTcpServiceHandler,
    ShutdownNotification>(*this, &BFSTcpServiceHandler::onShutdown));
  reactor.addEventHandler(socket, NObserver<BFSTcpServiceHandler,
    ErrorNotification>(*this, &BFSTcpServiceHandler::onError));
  reactor.addEventHandler(socket, NObserver<BFSTcpServiceHandler,
    TimeoutNotification>(*this, &BFSTcpServiceHandler::onTimeout));
  /*reactor.addEventHandler(socket, NObserver<BFSTcpServiceHandler,
    IdleNotification>(*this, &BFSTcpServiceHandler::onIdle));*/
}

BFSTcpServiceHandler::~BFSTcpServiceHandler() {
  //Unregister Callbacks
  reactor.removeEventHandler(socket, NObserver<BFSTcpServiceHandler,
    ReadableNotification>(*this, &BFSTcpServiceHandler::onReadable));
    ...
  //Close socket
  try {
    socket.close();
  }catch(...){}
}

void BFSTcpServiceHandler::onReadable(
    const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
  //LOG(ERROR)<<"onReadable:"<<socket.peerAddress().toString();
  try{
   //Read and process request
  } catch(Exception &e){
    LOG(ERROR)<<"Error in reading request:"<<e.message();
    delete this;
  }
  //So after a connection is served just close it!
  delete this;
}

void BFSTcpServiceHandler::onShutdown(
    const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf) {
  LOG(ERROR)<<"onShutdown:"<<socket.peerAddress().toString();

  //Call destructor of this class
  delete this;
}

void BFSTcpServiceHandler::onWriteable(
    const Poco::AutoPtr<Poco::Net::WritableNotification>& pNf) {
  static bool once = true;
  if(once) {
    LOG(ERROR)<<"onWritable:"<<socket.peerAddress().toString()<<" keepAlive?"<<socket.getKeepAlive()<<" isBlocking?"<<socket.getBlocking()<<" noDeley?"<<socket.getNoDelay();
    once = false;
  }
}

void BFSTcpServiceHandler::onTimeout(
    const Poco::AutoPtr<Poco::Net::TimeoutNotification>& pNf) {
  LOG(ERROR)<<"\nTIMEOUT! onTimeout:"<<socket.peerAddress().toString();
}

void BFSTcpServiceHandler::onError(
    const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf) {
  LOG(ERROR)<<"\nERROR! onError:"<<socket.peerAddress().toString();
}

void BFSTcpServiceHandler::onIdle(
    const Poco::AutoPtr<Poco::Net::IdleNotification>& pNf) {
  LOG(ERROR)<<"\nIDLE! onIdle:"<<socket.peerAddress().toString();
}

代码工作正常; 但是,过了一会儿它卡住了,这意味着服务器确实接受了连接,但是根本不再调用onReadable。 例如,卡住后,我可以远程登录到服务器,但是当我发送数据时,onReadable不会被触发。 使用netstat,我意识到一些数据被保留在RCV_QEUEUE中,而且反应堆不会触发onReadable事件。

我认为这是由于达到系统的连接/文件限制所致,但是当系统卡住时,实际上并没有打开多少连接。

任何意见或帮助表示赞赏。

谢谢,

#1楼 票数:0

问题出在使用有故障的NIC /驱动程序。 我将代码更改为常规POSIX套接字,并遇到了相同的问题,并且通过切换NIC解决了该问题。 我不确定这是驱动程序还是硬件问题。

  ask by Behrooz translate from so

未解决问题?本站智能推荐:

1回复

POCO-我可以将SocketReactor用作客户端吗?

当人们正在运行TCP服务器时,我看到了许多与SocketAcceptor结合使用的SocketReactor的示例。 但是,我想作为客户端连接到现有的TCP服务器,但希望能够处理SocketReactor公开的事件,例如onSocketReadable,onSocketWritable,on
2回复

将Websocket与Poco库连接

我正在尝试使用Poco C ++库连接到Echo Test Websocket 。 为了做到这一点,我的代码应该设置Websocket: 但它不起作用:我收到如下错误消息: 有人可以帮忙吗?
1回复

与Poco库的Websocket连接

我对 wss://www.bitmex.com/realtime 的 websocket 连接有问题。 我在这个问题中找到了一个例子: Connect Websocket with Poco libraries ,但我不能用我的 wss:// 地址做同样的事情。 我总是在字符串后收到异常:“找不到主
1回复

如何正确关闭与Poco::HTTPSClientSession的连接?

我遇到了Poco::HTTPSClientSession的问题,不知道如何处理它。 描述(或发生的事情) 使用Poco::HTTPSClientSession类建立与服务器的HTTPS连接。 连接建立,密钥交换,初始数据交换效果很好。 客户端在会话建立后直接发送一个请求。 使用H
3回复

Poco::Net库挂在Poco::Net::SocketStream的输出上

通过POCO网站上的幻灯片,我编写了一个几乎与他们的第一个NET示例相同的程序。 CopyStream函数输出一些数据,然后挂起。 我如何获得其余数据?
1回复

通过poco流套接字发送文件

我必须要说的第一件事是,本文的灵感来自[Remy Lebeau] [1] https://stackoverflow.com/users/65863/remy-lebeau的回答,其强烈启发是在这里: 通过TCP / IP连接发送二进制文件 。 我正在使用poco库和C ++。 消息
3回复

重定向TCP连接

我有一些像我的客户端和实际视频服务器(用c ++制作)之间运行的代理服务器(用java编写)。 客户端发送的所有内容都通过此代理进行,然后重定向到服务器。 它工作正常,但我有一些问题,并认为如果我可以使这个代理服务器只听取客户端请求,然后以某种方式告诉服务器已从客户端发出请求,它会更好应该
1回复

TCP连接失败

我写了服务器和客户端代码,客户端可以正常连接服务器,但只能在本地地址上,我不知道如何通过互联网连接 我试图将getaddrinfo中的NULL更改为ip地址,但始终无法连接