Boost.Asio 同步读写操作详解

Boost.Asio 同步读写操作详解

Boost.Asio 是一个高效的 C++ 网络和底层 I/O 库,提供了多种 API 用于同步和异步数据传输。本文将详细介绍同步操作及其具体实现,包括 write_somesendwriteread_somereceivereadread_until 等。


1. 同步写:write_some

功能: 将指定数量的字节写入到套接字。如果发送缓冲区已满,则只写入一部分数据并返回已写字节数。

特点:

  • 需要循环调用才能确保全部数据写完。
  • 每次写入的数据量由缓冲区的容量决定。

代码示例:

void write_to_socket(asio::ip::tcp::socket& sock) {
    std::string buf = "Hello World!";
    std::size_t total_bytes_written = 0;

    while (total_bytes_written != buf.length()) {
        total_bytes_written += sock.write_some(
            asio::buffer(buf.c_str() + total_bytes_written,
                         buf.length() - total_bytes_written));
    }
}

实际例子:
用于发送较大数据时,比如将日志分块写入到远程服务器。


2. 同步写:send

功能: 一次性发送缓冲区中的数据。如果缓冲区已满,则会阻塞,直到发送缓冲区有空闲。

特点:

  • 操作简单。
  • 自动处理缓冲区已满的情况。

代码示例:

int send_data_by_send() {
    asio::ip::tcp::socket sock(ios, ep.protocol());
    sock.connect(ep);
    std::string buf = "Hello World!";
    int send_length = sock.send(asio::buffer(buf.c_str(), buf.length()));

    if (send_length <= 0) {
        std::cout << "send failed" << std::endl;
        return 0;
    }
    return 0;
}

实际例子:
实时数据传输场景,如发送传感器数据到服务器。


3. 同步写:write

功能: 类似于 send,将整个缓冲区内容发送到对端,阻塞直到数据发送完成。

特点:

  • write 是更高层的封装。
  • 可与 asio::write 配合用于流式操作。

代码示例:

int send_data_by_write() {
    asio::ip::tcp::socket sock(ios, ep.protocol());
    sock.connect(ep);
    std::string buf = "Hello World!";
    int send_length = asio::write(sock, asio::buffer(buf.c_str(), buf.length()));

    if (send_length <= 0) {
        std::cout << "send failed" << std::endl;
        return 0;
    }
    return 0;
}

实际例子:
批量文件数据发送,例如将完整文件发送到云端。


4. 同步读:read_some

功能: 读取指定数量的字节。如果读取缓冲区为空,则会阻塞。

特点:

  • 返回读取的实际字节数。
  • 通常需要循环调用,直到读取到完整数据。

代码示例:

std::string read_from_socket(asio::ip::tcp::socket& sock) {
    const unsigned char MESSAGE_SIZE = 7;
    char buf[MESSAGE_SIZE];
    std::size_t total_bytes_read = 0;

    while (total_bytes_read != MESSAGE_SIZE) {
        total_bytes_read += sock.read_some(
            asio::buffer(buf + total_bytes_read,
                         MESSAGE_SIZE - total_bytes_read));
    }
    return std::string(buf, total_bytes_read);
}

实际例子:
读取固定长度的命令响应,如从数据库或设备返回的状态码。


5. 同步读:receive

功能: 一次性同步接收缓冲区中的数据。如果缓冲区为空,则会阻塞。

特点:

  • 操作简单。
  • 阻塞直到数据被完全接收或缓冲区满。

代码示例:

int read_data_by_receive() {
    asio::ip::tcp::socket sock(ios, ep.protocol());
    sock.connect(ep);
    char buffer_receive[BUFF_SIZE];
    int receive_length = sock.receive(asio::buffer(buffer_receive, BUFF_SIZE));

    if (receive_length <= 0) {
        std::cout << "receive failed" << std::endl;
    }
    return 0;
}

实际例子:
适用于接收固定格式的数据包,例如 IoT 设备发送的心跳包。


6. 同步读:read

功能: 类似于 receive,但提供更高级的封装,可以自动处理缓冲区管理。

特点:

  • 一次性读取到缓冲区满或数据读取完成。
  • 适合处理较大的数据块。

代码示例:

int read_data_by_read() {
    asio::ip::tcp::socket sock(ios, ep.protocol());
    sock.connect(ep);
    char buffer_receive[BUFF_SIZE];
    int receive_length = asio::read(sock, asio::buffer(buffer_receive, BUFF_SIZE));

    if (receive_length <= 0) {
        std::cout << "receive failed" << std::endl;
    }
    return 0;
}

实际例子:
传输大型文件或图片数据时的分块接收。


7. 同步读:read_until

功能: 一直读取数据,直到遇到特定字符(如换行符 \n)。

特点:

  • 适合处理基于分隔符的数据流。
  • 自动管理缓冲区,并返回分隔符前的数据。

代码示例:

std::string read_data_by_until(asio::ip::tcp::socket& sock) {
    asio::streambuf buf;
    asio::read_until(sock, buf, '\n');

    std::string message;
    std::istream input_stream(&buf);
    std::getline(input_stream, message);
    return message;
}

实际例子:
适用于实时聊天应用的消息接收,或日志服务器按行读取客户端日志。


总结

  • 写操作:
    • write_some: 低级别,需要循环调用。
    • sendwrite: 高级别,一次性发送。
  • 读操作:
    • read_some: 低级别,需要循环调用。
    • receiveread: 高级别,一次性读取。
    • read_until: 按分隔符读取数据流。

Boost.Asio 提供了丰富的同步 API,可以根据具体需求灵活选择使用,适用于各种网络应用场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值