C++ Boost asio无故退出,代码为0。在有问题的语句后设置断点可以解决问题
我正在用boost asio编写一个TCP服务器客户端对。它非常简单和同步 服务器应该通过对通过TCP传输数据包的函数的多次递归调用来传输大量二进制数据。客户端通过从套接字读取传入数据包的递归函数进行模拟、读取和追加数据C++ Boost asio无故退出,代码为0。在有问题的语句后设置断点可以解决问题,c++,boost,boost-asio,C++,Boost,Boost Asio,我正在用boost asio编写一个TCP服务器客户端对。它非常简单和同步 服务器应该通过对通过TCP传输数据包的函数的多次递归调用来传输大量二进制数据。客户端通过从套接字读取传入数据包的递归函数进行模拟、读取和追加数据 然而,在接收此数据的中间,大多数时间(大约80%)客户端突然停止递归,总是在一个读调用之前(如下所示)。它不应该能够做到这一点,因为递归之后还有其他几个语句和函数调用 size_t bytes_transferred = m_socket.read_some(boost::as
然而,在接收此数据的中间,大多数时间(大约80%)客户端突然停止递归,总是在一个读调用之前(如下所示)。它不应该能够做到这一点,因为递归之后还有其他几个语句和函数调用
size_t bytes_transferred = m_socket.read_some(boost::asio::buffer(m_fileReadBuffer, m_fileReadBuffer.size()));
m_fileReadBuffer是一个大小为4096的boost::字符数组(尽管我也尝试过其他缓冲区格式,但没有成功)
我绝对无法想象推断出为什么会发生这种情况
- 程序立即退出,因此我无法传递错误代码来读取某些和任何错误消息,因为这需要在read_some语句之后发生
- 没有抛出异常
- 编译/运行时没有错误或警告
- 如果我在递归函数中设置断点,则问题永远不会发生(传输成功完成)
- 如果我在传输后放置断点,或者在传输后将执行陷于while循环中,那么问题永远不会发生,也没有任何错误的迹象
void TCP_Client::receive_volScan_message()
{
try
{
//If the transfer is complete, exit this loop
if(m_rollingSum >= (std::streamsize)m_fileSize)
{
std::cout << "File transfer complete!\n";
std::cout << m_fileSize << " "<< m_fileData.size() << "\n\n";
return;
}
boost::system::error_code error;
//Transfer isn't complete, so we read some more
size_t bytes_transferred = m_socket.read_some(boost::asio::buffer(m_fileReadBuffer, m_fileReadBuffer.size()));
std::cout << "Received " << (std::streamsize)bytes_transferred << " bytes\n";
//Copy the bytes_transferred to m_fileData vector. Only copies up to m_fileSize bytes into m_fileData
if(bytes_transferred+m_rollingSum > m_fileSize)
{
//memcpy(&m_fileData[m_rollingSum], &m_fileReadBuffer, m_fileSize-m_rollingSum);
m_rollingSum += m_fileSize-m_rollingSum;
}
else
{
// memcpy(&m_fileData[m_rollingSum], &m_fileReadBuffer, bytes_transferred);
m_rollingSum += (std::streamsize)bytes_transferred;
}
std::cout << "rolling sum: " << m_rollingSum << std::endl;
this->receive_volScan_message();
}
catch(...)
{
std::cout << "whoops";
}
}
void TCP\u客户端::接收\u volScan\u消息()
{
尝试
{
//如果传输完成,则退出此循环
if(m_rollingSum>=(std::streamsize)m_fileSize)
{
我还没有完全理解这个问题,但是我已经设法完全解决了
问题的根源在于,在客户端上,如果服务器消息尚未到达,则boost::asio::read
调用会以代码0退出
while(m_socket.available() == 0)
{
;
}
在所有读取调用完全阻止问题之前。在调试和发布模式下
这是非常奇怪的,因为据我所知,这些函数应该一直阻塞,直到有东西要读,即使遇到错误,它们也应该返回零
我认为出现调试/发布差异是因为每当发生读取调用时,m_readBuffer
没有初始化为任何内容。这使得read
调用返回某种形式的静默错误。在调试时,未初始化的变量会自动设置为NULL
,悄悄地解决了我的问题
不过,我不知道为什么在传输后添加while循环可以防止问题的发生,也不知道为什么它通常发生在传输结束时,在设置了m_readBuffer并成功使用了多次之后
除此之外,我从未见过这种“撞车”以前,程序只是在一个随机位置退出,代码为0,没有抛出错误或异常。“通过多次递归调用”这听起来不太正确。为什么它必须是递归的?可能是一些时间问题,也可能是某个地方的问题?或者可能是因为递归太多,以致于你填满了堆栈,而调用无法完成使用导致程序崩溃的堆栈溢出?@πάνταῥεῖ 这是一种简单的方法。函数检查是否所有数据都已传输,如果未传输,则发送一些数据并调用自身。@Daniel一个简单的循环就足够了。我仍然不认为使用递归有任何意义。@JoachimPileborg我测试了发送和接收消息之间存在较大延迟的时间问题,但仍然发生了这种情况。此外,我正在测试小文件,因此通常会有3或4个递归调用,这样的溢出肯定不会不被注意地通过。这似乎不是正确的解决方案。您的客户端如何知道希望从服务器获得多少数据?@SamMiller该文件始终有一个固定大小的头,其中包含文件大小等信息。while(m_socket.available()==0)调用在客户端等待读取此头时发生,在客户端等待读取文件内容(紧跟其后)时再次发生。我仍然不明白为什么读取函数在有数据读取之前不会自然阻塞,就像它们应该执行的那样。读取函数确实会按照请求执行阻塞操作,我怀疑您的问题出在其他地方,因为您没有发布消息。