[英]Accepting multiple connections on a boost asio tcp socket
也就是說,我在端口(未連接的套接字)上偵聽,並希望最后獲得兩個已連接的套接字。
換句話說,如果我在同一個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()
。
您可以這樣做:
acceptor_.async_accept(
[this] (std::error_code ec, tcp::socket&& new_socket) {
在這種情況下,您將獲得一個new_socket
對象,該對象表示接受的連接。 我從這個例子中得到了它。
希望我能正確理解您的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.