即使套接字已收到数据,async_read_some() 操作也不会运行?

问题描述 投票:0回答:1

int main(int argc, char *argv[])
{   

    int acceptingCounter = 0;

    std::array<char, 2048> message_buffer;

    boost::asio::io_context io_context;

    std::vector<tcp::endpoint * > active_connections;
    std::vector< tcp::socket * > mySocks;

    //Create a tcp::acceptor object to listen for new connections.
    //Initialised to listen on port 13.

    tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), 1025));
    bool reading = false;

    std::cout << "Accepting..." << std::endl;

    while (true)
    {

        if (acceptingCounter < 1){ 

            tcp::socket * sock = new tcp::socket(io_context);
            tcp::endpoint * endpoint = new tcp::endpoint;

            // mySocks.push_back(sock);
            acceptor.async_accept(*sock,*endpoint,[endpoint,&active_connections, &acceptingCounter, &mySocks, sock](boost::system::error_code e)
            {
                active_connections.push_back(endpoint);
                mySocks.push_back(sock);
                
                std::cout << "Client newly accepted on: " << *endpoint << std::endl;
            });
            acceptingCounter++;
        }

        if (active_connections.size() > 0)
        {
            if (!reading){
                for (tcp::socket * s : mySocks){
                     reading = true;
                     s->async_read_some(boost::asio::buffer(message_buffer), [&message_buffer,s,&reading, mySocks](const boost::system::error_code &ec, std::size_t bytes_transferred)
                     {
                          //some completion code
                       reading = false;
                     }
                }
            }
        }
        

        io_context.poll();
        io_context.restart();

        //delete all endpoints and delete all sockets.
     
    }
    return 0;
}

所以我在这里有一个服务器脚本,我似乎无法弄清楚为什么 async_read_some 完成代码永远不会运行。当我让我的客户端成功将数据发送到此套接字时,io_context.poll() 甚至使用 run() 似乎永远不会运行完成代码,或者异步操作永远不会被视为“已完成”,据我所知,因此它永远不会运行。 为什么它从未被视为已完成,套接字对象没有超出范围,甚至在套接字上使用阻塞 read() 时我也无法超越它并实际看到收到的数据?请注意,我确实有完成 lambda 函数,它实际上打印出来,它不仅被注释掉,如下所示,但没有显示任何内容。客户端肯定会发送数据,因为我没有收到错误代码,并且 async_send() 的完成处理程序在该端运行。我还检查了它是否正在接受并尝试通过查看远程端点在同一个套接字上读取,但它不起作用。

c++ asynchronous networking boost-asio
1个回答
0
投票

所以,您的代码存在很多问题。主要的一点似乎是它正在发挥作用。

我把它做成了独立的:

住在科里鲁

#include <array>
#include <boost/asio.hpp>
#include <iostream>
using boost::asio::ip::tcp;
using boost::system::error_code;

int main() {
    int acceptingCounter = 0;

    std::array<char, 2048> message_buffer;

    boost::asio::io_context io_context;

    std::vector<tcp::endpoint*> active_connections;
    std::vector<tcp::socket*>   mySocks;

    // Create a tcp::acceptor object to listen for new connections.
    // Initialised to listen on port 13.

    tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), 1025));
    bool          reading = false;

    std::cout << "Accepting..." << std::endl;

    while (true) {
        std::cout << "Active connections: " << active_connections.size() << std::endl;
        std::cout << "Accepting counter: " << acceptingCounter << std::endl;
        if (acceptingCounter < 1) {

            tcp::socket*   sock     = new tcp::socket(io_context);
            tcp::endpoint* endpoint = new tcp::endpoint;

            // mySocks.push_back(sock);
            acceptor.async_accept( //
                *sock, *endpoint,
                [endpoint, &active_connections /*, &acceptingCounter*/, &mySocks, sock](error_code e) {
                    std::cout << "Client newly accepted on: " << *endpoint << " (" << e.message()
                              << std::endl;
                    active_connections.push_back(endpoint);
                    mySocks.push_back(sock);
                });
            acceptingCounter++;
        }

        if (active_connections.size() > 0) {
            if (!reading) {
                for (tcp::socket* s : mySocks) {
                    reading = true;
                    s->async_read_some(
                        boost::asio::buffer(message_buffer),
                        [/*&message_buffer, s,*/ &reading, mySocks](error_code ec, size_t transferred) {
                            std::cout << "Received: " << transferred << " bytes (" << ec.message() << ")"
                                      << std::endl;
                            // some completion code

                            reading = false;
                        });
                }
            }
        }

        io_context.run();
        io_context.restart();
        // delete all endpoints and delete all sockets.
    }
}

通过 Coliru 或本地进行现场演示:

问题

你有内存泄漏,竞争条件,不必要的动态分配,使用原始的新/删除,但也

  • 接受循环从不接受新连接
  • asio 的整个概念是抽象事件循环,你用大量的状态对其进行硬编码,就像你正在编写 C 风格的 epoll/select 代码一样。这意味着您甚至不能在单独的连接上并行进行两次读取。这与异步 IO 的目的背道而驰。

这是我的修复建议:

[即将推出]

© www.soinside.com 2019 - 2024. All rights reserved.