也就是说,我监听一个端口(未连接的套接字),并希望最后获得两个连接的套接字。
换句话说,如果我在同一个tcp套接字上接受两次,则无法解决在asio中如何区分两个连接的套接字的问题。这是在Linux上。
我有一个相对简单的tcp服务器类。它假定所有可能连接到它的客户端都是同构的:如果消息正在等待发送到客户端,而没有连接,则可以将其发送到下一个连接的客户端。这对于一个连接的套接字非常有用,但是现在我需要监听多个套接字(也就是说,两个客户端将连接)。同质性假设仍然几乎是正确的,但是现在我有了另一个约束,即如果消息是对某人的响应,则该消息应该发给该人。 (回复通常是确认。)
我从倾听和接受开始:
short port = kSomethingKnown;
boost::asio::io_service& io_service_;
boost::asio::ip::tcp::socket socket_(io_service_);
boost::asio::ip::tcp::acceptor acceptor_(
io_service_,
boost::asio::ip::tcp::endpoint(tcp::v4(), port));
acceptor_.async_accept(socket_, [this](boost::system::error_code ec) {
if (ec) {
// Failed to accept. Schedule to try again (not shown).
return;
}
// Accepted.
SendMessage(); // Flush any old messages, appropriate with a single client.
ReceiveHeader();
});
我将在下面解释其余部分,但这说明了要点。 ACCEPT(2)看起来像这样:
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
返回值(如果非零)是所连接套接字的文件描述符。也就是说,如果我在主机H上并且正在侦听端口P,那么sockfd
代表未连接的套接字,
(H, P, tcp, 0, 0)
返回的文件描述符表示已连接的套接字,
(H, P, tcp, H1, P1)
其中H1是客户端主机,而P1是客户端的(可能是短暂的)端口,它是此套接字的另一侧。如果我第二次成功接受,我将获得另一个已连接的套接字,
(H, P, tcp, H2, P2)
其中H2和P2中的至少一个不同于H1和P1。我在asio中看不到如何引用这两个连接的套接字。我一直在阅读源代码,这在教会我很多有关asio的工作原理,而不是async_accept
的工作原理。
首先,这是发送和接收呼叫的详细信息,但是我认为以上正是我真正需要的。了解这一点后,我将使用这些连接的套接字而不是socket_
。
SendMessage()
以接收消息的形式存在(只是将消息推送到双端队列),而上面的形式则用于处理队列。第二种形式如下:
void SendMessage() {
if (WeAreDead()) {
// This checked that the connection seems valid,
// we aren't being asked to shut down, etc.
return;
}
if (send_queue_.empty()) {
// Nothing to send.
return;
}
boost::asio::async_write(
socket_, boost::asio::buffer(send_queue_.front()),
[this](boost::system::error_code ec, size_t length) {
if (ec) {
// Failed, schedule another attempt, not shown here.
return;
}
send_queue_.pop_front();
if (!send_queue_.empty()) {
SendMessage();
}
});
}
ReceiveHeader()
(和相似的ReceiveBody()
)看起来很相似,关键是这样的呼叫:
boost::asio::async_read(
socket_, boost::asio::buffer(receive_buffer_, kTcpHeaderSize),
boost::asio::transfer_exactly(kTcpHeaderSize),
[this](boost::system::error_code ec, std::size_t received_length) {
同样,我发现令人困惑的部分与async_accept()
有关。
答案 0 :(得分:2)
您可以这样做:
acceptor_.async_accept(
[this] (std::error_code ec, tcp::socket&& new_socket) {
在这种情况下,您将获得一个new_socket
对象,该对象表示接受的连接。我是从example那里摘下来的。
希望我能正确理解您的问题。