Boost异步服务器接受两次连接
Boost asynchronous server accepting connection twice
我正在做一个boost。Asio异步服务器。目前,服务器代码非常简单。它接受来自客户端的连接,并在接受连接时向客户端发送READY消息。客户端打印READY消息,然后允许用户在客户端控制台中写入任何消息。在客户机中输入的任何消息都将被发送到服务器。服务器打印消息和消息的字节大小,然后将相同的消息发送回客户端,附带一个额外的"…"OK"字符串。
现在我所经历的是在服务器接受连接并发送第一个"READY"消息后,它接受另一个连接并实例化新的连接类。但之后一切都如预期的那样。
所以,我不太确定为什么调用async_write(发送READY消息)后,它是重新启动另一个连接。然而,async_write(即handle_write)的回调函数正在被调用!
以下是我的服务器和客户端代码:main.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;
}
server.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();
}
Connection.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;
}
}
下面是我的客户端代码:
main.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;
}
Client.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();
}
}
Connection.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
。在io_service
中打印"创建连接...."answers"接受连接....",然后将accept
任务分配给CC_5。
从你的日志:
<>以前ioService运行创建连接实例…接受连接接受连接…//显示连接实际接受的时间给客户写信->…sigaling准备好了重新启动连接接受…创建连接实例…Accept connection//这是在将Accept任务分派给io_service之前打印的,所以实际上并没有接受连接(Handle_write) !相关文章:
- g++的分段错误(在NaN上使用to_string两次时)
- 蛇在C++不会连续转两次
- 检查一个数组是否包含在另一个数组中,以相反的顺序,至少两次
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 我应该如何去缓解两次出现的cin?
- Realloc 两次无法在 Visual Studio 上运行
- 使用 getline(cin, var) 两次在进行字符串比较时会产生错误 (==)
- 为什么映射插入和 map.find() 的单次迭代比插入和 map.find() 的两次单独迭代慢得多
- C++析构函数调用两次,堆栈分配的复合对象
- 为什么参数在构造 std::thread 时移动两次
- Qt插槽调用了两次
- 做 std::用相同的unique_ptr移动两次
- C++两次定义相同的函数会导致错误
- 为什么具有静态存储持续时间的同一内联变量在包含在 VS2017 编译的两个翻译单元中时会构造和销毁两次
- 对于优化级别为 0 的 std::vector,析构函数被调用两次
- 使用柯南打包时如何避免列出两次依赖?
- 为什么要执行两次位移((x >> 4)<< 4)?
- 在同一 unix 套接字连接中读取元素两次时出错
- Boost接受器每次接受两次输入连接,并生成两个线程
- Boost异步服务器接受两次连接