基于 POCO C++ 库的多线程 TCP 服务器

5
我正在尝试使用POCO C++库开发TCP服务器。我在这里找到了一些示例(链接)。起初,我尝试了Alex的示例,但关闭事件不能正常工作。EchoServer也有同样的问题。然后,我尝试了Cesar Ortiz的示例,遇到了一个不寻常的问题。一段时间后,服务器会抛出一个错误:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
["src/ErrorHandler.cpp", line 60]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

连接出现连接超时错误,包括新连接在内。 使用事件处理程序的示例似乎更正确,但我不知道如何修复关闭事件。

1个回答

14
如果你只需要一个多线程的TCP服务器,那么“开箱即用”的Poco::Net::TCPServer就可以胜任 - 它在内部进行了多线程处理。 从定义连接开始,这个服务器会简单地将你发送的内容回显。
class EchoConnection: public TCPServerConnection {
public:
  EchoConnection(const StreamSocket& s): TCPServerConnection(s) { }

  void run() {
    StreamSocket& ss = socket();
    try {
      char buffer[256];
      int n = ss.receiveBytes(buffer, sizeof(buffer));
      while (n > 0) {
        ss.sendBytes(buffer, n);
        n = ss.receiveBytes(buffer, sizeof(buffer));
      }
    }
    catch (Poco::Exception& exc)
    { std::cerr << "EchoConnection: " << exc.displayText() << std::endl; }
  }
};

然后,运行服务器并向其发送一些数据:

TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>());
srv.start();

SocketAddress sa("localhost", srv.socket().address().port());
StreamSocket ss(sa);
std::string data("hello, world");
ss.sendBytes(data.data(), (int) data.size());
char buffer[256] = {0};
int n = ss.receiveBytes(buffer, sizeof(buffer));
std::cout << std::string(buffer, n) << std::endl;

srv.stop();

谢谢回复,Alex。正如我所说,现在我使用了像你的第二个例子一样的代码,但是我找不到“src/errorhandler.cpp”错误信息的原因。在这之后,服务器可以接受连接,但无法发送或接收新连接的字节,并对现有连接抛出“连接超时”的异常。 - Valera A.
你的连接处理程序中一定抛出了异常。由于它在线程中运行,所以最终会进入默认的错误处理程序。异常可能不是 std::exception 的子类,因此 ErrorHandler 对其一无所知。但是你没有提供足够的信息来确定问题所在。最好在调试器中运行代码并逐步查找问题的源头。 - Alex
正如我所说,我使用Cesar Ortiz的例子,只是更改了“run”函数 - 这里。我发现当连接无法获取数据时,因为它在队列中,但我不明白为什么?当当前连接达到16个时,所有新连接都将添加到队列中,并在之后被拒绝。在参数中,我设置了maxqueued(3),maxthreads(20)和threadidletime(100)。 - Valera A.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接