我有几个关于 Boost ASIO 的问题。
我遇到了一个问题,我的客户端可以连接到服务器并异步发送数据,但无法收到任何回复。async_write 回调得到错误:“提供的文件句柄无效”。我觉得这很奇怪,有几个原因:
- 当客户端最初连接时,我检查服务器上的 socket.isOpen(),它返回 true。
- 客户端仍然可以发送数据的事实使我认为这是服务器端问题或防火墙问题(我觉得很奇怪,因为服务器和客户端都在同一台计算机上(我使用“localhost”连接现在)。
更多信息...
TCP 套接字。
我正在并排使用 Boost 和 Allegro,并且正在使用 Boost 和 Allegro 线程。我的 io_service 像这样(服务器和客户端)在 Boost 线程中运行:
boost::asio::io_service::work work( io_service );
boost::thread io_thread( boost::bind( &boost::asio::io_service::run, &io_service ) );
这在我创建套接字之前就被调用了。
Allegro 线程保存 Allegro 事件循环,没有什么特别之处。
我不想发布源代码,它非常庞大且复杂,我宁愿不尝试将其简化为基本案例。如果有必要,我可以。
我的套接字由一个类包装,在该类中创建和传递共享指针而不是常规指针(不确定这是否重要,我是 Boost 新手)。
感谢您在确定我无法回信给已连接的客户时提供的任何帮助。
尼尔
编辑:请求的代码段:
async_read/write(服务器)和回调函数:
void ServerConnection::async_read()
{
if( this->m_socket.is_open() == false )
{
std::cerr << "socket closed... (read)\n";
}
boost::asio::async_read( this->m_socket,
boost::asio::buffer( &m_input, sizeof( m_input ) ),
boost::bind( &ServerConnection::read_callback,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred ) );
}
void ServerConnection::async_write(const packet_list &packet, packet_id id, uint8_t rr)
{
this->m_output.data = packet;
this->m_output.head.opcode = id;
this->m_output.head.sender_id = 0;
this->m_output.head.response_required = rr;
if( this->m_socket.is_open() )
{
std::cerr << "socket closed... (write)\n";
}
boost::asio::async_write( this->m_socket,
boost::asio::buffer( &m_output, sizeof( m_output ) ),
boost::bind( &ServerConnection::write_callback,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred ) );
}
void ServerConnection::read_callback( const boost::system::error_code &error,
size_t /*read_count*/ )
{
if( error )
{
std::cerr << "Error reading: " << error.message() << std::endl;
return;
}
std::cerr << "Server reading data...\n";
if( this->m_event_dispatcher != nullptr )
{
ALLEGRO_EVENT event;
if( m_input.head.opcode == C_ACCEPT )
{
event.type = 513;
}
else
{
event.type = 512;
event.user.data1 = (intptr_t)&m_input;
}
al_emit_user_event( this->m_event_dispatcher, &event, nullptr );
}
else
{
std::cerr << "Why is this null....\n";
}
async_read();
}
void ServerConnection::write_callback(const boost::system::error_code &error,
size_t /*write_count*/ )
{
// After a write, we don't need to do anything except error checking.
if( error.value() )
{
std::cerr << "Error writing to client. " << error.message() << std::endl;
}
}