簡體   English   中英

在Boost ASIO TCP套接字上接受多個連接

[英]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();
});

與BSD套接字接口的比較

我將在下面解釋其余部分,但這說明了要點。 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM