首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >POCO连接卡住

POCO连接卡住
EN

Stack Overflow用户
提问于 2015-01-15 02:38:54
回答 1查看 864关注 0票数 0

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

代码语言:javascript
复制
  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;
  }

下面是处理程序:

代码语言:javascript
复制
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中,reactor不会触发onReadable事件。

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

任何意见或帮助,我们将不胜感激。

谢谢,

EN

回答 1

Stack Overflow用户

发布于 2015-04-03 02:33:07

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27950121

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档