[英]Multiple connections on the same boost tcp socket object
在此示例(async_tcp_echo_server.cpp)中 ,
#include <cstdlib>
#include <iostream>
#include <memory>
#include <utility>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
class session
: public std::enable_shared_from_this<session>
{
public:
session(tcp::socket socket)
: socket_(std::move(socket))
{
}
void start()
{
do_read();
}
private:
void do_read()
{
auto self(shared_from_this());
socket_.async_read_some(boost::asio::buffer(data_, max_length),
[this, self](boost::system::error_code ec, std::size_t length)
{
if (!ec)
{
do_write(length);
}
});
}
void do_write(std::size_t length)
{
auto self(shared_from_this());
boost::asio::async_write(socket_, boost::asio::buffer(data_, length),
[this, self](boost::system::error_code ec, std::size_t /*length*/)
{
if (!ec)
{
do_read();
}
});
}
tcp::socket socket_;
enum { max_length = 1024 };
char data_[max_length];
};
class server
{
public:
server(boost::asio::io_service& io_service, short port)
: acceptor_(io_service, tcp::endpoint(tcp::v4(), port)),
socket_(io_service)
{
do_accept();
}
private:
void do_accept()
{
acceptor_.async_accept(socket_,
[this](boost::system::error_code ec)
{
if (!ec)
{
std::make_shared<session>(std::move(socket_))->start();
}
do_accept();
});
}
tcp::acceptor acceptor_;
tcp::socket socket_;
};
int main(int argc, char* argv[])
{
try
{
if (argc != 2)
{
std::cerr << "Usage: async_tcp_echo_server <port>\n";
return 1;
}
boost::asio::io_service io_service;
server s(io_service, std::atoi(argv[1]));
io_service.run();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
多個會話使用相同的boost::ip::tcp::socket
對象。 在do_accept()
函數內部,每次傳入連接時,我們都在創建一個新的會話對象,並通過rvalue引用(即std::move()
將socket_
傳遞給該對象。
假設我們有兩個活動的連接(S1和S2)。 結構大致如下所示
Server
|
|_ socket_
/\
/ \
/ \
S1 S2
因此,S1和S2都將使用相同的socket_
從網絡讀取消息/向網絡寫入消息。
我對此有兩個問題:
對於第一個連接,一切都很好,但是為什么第二個連接應該可以正常工作呢? 我們不是已經將socket_
的所有權socket_
到了第一次會話嗎?
如何確保將回復發送到正確的客戶端? 每當套接字上有東西到達時,兩個async_read_some
任何一個都不會觸發嗎?
對於第一個連接,一切都很好,但是為什么第二個連接應該可以正常工作呢? 我們不是已經將socket_的所有權轉移到了第一次會話嗎?
從插槽中移出后,該插槽實際上是“空”或“新創建的”。 這就是為什么這樣。
不,套接字對象不會“神奇地”與移動的實例共享身份。 實際上,身份只不過是底層套接字句柄,而后者顯然是不共享的。
但是在第二個連接的情況下會發生什么,因為我們在所有連接中都使用相同的套接字?
你不是。 您沒有使用相同的套接字句柄。 您也沒有使用相同的asio::ip::tcp::socket
對象實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.