繁体   English   中英

我如何在带有超时的boost asio套接字中检查数据

[英]How can I check data in boost asio socket with timeout

我如何读取boost :: asio :: socket缓冲区中是否有数据? 该检查应阻止程序执行,直到达到超时为止。 我发现可以使用该功能

boost::asio::socket_base::bytes_readable

但似乎是一种无阻塞操作,无需检查任何超时即可运行。 我不想使用async_read,但是如果有一些要读取的数据,则直接读取套接字

您只需使用事件循环使该套接字变为非阻塞状态,然后等待该套接字准备好进行读取或超时即可。

阻止等待套接字中某些字节的程序执行的一种简单方法是,将函数置于while周期中,以监视经过的时间。 下面是一个简单的解决方案,它将:

  • 连接到服务器
  • 从服务器读取。 如果什么也没读,请等待直到超时
  • 检查服务器消息并回复

int find_char(char *缓冲区,size_t size_out,char chr)

#include <boost/asio.hpp>  

int main () {
    const int MAX_BUFFER_SIZE = 1024; //max size of buffer
    const char PACKET_END     = static_cast<char>(0xFF); //character that identifies the end of a packet

    //creation of Client Socket
    boost::asio::io_service ios;
    boost::asio::ip::tcp::socket client_socket(ios);

    //creation of endpoint connection
    std::string host_ip = "199.01.00.00";
    int port_number   = 2000;                    
    boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::address::from_string(host_ip), port_number);

    //connect client socket to server
    boost::system::error_code error_connection;         //connection error

    //conect to server
    bool is_connected = false;
    client_socket.connect(endpoint, error_connection);
    if(!error_connection)
        is_connected = true;

    //read from server buffer
    if (is_connected == true) { //connected

        //create empty buffer to store from server
        char buffer[MAX_BUFFER_SIZE];
        std::fill(buffer, buffer + sizeof(buffer), 0);

        //TCPIP read from buffer
        boost::system::error_code error_read;

        //initialize Timeout variables
        int timeout = 5000000; //timeout of 5 seconds [microsec]
        boost::posix_time::time_duration difference;        //elapsed time
        boost::posix_time::time_duration time_to_read;      //duration of reading
        boost::posix_time::ptime start_try_read = boost::posix_time::microsec_clock::local_time(); //save initial time to read

        //understand if there is something to read
        size_t bytes_readable = 0;
        bool something_to_read = false; //check if something to read
        do {
                boost::posix_time::ptime start_read = boost::posix_time::microsec_clock::local_time(); //save initial time to try read

                boost::asio::socket_base::bytes_readable num_bytes_readable(true);
                client_socket.io_control(num_bytes_readable, error_read);
                bytes_readable = num_bytes_readable.get(); //get the value of readable data

                if ( bytes_readable > 0 ){
                    //found something to read
                    something_to_read = true;
                    break;
                }
                if (error_read == boost::asio::error::not_connected){
                    //server disconnected
                    is_connected = false;
                    something_to_read = false;
                    break;
                }
                boost::posix_time::ptime end_read = boost::posix_time::microsec_clock::local_time(); //save final time to try read
                time_to_read = end_read - start_read;
                difference = end_read - start_try_read;
        } while ( difference + time_to_read < boost::posix_time::microsec(time_out) && bytes_readable <= 0 );

        if (is_connected == true && difference + time_to_read >= boost::posix_time::microsec(time_out)) {
            //nothing to read, timeout
            something_to_read = false;
        } 
        else if (is_connected == true && !error_read && bytes_readable > 0) {

            //prepare to store the buffer
            char buffer_socket[bytes_readable + 1];
            std::fill(buffer_socket, buffer_socket + sizeof(buffer_socket), 0);

            //read from buffer the readable bytes amount and store
            boost::asio::read(client_socket, boost::asio::buffer(buffer_socket, bytes_readable));

            //check if message contains special character
            int position_end = find_char(buffer_socket, sizeof(buffer_socket), static_cast<char>(PACKET_END));

            //in case found an interesting message, reply to server
            if (position_end >= 0){
                std::memcpy(buffer, buffer_socket, position_end + 1); //found interesting message, store it
                //write response to server socket
                char response[100] = "received good message";
                boost::system::error_code error_write;
                boost::asio::write(client_socket, boost::asio::buffer((char*)ct_request_buffer, sizeof(ct_request_buffer)), error_write);
            }
        }
    }
}
int find_char(char* buffer, size_t size_out, char chr){
    int pos = -1;
    size_t i = size_out - 1;
    while (i >= 0){
        if (buffer[i] == chr){
            pos = i;
            break;
        }
        i--;
    }return pos;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM