0hquazEd
@0hquazEd

Почему не работает эхо сервер на boost::asio?

Здравствуйте! Недавно начал изучать boost::asio. Спустя некоторое время решил написать эхо сервер. Я смог это сделать, но понял, что на сервер может одновременно подключиться максимум один клиент. Решив убрать этот недостаток я столкнулся с проблемой: при попытке подключения двух клиентов один может отправлять и получать ответ от сервера, а второй нет. Вот код:

#include <boost/asio.hpp>
#include <iostream>
using namespace boost::asio;

void read_and_echo(ip::tcp::socket& sock)
{
	char buff[512];
	
	while (true)
	{
		sock.wait(ip::tcp::socket::wait_read);
		sock.read_some(buffer(buff));
		sock.write_some(buffer(buff));
	}
}

int main()
{
	io_service io;
	ip::tcp::endpoint ep(ip::tcp::v4(), 80);
	ip::tcp::acceptor ac(io, ep);
	std::vector<ip::tcp::socket> sockets;
	boost::thread_group th;

	while (true)
	{
		sockets.push_back(ac.accept());
		std::cout << "Accept client" << std::endl;
		th.create_thread([&sockets]()
			{
				read_and_echo(sockets.back());
			});
	}

	th.join_all();
	return 0;
}


После подключения второго клиента сервер второй раз выводит "Accept Client", после вылетает ошибка. Подскажите пожалуйста в чём ошибка, мне кажется в том, что два клиента подключаются по одному порту, но возможно проблема в другом.
  • Вопрос задан
  • 53 просмотра
Решения вопроса 1
xorknown
@xorknown
Будут проблемы - решайте
Проблема в выборе контейнера для сокетов. У вектора есть особенность, он распределяет все свои элементы последовательно в памяти и заранее выделяет под них память. В какой-то момент, при добавлении элемента, к примеру, он может изменить расположение этого последовательного участка в памяти. И получается что в своих потоках вы ссылаетесь на память в которой сокеты уже не находятся. std::vector::reserve лишь временное откладываение проблемы, которая покажет себя при большем кол-ве подключений.
Следует задуматься о замене вектора на std::list , к примеру, который не имеет данной особенности.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы