我正在开发一个 boost.asio 异步服务器。 目前服务器代码非常简单。它接受来自客户端的连接,并在接受连接时向客户端发送 READY 消息。客户端打印 READY 消息,然后允许用户在客户端控制台中写入任何消息。客户端输入的任何消息都将发送到服务器。服务器打印消息和消息的字节大小,然后将相同的消息发送回带有额外“... OK”字符串的客户端。
现在我遇到的是在服务器接受连接并发送第一个“READY”消息后,它接受另一个连接并实例化新的连接类。但之后一切都按预期进行。
所以,我不太确定为什么在调用 async_write(发送 READY 消息)后它重新启动另一个连接。但是,正在调用 async_write(即 handle_write)的回调函数!
这是我的服务器和客户端代码:
主要.cpp
#include "casperServer.h"
#include <iostream>
int main(int argc, char* argv[])
{
try
{
casperServer s("0.0.0.0", "7000");
s.run();
}
catch (std::exception& e)
{
std::cerr << "exception: " << e.what() << "\n";
}
return 0;
}
服务器.cpp
#include "casperServer.h"
#include <boost/bind.hpp>
casperServer::casperServer(const std::string& address, const std::string& port)
:_acceptor(_ioService),
_connection()
{
boost::asio::ip::tcp::resolver resolver(_ioService);
boost::asio::ip::tcp::resolver::query query(address, port);
boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
_acceptor.open(endpoint.protocol());
_acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
_acceptor.bind(endpoint);
_acceptor.listen();
//Starting the acceptor
//start_accept();
}
void casperServer::run()
{
std::cout<< "Running ioService" <<std::endl;
start_accept();
_ioService.run();
}
void casperServer::start_accept()
{
std::cout<< "Creating connection instance ..." <<std::endl;
_connection.reset(new casperConnection(_ioService));
std::cout<< "Accept connection" <<std::endl;
_acceptor.async_accept( _connection->socket(),
boost::bind( &casperServer::handle_accept, this,
boost::asio::placeholders::error));
}
void casperServer::handle_accept(const boost::system::error_code& e)
{
std::cout<< "Connection accepted ..." <<std::endl;
if (!e)
{
_connection->start();
}
std::cout<< "Restarting connection accept ..." <<std::endl;
start_accept();
}
连接.cpp
#include <iostream>
#include "casperConnection.h"
#include <boost/bind.hpp>
casperConnection::casperConnection(boost::asio::io_service& io_service)
:_socket(io_service)
{
}
boost::asio::ip::tcp::socket& casperConnection::socket()
{
return _socket;
}
void casperConnection::start()
{
std::cout<< "Writing to client ->" <<std::endl;
std::cout << "...sigaling READY"<< std::endl;
boost::asio::async_write( _socket, boost::asio::buffer("Server READY ..."),
boost::bind( &casperConnection::handle_write, shared_from_this(),
boost::asio::placeholders::error));
}
void casperConnection::handle_read(const boost::system::error_code& e, std::size_t bytes_transferred)
{
std::cout<<"[Handle_read]!"<<std::endl;
_inputBuffer.clear();
std::copy(_readBuffer.begin(), _readBuffer.begin()+bytes_transferred, std::back_inserter(_inputBuffer));
std::cout << "Byte recieved: "<<bytes_transferred<< std::endl;
std::cout << "Data: "<<_inputBuffer<< std::endl;
_inputBuffer= _inputBuffer + " ...OK";
boost::asio::async_write( _socket, boost::asio::buffer(_inputBuffer, _inputBuffer.length()),
boost::bind( &casperConnection::handle_write, shared_from_this(),
boost::asio::placeholders::error));
}
void casperConnection::handle_write(const boost::system::error_code& e)
{
std::cout<<"[Handle_write]!"<<std::endl;
_socket.async_read_some( boost::asio::buffer(_readBuffer),
boost::bind( &casperConnection::handle_read, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
if(_readBuffer.empty())
{
std::cout<<"Buffer empty!"<<std::endl;
}
}
这是我的客户端代码:
主要.cpp
#include <iostream>
#include <boost/asio.hpp>
#include "Client.h"
using boost::asio::ip::tcp;
int main(int argc, char* argv[])
{
Client _client("127.0.0.1", "7000");
_client.Connect();
return 0;
}
客户端.cpp
#include <iostream>
Client::Client(const std::string& address, const std::string& port)
{
std::cout<<"Client CTOR "<<std::endl;
boost::asio::ip::tcp::resolver resolver(_ioService);
boost::asio::ip::tcp::resolver::query query(address, port);
boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
initConnection(endpoint);
}
Client::~Client()
{
}
void Client::initConnection(boost::asio::ip::tcp::endpoint ep)
{
std::cout<<"Initializing connection "<<std::endl;
_connection.reset(new clientConnection(_ioService));
_connection->socket().async_connect(ep, boost::bind(&Client::on_connect, this, boost::asio::placeholders::error));
}
void Client::Connect()
{
std::cout<<"Calling ioService run."<<std::endl;
_ioService.run();
}
void Client::on_connect(const boost::system::error_code& e)
{
std::cout << "On connection accept ..." << std::endl;
if (!e)
{
_connection->start();
}
}
连接.cpp
#include "clientConnection.h"
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <iostream>
clientConnection::clientConnection(boost::asio::io_service& io_service)
:_socket(io_service)
{
std::cout<<"Client Connection CTOR"<<std::endl;
}
clientConnection::~clientConnection()
{
}
boost::asio::ip::tcp::socket& clientConnection::socket()
{
return _socket;
}
void clientConnection::start()
{
_socket.async_read_some( boost::asio::buffer(_buffer),
boost::bind(&clientConnection::on_read, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void clientConnection::on_read(const boost::system::error_code& e, std::size_t bytes_transferred)
{
std::cout<<"Server msg: "<<_buffer.c_array()<<std::endl;
std::cout<<bytes_transferred<< " bytes read."<<std::endl;
_buffer.assign(0);
std::cout<<">>";
std::getline(std::cin, input);
std::cout<<"Sending to server: "<<input<<std::endl;
boost::asio::async_write( _socket, boost::asio::buffer(input, input.length()),
boost::bind( &clientConnection::on_write, shared_from_this(),
boost::asio::placeholders::error));
}
void clientConnection::on_write(const boost::system::error_code& e)
{
_socket.async_read_some( boost::asio::buffer(_buffer),
boost::bind(&clientConnection::on_read, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
这是我在控制台中的输出:
Running ioService
Creating connection instance ...
Accept connection
Connection accepted ...
Writing to client ->
...sigaling READY
Restarting connection accept ...
Creating connection instance ...
Accept connection
[Handle_write]!
你可以看到,在写完 READY 命令后,服务器正在初始化另一个连接,我不确定为什么。
有什么建议吗?
最佳答案
据我所知,接受另一个连接没有问题。这只是您添加打印件的方式。
void casperServer::start_accept()
{
std::cout<< "Creating connection instance ..." <<std::endl;
_connection.reset(new casperConnection(_ioService));
std::cout<< "Accept connection" <<std::endl;
_acceptor.async_accept( _connection->socket(),
boost::bind( &casperServer::handle_accept, this,
boost::asio::placeholders::error));
}
void casperServer::handle_accept(const boost::system::error_code& e)
{
std::cout<< "Connection accepted ..." <<std::endl;
if (!e)
{
_connection->start();
}
std::cout<< "Restarting connection accept ..." <<std::endl;
start_accept();
}
根据上面的代码,在接受第一个连接后,将调用handle_accept
,您可以在其中启动连接实例,然后再次调用start_accept
。在 start_accept
中打印“Creating connection ....”和“Accept connection....”,然后将 accept
任务分派(dispatch)给 io_service
.
来自您的日志:
Running ioService Creating connection instance ... Accept connection Connection accepted ... // This shows when connection was actually accepted Writing to client -> ...sigaling READY Restarting connection accept ... Creating connection instance ... Accept connection // This is a print just before dispatching the accept task to io_service, so not actually accepting a connection [Handle_write]!
关于c++ - boost 异步服务器两次接受连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39030638/