繁体   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