Boost ASIO套接字读取N字节不多不少,等待它们到来或超时异常

Boost ASIO socket read N bytes not more not less and wait until they come or timeout exception?

本文关键字:异常 超时 等待 读取 套接字 ASIO 字节 Boost      更新时间:2023-10-16

基于示例创建一个简单的TCP服务器,但仍然不知道如何创建一个套接字,它将读取一定数量的字节,如果没有足够的字节将等待。我需要这不是异步操作

#include <iostream>
#include <boost/asio.hpp>
#ifdef _WIN32
#include "Windows.h"
#endif
using namespace boost::asio::ip;
using namespace std;
int main(){
    int m_nPort = 12345;
    boost::asio::io_service io_service;
    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), m_nPort));
    cout << "Waiting for connection..." << endl;
    tcp::socket socket(io_service);
    acceptor.accept(socket);
    cout << "connection accepted" << endl;
    try
    {
        socket.send(boost::asio::buffer("Start sending me datarn"));
    }
    catch(exception &e)
    {
        cerr << e.what() << endl; //"The parameter is incorrect" exception
    }
}

如何接收10000字节,并做到这一点,直到所有10000到达或1000毫秒超时,并抛出一个异常?

Boost 1.47.0刚刚为basic_socket_iostream引入了超时特性,即expires_atexpires_from_now方法。

下面是基于您的代码片段的示例:

#include <iostream>
#include <boost/asio.hpp>
using namespace boost::asio::ip;
using namespace std;
int main(){
    int m_nPort = 12345;
    boost::asio::io_service io_service;
    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), m_nPort));
    cout << "Waiting for connection..." << endl;
    tcp::iostream stream;
    acceptor.accept(*stream.rdbuf());
    cout << "Connection accepted" << endl;
    try
    {
        stream << "Start sending me datarn";
        // Set timeout in 5 seconds from now
        stream.expires_from_now(boost::posix_time::seconds(5));
        // Try to read 12 bytes before timeout
        char buffer[12];
        stream.read(buffer, 12);
        // Print buffer if fully received
        if (stream) // false if read timed out or other error
        {
            cout.write(buffer, 12);
            cout << endl;
        }
    }
    catch(exception &e)
    {
        cerr << e.what() << endl;
    }
}

这个程序可以在Linux上运行。

请注意,我并不提倡使用超时而不是带有截止日期计时器的异步操作。由你来决定。我只是想说明basic_socket_iostream可能存在超时

如何超时并抛出异常?

一般来说,只有在使用异步方法时才能获得超时和可取消性。有一些特定于平台的方法可以解决这个问题,这些方法在前面的问题中已经讨论过了。我强烈建议您研究使用异步方法,这将使理解逻辑容易得多。

也就是说,您可以通过在下面使用异步方法来呈现同步接口。这是在Asio库提供的阻塞TCP客户机超时示例中完成的。但是要注意,由于它的控制反转和lambda函数的使用,这个例子并不是完全直截了当的(尽管有很好的注释)。我建议您在尝试这样做之前先调查一下直接使用异步方法。

如何接收10000字节?

使用async_read free函数,注释部分描述了您所需要的

评论

这个重载相当于调用:

boost::asio::async_read(
    s, buffers,
    boost::asio::transfer_all(),
    handler);