【问题标题】:Boost Tcp Client Receive CrashBoost Tcp 客户端接收崩溃
【发布时间】:2017-06-07 05:16:58
【问题描述】:

我最近一直在使用 Windows Visual Studio 2015 的 Boost 库。我最​​近一直在研究可以通过 tcp 连接轻松传输数据的服务器和客户端。但最近我试图向客户端发送一个 Base64 编码的文件字符串,它大约是 366,660 字节的数据。为此,我将数据分成大小约为 1000 的数据包。 (不确定最大大小是多少)但无论如何服务器发送数据完全正常,但是当客户端接收到超过 160,000 个字节时,它会崩溃,无一例外。

客户:

try
{
    for (static int i = 1000; i <= sizeofpackets /*(366,660) (currently 170,000 for testing)*/; i += 1000)
    {
        char Buffer[1000];
        memset(Buffer, 0, 1000);
        boost::asio::read(s, boost::asio::buffer(Buffer, 1000));
        std::cout << i << std::endl;
    }
}
catch (std::exception& e)
{
    std::cerr << "Exception: " << e.what() << "\n";
}

服务器:

for (int i = 1000; i <= 170000; i += 1000)
{
    std::string NewData = encodedBuffer.substr(i - 1000, i);
    NewData.erase(0, i - 1000);
    boost::asio::write(*sock, boost::asio::buffer(NewData, 1000));
    std::cout << NewData.size() + i - 1000 << std::endl;
    NewData.clear();
}

任何 cmets 或建议都会有很大帮助!

【问题讨论】:

  • 到目前为止,您尝试了哪些方法来确定崩溃的原因?
  • 我将其调试为 boost::asio::read 并且每次迭代都会重置缓冲区,所以不确定还要检查什么。

标签: c++ boost tcp boost-asio boost-thread


【解决方案1】:

你还没有发布你的完整代码,所以很难说,但你的问题可能是你处理字符串的方式,而不是你处理套接字传输的方式(substr() 成员函数开始了偏移量和大小,看起来您正在尝试为 NewData 使用不断增加的大小)。

以下(完整)代码使用您的客户端和服务器代码作为参考,但更改了字符串处理,在我的机器上确实可以传输 170000 字节,所以它可能会有所帮助:

#include <boost/asio/io_service.hpp>
#include <boost/asio/write.hpp>
#include <boost/asio/read.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/asio/streambuf.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <array>
#include <string>
#include <iostream>


namespace
{
    const size_t BIG_MESSAGE_SIZE = 170000;
    const size_t BLOCK_SIZE = 1000;

    void doTX(boost::asio::ip::tcp::socket& socket, size_t& TXsize)
    {
        char rawBuffer[BIG_MESSAGE_SIZE] = { 0 }; // raw data to send
        std::string encodedBuffer(rawBuffer, BIG_MESSAGE_SIZE);
        for (size_t i = 0; i < BIG_MESSAGE_SIZE; i += BLOCK_SIZE)
        {
            std::string NewData = encodedBuffer.substr(i, BLOCK_SIZE);
            TXsize += boost::asio::write(socket, boost::asio::buffer(NewData, BLOCK_SIZE));
        }
    }

    void doRX(boost::asio::ip::tcp::socket& socket, size_t& RXsize)
    {
        for (size_t i = 0; i < BIG_MESSAGE_SIZE; i += BLOCK_SIZE)
        {
            char Buffer[BLOCK_SIZE];
            memset(Buffer, 0, BLOCK_SIZE);
            RXsize += boost::asio::read(socket, boost::asio::buffer(Buffer, BLOCK_SIZE));
        }
    }
}

int main(int argc, char * argv[])
{
    std::cout << "Running:" << std::endl;

    int port = 9876;

    boost::asio::io_service ios;
    boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::address::from_string("127.0.0.1"), port);
    boost::asio::ip::tcp::acceptor acceptor(ios, endpoint);
    boost::asio::ip::tcp::socket TXsocket(ios);
    boost::asio::ip::tcp::socket RXsocket(ios);

    TXsocket.connect(endpoint);
    acceptor.accept(RXsocket);

    size_t TXsize = 0;
    size_t RXsize = 0;

    doTX(TXsocket, TXsize);
    doRX(RXsocket, RXsize);

    std::cout << TXsize << " " << RXsize << std::endl;

    return 0;
}

【讨论】:

  • 我不能在一个数据包中发送一个 366,600 字节的字符串,所以我将它分成 1000 个间隔数据包。这就是 NewData 正在发生变化的原因。我还将它更改为 1024 以充分利用我的数据包,似乎服务器发送字符串很好,但客户端似乎在某个点停止。 image.prntscr.com/image/f9595c1acc41437bb37070d96e631731.png
  • @Opendn33 是的,我知道您正在尝试做什么,但不幸的是您没有发布代码的完整工作版本,因此我无法验证它是否按您的预期工作。如果你能做到,我会尽力提供帮助。如果没有,我建议您在每次调用 write() 时检查返回值,并使用它来更新实际发送量的运行总计(以我的代码为例),只需打印出 NewData.size() + i - 1000 不可​​靠。
  • 非常感谢您的帮助,我刚刚检查了发送字节的返回数据,它以百万计,所以我通过更改数据类型来修复它,现在它只发送 1024。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-05
  • 2012-03-15
  • 2017-01-11
相关资源
最近更新 更多