简而言之,我的问题是,如果你有一个只有一个活动连接的tcp服务器,你可以只创建一个服务器端数据套接字。在所有教程中,我看到创建了一个新的套接字,我不明白为什么会出现这种情况。为什么不创建一个服务器端套接字然后打开,关闭,重置它(我原本希望async_accept以某种方式做到了)?
更详细:
我已经完成了针对异步日间服务器的boost asio教程,并且可以让它进行编译和工作。我甚至可以为我的应用程序修改它,让它按我的意愿运行:)。但是,我原来的方法不起作用,我不明白为什么我希望得到你的帮助。
基本上我想创建一个只接受一个TCP客户端并忽略所有其他客户端的TCP服务器,除非第一个客户端断开连接。我使用acceptor.close()和acceptor.open()这样做,这样当第一个连接被接受时我就关闭了接受器,然后每当我拿起一个eof错误时,我重新打开了接受器来监听新的连接。我天真地想,因为我只想要一个有效的连接,我只需要创建一个:
boost::asio::ip::tcp::socket socket_
因为我只有一个数据套接字从客户端接收数据,所以根据教程创建一个完整的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_;
};
因此我试图只使用一个boost :: asio :: ip :: tcp :: socket。我使用io_service以与上面教程类似的方式在我的服务器类的构造函数中初始化了这个。我的测试显示我的第一个客户端将连接,并且只有在第一个客户端断开连接后才会连接。但是,无论我做什么,async_accept(socket _,.....)调用上的数据缓冲区永远不会被填充。最初我只是不断得到eof错误,然后我尝试关闭socked并重新打开,这删除了eof错误并给出了传输结束没有连接错误。显然我在这里做了一些非常愚蠢的事情但是我无法从哲学角度看待我想要做的事情。当我使用教程技术创建一个新套接字时,一切都按预期工作。
所以我的问题是我可以只使用一个插槽并执行取消,关闭,打开等操作吗?我是想绑定还是别的但是不是async_accept job?
我现在只使用了提升asio一周,这是我第一次发布到这样的论坛,所以对我来说很容易;)。
答案 0 :(得分:3)
你可以,但你不能。
没有理由说TCP无法实现,但我没有注意到操作系统。
原因非常简单,因为OS 必须支持多个并发连接,因此这是指示实现的设计要求。要实现“只能有一个”的情况,只需在成功接受新连接后关闭侦听器套接字,然后再重新打开它。这样做通常不值得。
您描述的开销很小,不值得尝试优化。