저는 오랜 기간 동안 다른 서버와 통신하기 위해 몇 가지 영구적 인 기능을 사용할 수 있어야하는 프로젝트를 진행하고 있습니다. 이 서버는 상당히 높은 처리량을 갖습니다. 영구 연결을 올바르게 설정하는 방법을 찾는 데 문제가 있습니다. 이 작업을 수행하는 가장 좋은 방법은 영구 연결 클래스를 만드는 것입니다. 이상적으로는 한 번 서버에 연결하고 async_writes를 수행하면 정보가 나에게 들어옵니다. 그리고 그것이 나에게 돌아올 때 정보를 읽으십시오. 나는 내가 올바르게 나의 클래스를 형성하고있다라고 생각하지 않는다. 여기영구적 인 ASIO 연결
내가 지금 구축 한 것입니다 :
persistent_connection::persistent_connection(std::string ip, std::string port):
io_service_(), socket_(io_service_), strand_(io_service_), is_setup_(false), outbox_()
{
boost::asio::ip::tcp::resolver resolver(io_service_);
boost::asio::ip::tcp::resolver::query query(ip,port);
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
boost::asio::ip::tcp::endpoint endpoint = *iterator;
socket_.async_connect(endpoint, boost::bind(&persistent_connection::handler_connect, this, boost::asio::placeholders::error, iterator));
io_service_.poll();
}
void persistent_connection::handler_connect(const boost::system::error_code &ec, boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
{
if(ec)
{
std::cout << "Couldn't connect" << ec << std::endl;
return;
}
else
{
boost::asio::socket_base::keep_alive option(true);
socket_.set_option(option);
boost::asio::async_read_until(socket_, buf_ ,"\r\n\r\n", boost::bind(&persistent_connection::handle_read_headers, this, boost::asio::placeholders::error));
}
}
void persistent_connection::write(const std::string &message)
{
write_impl(message);
//strand_.post(boost::bind(&persistent_connection::write_impl, this, message));
}
void persistent_connection::write_impl(const std::string &message)
{
outbox_.push_back(message);
if(outbox_.size() > 1)
{
return;
}
this->write_to_socket();
}
void persistent_connection::write_to_socket()
{
std::string message = "GET /"+ outbox_[0] +" HTTP/1.0\r\n";
message += "Host: 10.1.10.120\r\n";
message += "Accept: */*\r\n";
boost::asio::async_write(socket_, boost::asio::buffer(message.c_str(), message.size()), strand_.wrap(
boost::bind(&persistent_connection::handle_write, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)));
}
void persistent_connection::handle_write(const boost::system::error_code& ec, std::size_t bytes_transfered)
{
outbox_.pop_front();
if(ec)
{
std::cout << "Send error" << boost::system::system_error(ec).what() << std::endl;
}
if(!outbox_.empty())
{
this->write_to_socket();
}
boost::asio::async_read_until(socket_, buf_ ,"\r\n\r\n",boost::bind(&persistent_connection::handle_read_headers, this, boost::asio::placeholders::error));
}
이 잘 보낼 것 같다에서 내가 보내드립니다 첫 번째 메시지는 서버가 그것을 가져오고 유효한 응답으로 응답합니다. 불행히도 두 가지 문제가 나타납니다.
1) async_write 명령을 실행 한 후 내 handle_write가 호출되지 않습니다. 이유가 없습니다. 2)이 프로그램은 응답을 읽지 않습니다. asyn_read_until은 해당 함수가 발생할 때까지 호출되지 않기 때문에 # 1과 관련이 있다고 생각합니다. 3) 누군가 내가 내 strand_.post 콜을 주석 처리 한 이유가 무엇인지 알 수 있는지 궁금합니다.
나는 대부분이 내 io_service를 어떻게 사용해야하는지에 대한 지식이 부족하기 때문에 내 생각에 누군가가 내게 크게 감사할만한 포인터를 줄 수 있다면 말이다. 추가 정보가 필요하면 좀 더 제공하게되어 기쁩니다.
int main()
{
persistent_connection p("10.1.10.220", "80");
p.write("100");
p.write("200");
barrier b(1,30000); //Timed mutex, waits for 300 seconds.
b.wait();
}
및
void persistent_connection::handle_read_headers(const boost::system::error_code &ec)
{
std::istream is(&buf_);
std::string read_stuff;
std::getline(is,read_stuff);
std::cout << read_stuff << std::endl;
}
게시 한 코드에서 결코 write를 호출하지 않으며 읽기 핸들러가 없습니다. 그걸 제공 할 수 있니? – Loghorn
당신은'io_service'를 다중 스레드에서'run'을 호출하고 있습니까? 왜냐하면 그렇지 않다면 가닥이 필요하지 않기 때문입니다. 여러 스레드에서 호출하는 경우 * 동일한 스레드에 대해 모든 처리기를 래핑해야합니다. 그렇지 않으면 동일한 연결의 처리기가 동시에 실행될 수 있습니다. –
여러 스레드에서 쓰기를 호출합니다. 이 프로그램의 구조는 asio 웹 서버입니다. 각 요청에 대해 정보를 구문 분석 한 다음 구문 분석 된 정보를 영구 연결로 보냅니다. 그래서 각각의 연결은 write를 호출 할 것이고, 각각의 연결은 다른 쓰레드에있게 될 것입니다. – Eumcoz