我正在研究处理TCP套接字连接的一段代码上的一个奇怪问题:每隔10分钟,我们的客户端在使用boost async_read_some()读取数据时会收到一个EOF错误。 当客户端<->服务器连接丢失并且因此我们的客户端正常关闭连接然后重新打开它时,通常会发生这种情况。
但是,当更深入地寻找EOF错误的原因时,我发现:
有人对我为什么得到EOF有任何想法吗?我在Gentoo Linux上使用Boost v1.56.0。
先谢谢您。 SiS。
编辑:这是代码的简化版本,给了我这个问题(很抱歉,但是我无法发布实际的代码):
#include <boost/asio.hpp>
#include <boost/function.hpp>
#include <boost/signals2.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <cstddef>
static const unsigned int g_reconnect_time = 15; // Seconds
class conn_t
{
public:
conn_t( std::string ip, int port, boost::asio::io_service& io_service ) :
m_tcp_host(ip),
m_tcp_port(port),
m_io_service( io_service ),
m_socket( io_service ),
m_reconnect_interval( g_reconnect_time ),
m_reconnect_timer( io_service, m_reconnect_interval )
{
}
~conn_t()
{
disconnect();
}
bool connect()
{
using boost::asio::ip::tcp;
tcp::resolver resolver( m_io_service );
tcp::resolver::query query( tcp_host, m_tcp_port);
tcp::resolver::iterator endpoint_iterator = resolver.resolve( query );
tcp::resolver::iterator end;
boost::system::error_code error = boost::asio::error::host_not_found;
while ( error && ( endpoint_iterator != end ) )
{
m_socket.close();
m_socket.connect( *endpoint_iterator++, error );
}
if ( error )
{
// Bail out and schedule for retry:
queue_reconnect();
return false;
}
if ( !m_socket.is_open() )
return false;
read_data();
return true;
}
void disconnect()
{
m_socket.close();
}
void read_data()
{
m_socket.async_read_data_some( boost::asio::buffer( m_buff ),
[this]( const boost::system::error_code& error, std::size_t len )
{
if ( handle_error( error ) )
{
std::cerr << "Error read_dataing data: " << std::endl;
reconnect();
}
else
{
std::cerr << "got " << len << " bytes of data" );
// process data here...
read_data();
}
} );
}
void reconnect()
{
queue_reconnect();
}
private:
bool handle_error ( const boost::system::error_code& error )
{
if ( error && error != boost::asio::error::operation_aborted )
{
std::cerr << "Socket i/o error: " << error.message() << std::endl;
boost::system::error_code ignored_ec;
m_socket.shutdown( boost::asio::ip::tcp::socket::shutdown_both, ignored_ec );
m_socket.close();
return true;
}
return false;
}
void queue_reconnect()
{
auto new_deadline = m_reconnect_timer.expires_at() + m_reconnect_interval;
if ( new_deadline > boost::asio::deadline_timer::traits_type::now() )
m_reconnect_timer.expires_at( new_deadline );
else
m_reconnect_timer.expires_from_now( m_reconnect_interval );
m_reconnect_timer.async_wait( boost::bind( &conn_t::start, this ) );
}
private:
std::string tcp_host;
int m_tcp_port;
boost::asio::io_service& m_io_service;
boost::asio::ip::tcp::socket m_socket;
boost::posix_time::seconds m_reconnect_interval;
boost::asio::deadline_timer m_reconnect_timer;
char m_buff[1024];
};