C++ boost asio计时器不适用于阻止读取调用

C++ boost asio计时器不适用于阻止读取调用,c++,linux,sockets,boost,boost-asio,C++,Linux,Sockets,Boost,Boost Asio,我有以下服务器代码。它等待客户机连接,一旦客户机连接,它将启动从连接的客户机接收数据的线程,主线程将等待另一个客户机连接。这段代码运行良好 现在我必须指定服务器将等待一段时间(比如10秒)从连接的客户端接收数据。否则,如果在指定时间内未收到数据,服务器将关闭通信。我已经为同一个应用程序实现了计时器,但不知何故它不起作用,并且在经过一段时间后不会调用timer\u callback #include <ctime> #include <iostream> #include

我有以下服务器代码。它等待客户机连接,一旦客户机连接,它将启动从连接的客户机接收数据的线程,主线程将等待另一个客户机连接。这段代码运行良好

现在我必须指定服务器将等待一段时间(比如10秒)从连接的客户端接收数据。否则,如果在指定时间内未收到数据,服务器将关闭通信。我已经为同一个应用程序实现了计时器,但不知何故它不起作用,并且在经过一段时间后不会调用
timer\u callback

#include <ctime>
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <sys/socket.h>
#include <unistd.h>
#include <string>
#include <boost/bind.hpp>
#include <boost/thread.hpp>
#include <boost/date_time.hpp>

using namespace std;
using boost::asio::ip::tcp;

void run(boost::shared_ptr<tcp::socket> my_socket)
{
    while (1)
    {
        char buf[128];
        boost::system::error_code error;

        size_t len = my_socket->read_some(boost::asio::buffer(buf, 128), error);
        std::cout << "len : " << len << std::endl;

        if (error == boost::asio::error::eof)
        {
            cout << "\t(boost::asio::error::eof)" << endl;
            if (my_socket->is_open())
            {
                boost::system::error_code ec;
                cout << "\tSocket closing" << endl;
                my_socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
                cout << "\tShutdown " << ec.message() << endl;
                //cout << "normal close : " << ::close(my_socket->native_handle()) << endl;
                my_socket->close(ec);
                cout << "\tSocket closed" << endl;
            }
            break; // Connection closed cleanly by peer.
        }
        else if (error)
        {
            std::cout << "Exception : " << error.message() << std::endl;
            break;
        }
        else
        {
            for (unsigned int i = 0; i < len; i++)
                printf("%02x ", buf[i] & 0xFF);
            printf("\n");
        }
    }
}

void timer_callback(boost::shared_ptr<tcp::socket> my_socket, const boost::system::error_code& error)
{
    std::cout << "timer expired.... " << std::endl;
    if (error != boost::asio::error::operation_aborted)
    {
        // do something
        std::string str_error = "timer expired  " + error.message();
        my_socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both);
        my_socket->close();
    }
    else
    {
        std::cout << "timer cancelled ..." << error.message() << std::endl;
    }
}

int main()
{
    const int S = 1000;
    vector<boost::shared_ptr<boost::thread> > arr_thr(S);
    boost::asio::io_service io_service;
    boost::asio::deadline_timer timer(io_service);

    try
    {
        for (uint32_t i = 0;; i++)
        {

            tcp::endpoint endpoint(tcp::v6(), 10001);

            boost::shared_ptr<tcp::socket> my_socket(new tcp::socket(io_service));
            tcp::endpoint end_type;

            tcp::acceptor acceptor(io_service, endpoint);

            std::cout << "before accept" << endl;
            acceptor.accept(*my_socket, end_type);

            usleep(10000);

            std::cout << "connected... hdl : " << my_socket->native_handle() << std::endl;

            boost::asio::ip::address addr = end_type.address();
            std::string sClientIp = addr.to_string();

            std::cout << "\tclient IP : " << sClientIp << std::endl;

            timer.expires_from_now(boost::posix_time::seconds(10));
            timer.async_wait(
                    boost::bind(&timer_callback, my_socket, boost::asio::placeholders::error));

            arr_thr[i] = boost::shared_ptr<boost::thread>(new boost::thread(&run, my_socket));
        }
    } catch (std::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
使用boost::asio::ip::tcp;
无效运行(boost::共享\u ptr我的\u套接字)
{
而(1)
{
char-buf[128];
boost::system::error\u code error;
size\u t len=my\u socket->read\u some(boost::asio::buffer(buf,128),错误);

std::cout看起来您想从主线程执行
接受
异步等待
,并在单独的线程上执行一些阻塞读取

这种方法存在多个问题。首先,您的
accept
被阻塞,因此当主线程等待接受时,计时器无法运行。此外,没有调用
io\u服务
run
poll
,因此将永远不会调用异步处理程序

如果要在同一线程中混合使用
async\u wait
,则必须使用
async\u accept

但是,您仍然无法取消另一个线程上的阻塞读取。声明同时使用来自多个线程的套接字是不安全的(共享对象:不安全)


我建议您使用完全异步设计。

您好,我同意您使用完全异步设计的建议,但问题是,一旦我使用io_service.stop()&io_service.reset(),然后使用io_service.run())给出错误。这是因为存在挂起的异步操作。只需将其设计为当您要停止服务器时,停止发出任何异步操作,或在您要退出时放弃有关异步挂起操作的错误。通常,您不使用
io\u service::stop()
io\u service::reset()
在简单服务器中。查看文档中的示例以获取异步服务器示例代码。