Comments 33
Вне хабра проскочил вопрос «передачи параметров времени и лимита пакетов. Где в OpenConnection указываются те самые 10 second?» Я думал, что это и так понятно, но, на всякий случай, поясню тут и пойду спать (:
<packet id><type id><first arg — time><second arg — count> — всё... А как кодировать? Можете предложить варианты!
Он поверх TCP работает? Если нет то как будут разруливаться потери\дублирование\изменение порядка пакетов?
Нет, сразу поверх IP. Читайте внимательней :)
Я так и предположил, но что тогда по второму вопросу?
Если открыли соединение на 2 пакета, потом клиент отправил 1 пакет а он пришел на сервер дважды - соединение закроется? А если пакет потерялся - соединение наоборот будет висеть до перезагрузки сервера? Что если потеряется EndPacket\OpenConnection\ExtendConnection - во всех случаях будут либо висящие соединения либо прием пакетов без соединения? Тогда я не понимаю чем это лучше UDP.
Потери сугубо приемлемы, что уже упоминалось, а дублирование и, возможно, сохранение порядка можно ввести в протокол. Думаю не будет ничего сложного, если добавить ещё пару простых счётчиков входящих и исходящих пакетов в подключении, а также добавлять текущее значение исходящего в отправляемые пакеты, чтобы на той стороне сверялись и отбрасывали дубли либо ожидали предыдущие. Предугадывая вопрос, безусловно необходимо подумать ещё и над сохранением целостности пакетов.
P.s. Извиняюсь, я вообще не заметил второй вопрос (вторые сутки на ногах ;).
потери DataPacket делают бесполезным открытие соединение на заданное число пакетов, так что можно выкинуть его из протокола и оставить только время.
Потери EndPacket делают бесполезным этот тип пакетов в принципе. Зачем нужен пакет который ничего не гарантирует?
Потери OpenConnection\ExtendConnection можно разрулить повторной отправкой по таймауту пока не пришел ответ.
Но это:
надо описать в протоколе (а не описывать только идеальную ситуация когда все пакеты доходят)
Раз в N минут будет возникать затык равный таймауту(*2 и больше) при плохом соединении, при этом доставка собственно данных все равно не гарантируется.
и нет, передача данных когда каждый DataPacket ждет подтверждения от сервера будет сильно менее эффективна чем в TCP, так что для надёжной передачи эффективнее использовать TCP.
кстати, а чему этот самый таймаут равен? захардкожен в реализации? определяется по результатам пинга?
Выкидывание заданного числа пакета не одобряю, это необходимо, чтобы не пытаться в последнюю секунду отправить последний пакет, если нужно.
EndPacket — сугубо информационный пакет, он уведомляет, что больше ты не будешь отправлять пакеты. Иначе говоря, от его потери ты не станешь отправлять пакеты ещё. Хотя, его потеря неприятна, так как получатель мог бы не ждать от тебя пакетов.
Таймаут, который активируется лишь при ненулевом счётчике пакетов, но вышедшим временем жизни подключения, как я уже говорил в другом комментарии, также указывается в OpenConnection, но не изменяется в ExtendConnection.
В остальном, я не совсем понял о чём речь. Действительно, описывать лишь идеальную ситуацию не есть гуд, но то же самостоятельное подтверждение получения пакетов не обязательно должно быть на каждый пакет, ведь важно слово «самостоятельное» (можешь и лучше их пачками подтверждать, если тебе оно нужно).
Про число пакетов. Я не вижу сценария в котором "ожидать н пакетов" принципиально отличалось бы от "ожидать 999 дней" (с учетом того что любой пакет может потеряться). Сможете привести такой сценарий?
С EndPacket аналогично - во всех сценариях которые я могу представить он просто служит небольшой оптимизации - "если дойдет тогда другая сторона закроет соединение чуть раньше, не дойдет - все равно закроет по таймауту"
Клиент отправил ExtendConnection, ответ от сервера не пришел (либо потерялся запрос, либо ответ на него).Что делать клиенту? Я предположил что надо выждать н миллисекунд (скажем пинг измеренный ранее*2) и заново отправить запрос. Ок, есть другой вариант - слать раз в минуту ExtendConnection(10 минут) вперемешку с данными и не дожидаясь ответа надеяться что хоть один из десяти пройдет. Если 9 не прошли можно даже начинать "паниковать" и слать их раз в минуту, тогда вопрос с таймаутом снимается (конечно ExtendConnection должен перетирать время а не прибавлять, иначе избыток будет набегать).
В текущем виде протокола не вижу преимуществ над UDP. Любые гарантии доставки/упорядоченности пользователь должен реализовывать сам поверх протокола и в JPP и в UDP, смысл от ограничения на число сообщений в JPP неясен учитывая сказанное выше, ну а таймаут из JPP легко реализовать и на UDP - сервер может рвать соединение если от клиента не пришло пакетов в течении н секунд, а клиент слать пустые пакеты раз в секунду даже если нет данных для обмена.
Дело осталось за малым - представить, что будет с дропом, джиттер, реордером, изменением источника в сессии, нужна ли абстракция, подобная порту, или хватит только абонента, ну и сущая мелочь, убедить хуавеи и циски, что им это надо/
Неплохо было бы почитать про особенности работы компьютерных сетей, чтобы такую наивную дичь не постить.
В текущем виде (особенно с подсчетом пакетов) совершенно непонятно, как протокол должен работать с учетом переотправки потерянных пакетов.
Также, при таком дизайне можно заддосить сервер, открыв множество соединений на длительное время.
Не понимаю, что вам непонятно в переотправке потерянных пакетов: по-умолчанию нет никаких механизмов на этот случай, но если вам необходимо, то можно элементарно присылать DataPacket в ответ, разве нет?
Что же насчёт ддоса, то он возможен и в TCP, и в UDP, так как решается не на этом уровне и достаточно просто: ты можешь отбраковывать неугодные тебе одиночные пакеты (в том числе, и на открытие соединения). Даже по причине подозрительной активности у отправителя...
Кстати, а что наивного-то? :)
Поэтому и стоит сначала ознакомиться со спецификацией TCP и понять, какие проблемы этот протокол решает, прежде чем выдумывать свой протокол, который просто не будет работать в реальных условиях.
В этом и заключается Ваша наивность - эффект Даннинга - Крюгера.
Как уже говорил ниже, это лишь сырая и обобщённая идея, которая и нужна для этого — чтобы повысить компетенцию, начать дискуссию и, возможно, получить нечто стоящее. С конкретным эффектом же вы промазали, я вполне себе осознаю свою некомпетентность и довольно поверхностное знание в данной теме... Что скажете? :)
Не нашел в статье ответа на вопросы:
в каком сценарии использования наличие заранее заданных ограничений по времени/числу пакетов будет полезно?
как планируется выбирать эти ограничения с учётом нестабильной работы сети?
Я тоже не понял главным образом, зачем это нужно. Поддержка таблицы соединений стоит денег, зачем это, если цель – просто передавать пакеты?
Насчёт таблицы соединений — осмелюсь заметить, что даже для UDP она поддерживается, просто самими провайдерами и в, так сказать, корыстных целях :)
Соглашусь, что этот протокол залез ещё и на уровне выше (уровень сессий)... но в данном случае — это достаточно обосновано и просто, идя как лёгкий довесок. Нет/да?
Всё достаточно элементарно по вашим вопросам:
В любом. Это как сервисные пакеты для проверки соединения в том же TCP, но ты сразу и чётко знаешь сколько их будет или как долго будет соединение. Можете воспринимать это как контракты, например.
Методом научного тыка?.. Не уверен, честно говоря, всё-таки представлял это как: открыл соединение на N минут (предположим, N=5), через N-1 расширил соединение ещё на N, если необходимо, и так на протяжении всей работы. Можно даже производить простенькие вычисления, чтобы не накапливался остаток.
Я ответил?
Не вижу сходства. Сервисные пакеты отправляются строго по мере надобности.
Ключевой момент именно в этом: на транспортном уровне мы не знаем, что, сколько и как долго собирается передавать приложение. В лучшем случае эта информация будет доступна на уровне протокола самого приложения, подобно Keep-Alive в HTTP. И даже там она передаётся "по факту", без попыток угадать заранее.
А угадать будет непросто. Сеть подтормаживает, и наша прикидка о длительности сессии оказалась некорректной. Соединение разорвётся, несмотря на работоспособность сети? Пользователю это не понравится.
Далее, а что подразумевается под пакетом? IP пакет? Тогда сразу встаёт вопрос: как быть с фрагментацией пакетов? Фрагмент считается за пакет? Как быть с повторной отправкой?
И это все при условии что приложение вообще знает, сколько точно данных и как долго оно будет отправлять. Я вообще навскидку затрудняюсь назвать такой сценарий, кроме разве что передачи файла заранее известного размера. Так это всего один сценарий, из-за чего огород-то городить?
Конечный итог будет простой: приложение будет брать параметры с бааальшим запасом. И тогда ваш протокол мало чем будет отличаться от того же TCP.
Как будто бы надёжности в этом протоколе нет, да и подделать пакеты третьей стороной в сессии не представляется сложным. Будущее конечно за оптимизацией, но к сожалению не в мире сетевых технологий)
Действительно, насчёт механизмов против подделки не было упомянуто, так как они отсутствуют, но их достаточно просто реализовать (как пример: подписью и её проверкой поверх протокола). Возможно, можно сразу учесть и обозначить этот функционал в протоколе... Но я не совсем уверен, стоит ли.
А вот оптимизации нужны и будут даже в сетевых технологиях, вопрос в том какие, как и когда. Разве нет? ;)
Забыли упомянуть какой из фатальных недостатков имеющихся протоколов ваш решает.
Так сказать, сравнительный анализ провести.
Фатальных? Скорее всего, никакой. Увы, но это просто нечто вроде оптимизации (приводя аналогию, замена неумелого бумажного самолётика на сделанный более аккуратно и ровно ;)
Я так понимаю старый мем вы не узнали :)
Я как раз это и имел ввиду - в чем заключается оптимизация? Что в имеющихся протоколах на ваш взгляд сделано более неумело? Вот этого анализа не хватает.
Почему то мне кажется что это какое то подражание quick.
Статья представляет из себя большой мысленный эксперимент. Надо бы всё-таки чё-нибудь написать. Причём на Си я бы не советовал. Возьмите библиотеку scapy на Питоне, опишите её средствами структуру пакетов, с её помощью сбилдите несколько примеров сессий, сохраните в PCAP. Потом можно будет добавить поддержку в Wireshark через Lua-скрипт, чтобы можно было посмотреть на это в удобной форме.
К моменту, как всё это сделаете, возможно, у вас появится понимание проблем протокола и, возможно, идеи, как это чинить.
Очень нравится читать подобные неопытные наброски, т.к. я также неопытен и интересно как разбирают в комментариях. Благодарю!
и где теоретическое моделирование? статистические оценки на реальных данных несущих сетей? примеры применения полезного где?
Это сырая идея, имейте совесть! В самом деле, у меня нет возможности и желания проводить подобное «глубокое расследование», да и в этом нет никакой необходимости. ;)
P.s. Полезное применение такое же как у остальных протоколов того же уровня — везде где они используются. А если вы про «почему он лучше старого», то я уже упоминал, что лучше простотой, локаничностью и конкретизацией ожиданий по пакетам.
Как человек, поработавший с достаточным количеством самых разных сетевых протоколов, вынужден согласиться со всей критикой выше.
На мой взгляд, проблемных момента в вашем предложении два.
Во-первых, так дела не делаются =). Недостаточно просто придумать пару заголовков и мол ну что вы пристали, это пока только идея, сейчас подумаю как это вообще может работать и зачем это может быть кому-нибудь нужно.
Протокол (и особенно базовый транспортный) должен не просто решать какую-то абстрактную задачу в вакууме, типа мы добавили возможность указать количество пакетов чтобы знать сколько нужно ждать пакетов, авось кому-нибудь пригодится. Он должен решать конкретную, практическую проблему, которую неэффективно и/или приходится постоянно раз за разом решать уровнем выше или ниже.
Во-вторых, почему собственно транспортный уровень? С самого начала речь идет о времени сессии и о количестве сообщений, большая часть отмеченных в комментариях проблем из-за недостаточного на транспортном уровне контекста, решать эти проблемы предлагается уровнем выше. По-моему очевидно, что вся затея на самом деле должна быть как минимум на сеансовом, если не вообще на прикладном уровне. Вот там -- пожалуйста, таймауты и предполагаемое количество сообщений могут быть полезны. Или нет.
Новый транспортный протокол? JPP — Just Packet Protocol