LINUX.ORG.RU

Сокеты, мультиплекирование и ветвистые протоколы

 ,


0

1

Очень нужна критика, ощущение велосипедостроения

***Далее, сокеты неблокируемые, мультиплексируем с пом epoll (тут непринципиально)

В процессе обмена данными между клиентом и сервером размеры пакетов данных заранее неизвестны (указываются в самих пакетах), пакеты приходится разберать «налету», дочитывать из сокета требуемое колво-данных и возвращаться к прежнему состоянию протокола.

Алгоритм протокола я разбила на этапы каждый из которых завершается тем что нужно вычитать/отправить еще данных из сокета и возврат к ожиданию события EPOLLIN/EPOLLOUT.

Схематично:

//Сам протокол
protocol_stage_t protocol(protocol_stage_t stage)
{

	if(stage_1)
	{
		//Какой-то алгоритм
		...
		//Если нужно получить/отправить данные, запоминаем состояние протокола и выходим
	}

	if(stage_2)
	{
		//Какой-то алгоритм
		...
		//Если нужно получить/отправить данные, запоминаем состояние протокола и выходим
	}
	
	....
}

//Ожидаем события
void event_loop()
{

	//Если пришли данные
	if(EPOLLIN)
	{
		...
		//Восстанавливаем состоние протокола для клиента и продолжаем выполнение
		...
		last_stage = protocol(saved_protocol_state);

		//Запоминаем где-то состояние протокола на котор остановились
		...
	}


	//Если ушли данные
	if(EPOLLOUT)
	{
		...
		//Восстанавливаем состоние протокола для клиента и продолжаем выполнение
		...
		last_stage = protocol(saved_protocol_state);

		//Запоминаем где-то состояние протокола на котор остановились
		...
	}
}
Очень нужна криптика такого подхода и желательно советы.
Возможно, такие подходы уже реализованы в каких-то библиотеках, но я о них не знаю.


Запоминаем где-то состояние протокола на котор остановились

Вот это место выглядит немного коряво. Почему не сделать в ОО стиле? На каждое соединение создавать экземпляр протокола и кормить его данными через его методы.

redixin ★★★★
()
Ответ на: комментарий от redixin

То же самое написать захотелось. Ну почти: незачем ретурнить стейты из ф-ций, просто передавать в аргументе для совершения каких-либо проверок и/или действий.

deep-purple ★★★★★
()
Ответ на: комментарий от anonymous

Работа с сетью не вызывает проблем и за рамками вопроса. Интересовало то как правильнее сделать сохранение состояния протокола.

nyka
() автор топика
Ответ на: комментарий от nyka

Состояние протокола хранится в сущности Protocol кеп
ps у вас проблемы с асинхронным программированием а не с состояниями протокола, изучите досконально первое, и по втором вопросов уже не будет

anonymous
()

Ты изобрела FSM (конечный автомат). Так, конечно, тоже можно, но это не слишком удобно.

intelfx ★★★★★
()
Ответ на: комментарий от anonymous

если под ассинхронным программированием имеете в виду работу с неблокируемыми сокетами с пом poll/epoll/select..., то с этим проблем нет никаких.
Состояние протокола храню в экземпялре класса протокола.
О конечных автоматах читала когда-то, но сейчас перечитаю более внимательно и подробно, за это отдельное спасибо

nyka
() автор топика
Ответ на: комментарий от nyka

В вашем случае Асинхронное это использование колбеков(функций)
и тогда вопросов вообще не появляется

anonymous
()
Ответ на: комментарий от anonymous

Имеете в виду запоминать адрес функции/метода с состоянием протокола и вызывать его при событии на сокете?

nyka
() автор топика
Ответ на: комментарий от nyka

Что то типа,только в концепции С++ это выглядит обыденно

anonymous
()

Это курсовая для колледжа? Сделай грамотно, возьми asio, на каждого клиента создаешь инстанс и поток, и там все хранишь. Или используй пул потоков, в бусте это все давно есть и прекрасно работает.

Bobby_
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.