Boost asio tcp,为什么我不能在服务器端只有一个数据套接字可以打开和关闭

use*_*872 5 c++ sockets boost tcp boost-asio

简而言之,我的问题是,如果您有一台只有一个活动连接的 tcp 服务器,您可以只创建一个服务器端数据套接字吗?在所有教程中,我看到创建了一个新套接字,但我不明白为什么会出现这种情况。为什么不创建一个服务器端套接字,然后打开、关闭、重置它(我最初希望 async_accept 以某种方式做到了)?

更详细地说:

我已经完成了异步日间服务器的 boost asio 教程,并且可以让它编译和工作。我什至可以为我的应用程序修改它并让它按照我的意愿运行:)。然而,我原来的方法不起作用,我不明白为什么,这就是我希望得到你的帮助的地方。

基本上我想创建一个 TCP 服务器,它只接受一个 TCP 客户端并忽略所有其他客户端,除非第一个客户端断开连接。我使用acceptor.close()和acceptor.open()来做到这一点,这样当第一个连接被接受时,我只是关闭了接受器,然后每当我发现一个eof错误时,我就重新打开接受器来监听新的连接。我天真地认为,因为我只想要一个活动连接,所以我只需要创建一个:

boost::asio::ip::tcp::socket socket_
Run Code Online (Sandbox Code Playgroud)

由于我只有一个数据套接字从客户端接收数据,因此根据教程创建整个 tcp_connection 类似乎有点过分,据我所知,它只返回一个用 io_service 构造的新套接字。(在本教程中,我认为每次服务器接受新连接时,都会使用此代码创建新套接字):

class tcp_connection
  : public boost::enable_shared_from_this<tcp_connection>
{
 public:
  typedef boost::shared_ptr<tcp_connection> pointer;

  static pointer create(boost::asio::io_service& io_service)
  {
    return pointer(new tcp_connection(io_service));
  }

  tcp::socket& socket()
  {
    return socket_;
  }


 private:
  tcp_connection(boost::asio::io_service& io_service)
    : socket_(io_service)
  {
  }

  tcp::socket socket_;
  std::string message_;
};
Run Code Online (Sandbox Code Playgroud)

因此,我尝试只使用一个 boost::asio::ip::tcp::socket。我使用 io_service 以与上面教程类似的方式在服务器类的构造函数中初始化了它。我的测试表明,我的第一个客户端会连接,只有在第一个客户端断开连接后,第二个客户端才会连接。但是,无论我做什么, async_accept(socket_,.....) 调用上的数据缓冲区都永远不会被填满。最初我只是不断收到 eof 错误,然后我尝试关闭 socked 并重新打开,这消除了 eof 错误并给出了传输端未连接错误。显然我在这里做了一些非常愚蠢的事情,但我看不出从哲学上讲我想做的事情有什么问题。当我使用教程技术创建一个新套接字时,一切都按预期工作。

所以我的问题是我可以只有一个套接字并执行诸如取消、关闭、打开之类的操作吗?我是要绑定还是其他东西,但这不是 async_accept 工作吗?

我现在只使用了 boost asio 一周,这是我第一次在这样的论坛上发帖,所以对我要宽容;)。

Bri*_*ite 3

你可以,但你不能。

没有理由不能像你所说的那样实现 TCP,但据我所知,没有操作系统这样做。

原因很简单,操作系统必须支持多个并发连接,因此这是决定实现的设计要求。要实现“只能有一个”情况,只需在成功接受新连接后关闭侦听器套接字并稍后重新打开它即可。通常不值得为此付出努力。

您描述的开销很小,不值得尝试优化。