You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Boost.Asio读写int向量的服务端客户端程序异常求助

Boost.Asio传输int向量异常:客户端接收随机值且无限阻塞

问题场景

基于Boost.Asio实现服务端与客户端,通过boost::asio::read和boost::asio::write传递int类型vector,预期服务端发送{1,2,3,4,5,6,7,8,9},客户端接收后输出,但实际客户端输出随机值且程序无限运行。

服务端代码(server.cpp)

#include <boost/asio.hpp>
#include <vector>
using boost::asio::ip::tcp;

int main()
{
    boost::asio::io_service ctx;
    std::vector<int> vc = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    tcp::acceptor s(ctx, tcp::endpoint({}, 1234));
    tcp::socket conn = s.accept();
    boost::asio::write(conn, boost::asio::buffer(vc));
} 

客户端代码(client.cpp)

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

int main()
{
    boost::asio::io_service ctx;
    tcp::socket s(ctx);
    s.connect(tcp::endpoint({}, 1234));
    std::vector<int> data(10);
    boost::asio::read(s, boost::asio::buffer(&data, sizeof(data)));

    for (auto x : data)
    {
        std::cout << x;
    }
}

实际现象

客户端输出大量随机值,且程序无限阻塞无法终止,输出示例:

26710220016661817222889274343557-214234613021914980240162615587848787224662874348677-17396929467224662874344069-204168283435745930074342533275669381911258937235205-10518278365142660544104632-2123472756944701572-531734500513653821913629-431025833424607876961438854961439111-1605430441513807051429161632526724-514957158-1286708961-1722871465961441157961440647-10517823135587861975587910445420122923239035401615725572156135866-921828804-53346303354091785516346447661095676702-529630690162195379954202857416346304291095676702-5296301791134131916325264895177476-53175062851527985158940-514916202558825605-428968316-244381721-1052917621558784836644769668-2041704702-2039585146-244387042-1972796771370310219-227626210-1841446849-244403426-240316597-1972796411370309963-227626210-1841446813-244403426-944959413-244387041-23083408513630013831919857438-1303465186-1536266722-2276098271689063955722665261701735454-46249085116722869991632510750-4814189801664991319558789404-246504676163873306321934878-512852195-508750817540917819-4289364201756172547-164364287-173190433-491957361-18996792912092702721463582721756954624676495360-2143748096148180172812092702759437233-398605863227607747-1588838227121307139359768881-1556233763-1269955807-1049730683-445750395-398606325110167107-1488174931-95114723612151757815976888

问题原因

  1. Buffer构造错误:客户端中boost::asio::buffer(&data, sizeof(data))是错误的。sizeof(data)获取的是std::vector对象本身的大小(仅包含内部指针、容量、大小等元数据,固定为几十字节),而非存储int元素的内存总字节数,导致实际读取的字节数远小于预期,后续元素内存未初始化,输出随机值。
  2. 数据量不匹配:服务端发送9个int的字节数,客户端却尝试读取10个int的字节数,boost::asio::read是阻塞式读取,必须读取到指定字节数才会返回。服务端发送完毕后退出,客户端无法获取剩余字节,导致程序无限阻塞。

解决方案

方案1:直接修正buffer和数据量匹配

调整客户端代码,让读取的字节数与服务端发送的一致,同时正确构造buffer:

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

int main()
{
    boost::asio::io_service ctx;
    tcp::socket s(ctx);
    s.connect(tcp::endpoint({}, 1234));
    // 服务端发送9个int,创建对应大小的vector
    std::vector<int> data(9);
    // 直接传入vector,Asio会自动计算元素总字节数
    boost::asio::read(s, boost::asio::buffer(data));

    for (auto x : data)
    {
        std::cout << x << " ";
    }
    std::cout << std::endl;
}

方案2:添加长度前缀(更健壮,适合未知数据量场景)

TCP是流协议,没有消息边界,更可靠的方式是先发送数据长度,再发送实际数据,客户端先读取长度再读取对应数据:

修正后的服务端

#include <boost/asio.hpp>
#include <vector>
#include <cstdint>
#include <arpa/inet.h> // 跨平台需替换对应头文件
using boost::asio::ip::tcp;

int main()
{
    boost::asio::io_service ctx;
    std::vector<int> vc = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    // 发送长度,用uint32_t保证跨平台兼容性
    uint32_t size = static_cast<uint32_t>(vc.size());
    // 转换为网络字节序(跨平台时必须)
    size = htonl(size);

    tcp::acceptor s(ctx, tcp::endpoint({}, 1234));
    tcp::socket conn = s.accept();
    // 先发送长度
    boost::asio::write(conn, boost::asio::buffer(&size, sizeof(size)));
    // 再发送实际数据
    boost::asio::write(conn, boost::asio::buffer(vc));
} 

修正后的客户端

#include <boost/asio.hpp>
#include <iostream>
#include <cstdint>
#include <arpa/inet.h> // 跨平台需替换对应头文件
using boost::asio::ip::tcp;

int main()
{
    boost::asio::io_service ctx;
    tcp::socket s(ctx);
    s.connect(tcp::endpoint({}, 1234));

    // 先读取长度
    uint32_t size = 0;
    boost::asio::read(s, boost::asio::buffer(&size, sizeof(size)));
    // 转换为主机字节序
    size = ntohl(size);

    // 根据长度创建vector
    std::vector<int> data(size);
    boost::asio::read(s, boost::asio::buffer(data));

    for (auto x : data)
    {
        std::cout << x << " ";
    }
    std::cout << std::endl;
}

内容的提问来源于stack exchange,提问作者NOK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 18:01:23