Здравствуйте, v_andal, Вы писали:
_>Здравствуйте, netch80, Вы писали:
N>>А ещё я бы в тот же FAQ запихнул жёсткое "нужен собственный протокол — начинайте с SCTP и переходите на TCP только если первый недоступен".
_>Я бы этого точно этого не рекомендовал. Это противоречит KISS. TCP элементарен в использовании.
Постоянная необходимость держать собственный буфер, двигаться по нему с байтовыми позициями (а не целыми сообщениями) и собирать сообщения из байтов это никак не "элементарен в использовании", это изуверски сложно для новичков и неудобно даже для профессионалов.
_> Чтобы использовать расширенные возможности SCTP нужно разобраться с кучей доков,
Вы обманно подменили тезис дискуссии. Я не говорил про "расширенные возможности SCTP".
_> а в конце выясняется, что всех удовольствий — это возможность указать системе границы пакетов которые нужно отдавать пользователю. Вся остальная дребедень типа мультихома нужна только в специфических случаях и требует ещё кучу сложностей.
Не используйте, и она ничего не будет требовать. Зато границы сообщений — архиполезно.
_>В данном же случае, HTTP вообще не предполагает пакетных границ. Он уже заточен под использование TCP.
Ещё один не прочитавший явно написанное русским по фоновому про "собственный протокол".
_> Так что ожидание данных в рамках одного пакета — это классические грабли всех начинающих сетевых программистов. Нужно изначально проектировать решение как систему обработчиков событий.
Здравствуйте, netch80, Вы писали:
N>Здравствуйте, v_andal, Вы писали:
_>>Здравствуйте, netch80, Вы писали:
N>>>А ещё я бы в тот же FAQ запихнул жёсткое "нужен собственный протокол — начинайте с SCTP и переходите на TCP только если первый недоступен".
_>>Я бы этого точно этого не рекомендовал. Это противоречит KISS. TCP элементарен в использовании.
N>Постоянная необходимость держать собственный буфер, двигаться по нему с байтовыми позициями (а не целыми сообщениями) и собирать сообщения из байтов это
никак не "элементарен в использовании", это изуверски сложно для новичков и неудобно даже для профессионалов.
Простите, однако SCTP также не гарантирует сохранение границ пакетов. Смотрите Секцию 10 в https://www.rfc-editor.org/rfc/rfc2960.txt протокол может делать частичную доставку пакета. Так что в любом случае приходится вести учёт полученных байтов и держать буфер. То бишь в простейшем варианте использования разницы никакой, только документация сложнее и системные вызовы более заморочные. На практике, границы пакета ничего не дают для программы.
_>> а в конце выясняется, что всех удовольствий — это возможность указать системе границы пакетов которые нужно отдавать пользователю. Вся остальная дребедень типа мультихома нужна только в специфических случаях и требует ещё кучу сложностей.
N>Не используйте, и она ничего не будет требовать. Зато границы сообщений — архиполезно.
Смотри выше. Эти границы — фикция.
_>>В данном же случае, HTTP вообще не предполагает пакетных границ. Он уже заточен под использование TCP.
N>Ещё один не прочитавший явно написанное русским по фоновому про "собственный протокол".
Извините, я просто перешёл от "собственный протокол" к "данному случаю HTTP протокола". Ничего больше.
_>> Так что ожидание данных в рамках одного пакета — это классические грабли всех начинающих сетевых программистов. Нужно изначально проектировать решение как систему обработчиков событий.
N>Не "нужно", а "неизбежно при использовании TCP".
То же самое относится к SCTP. Нужно обязательно проверять получил ли ты полный пакет, или же только partial delivery.
Здравствуйте, v_andal, Вы писали:
_>Простите, однако SCTP также не гарантирует сохранение границ пакетов. Смотрите Секцию 10 в https://www.rfc-editor.org/rfc/rfc2960.txt протокол может делать частичную доставку пакета. Так что в любом случае приходится вести учёт полученных байтов и держать буфер. То бишь в простейшем варианте использования разницы никакой, только документация сложнее и системные вызовы более заморочные. На практике, границы пакета ничего не дают для программы.
Боже мой! Нужно проверить один флажок и заполнять если он в 1 то ли дело TCP!
Здравствуйте, v_andal, Вы писали:
_>Простите, однако SCTP также не гарантирует сохранение границ пакетов. Смотрите Секцию 10 в https://www.rfc-editor.org/rfc/rfc2960.txt протокол может делать частичную доставку пакета.
Это не есть несохранение границ. Границы при этом сохраняются без проблем: с помощью того же флага можно выяснять, идёт речь о новом сообщении или нет. Не происходит такого, что одним receive получаются фрагменты нескольких сообщений, и в этом главное и принципиальное преимущество по сравнению с TCP.
Более того, в практически встречаемых API, чтобы производилась такая частичная доставка, надо постараться. Вот, например, из мана sctp_recvmsg на FreeBSD:
The length of the message msg to be received is bounded by len. If the message is too long to fit in the users receive buffer, then the flags argument will not have the MSG_EOF flag applied. If the message is a complete message then the flags argument will have MSG_EOF set.
Большинство остальных реализаций следуют тому же принципу. В случае более простого вызова (recvmsg, recv, read) такой проблемы аналогично нет, если размер буфера заведомо достаточен для полного сообщения, но там может не оказаться диагностики дробления.
_> Так что в любом случае приходится вести учёт полученных байтов и держать буфер.
Нет, не приходится. Передавайте приёмный буфер нужного размера и забудьте о проблеме.
_> На практике, границы пакета ничего не дают для программы.
Вы о чём? Если о результатах своего прочтения, то они неадекватны текущей реальности. Если о практике с поправкой, то они чудовищно удобны.
N>>Не используйте, и она ничего не будет требовать. Зато границы сообщений — архиполезно. _>Смотри выше. Эти границы — фикция.
Повторяю: Вы совершенно некорректно прочли RFC. Даже с учётом возможной частичной доставки таким образом, границы — ни капельки не фикция, потому что в результат одного RECEIVE не попадут части двух разных сообщений, а признак границы сообщения всё равно тривиально восстанавливается (!partial => последняя часть сообщения).
N>>Не "нужно", а "неизбежно при использовании TCP". _>То же самое относится к SCTP. Нужно обязательно проверять получил ли ты полный пакет, или же только partial delivery.
Нет, не нужно, если буфер достаточен для приёма полного сообщения.
Здравствуйте, netch80, Вы писали:
N>>>Не "нужно", а "неизбежно при использовании TCP". _>>То же самое относится к SCTP. Нужно обязательно проверять получил ли ты полный пакет, или же только partial delivery.
N>Нет, не нужно, если буфер достаточен для приёма полного сообщения.
Но с буфером-то всё равно придётся возится. Придётся "помнить", что этот буфер содержит только часть сообщения. Кроме того, редко когда приходящие пакеты имеют одинаковую длину, а значит ты не знаешь какой длины буфер тебе нужен.
Всё, что я пытаюсь сказать, знание границ пакета ничего не упрощает. Работа с буфером никуда не исчезает и проще она не становится. Алгоритм остаётся тем же: выделил некий буфер, прочёл, проверил сколько реально нужно памяти, если надо увеличил буфер и снова читаешь. Если протокол подразумевает пакеты, то в SCTP тебе сообщают длину пакета, в TCP нужно самому взять первые 2 или 4 байта, чтобы узнать длину пакета. Вся разница в 2-х строчках кода. И ради этого трахаться с более сложной документацией для SCTP?
Я уже 15 лет работаю с обоими этими протоколами, и не устаю восхищаться разработчиками TCP. С этим протоколом я будучи полным нубом разобрался за пару дней. На штудирование SCTP ушла неделя, и я до сих пор регулярно заглядываю в доки проверяя, все ли детали я учёл.
Да и давайте уж смотреть на вещи реально. Если считать работу с буфером "архисложной", то тогда что говорить о работе с таймерами, об обработке сетевых ошибок, да и об обработке полученных данных? Работа с буфером укладывается в 150-200 строк С-кода, на фоне остального кода это тривиальный мизер. Я еще в первые месяцы написания сетевых программ сляпал себе крошечный модуль-администратор для буфера и с тех пор не думаю об этом. Этот модуль я пользую и для TCP и для SCTP.
Здравствуйте, v_andal, Вы писали:
N>>>>Не "нужно", а "неизбежно при использовании TCP". _>>>То же самое относится к SCTP. Нужно обязательно проверять получил ли ты полный пакет, или же только partial delivery. N>>Нет, не нужно, если буфер достаточен для приёма полного сообщения. _>Но с буфером-то всё равно придётся возится. Придётся "помнить", что этот буфер содержит только часть сообщения. Кроме того, редко когда приходящие пакеты имеют одинаковую длину, а значит ты не знаешь какой длины буфер тебе нужен.
Во многих случаях я это гарантированно знаю за счёт ограничений протокола. И всё равно важнее то, что каждый возврат из recv*() для SCTP содержит части не более одного сообщения.
_>Всё, что я пытаюсь сказать, знание границ пакета ничего не упрощает. Работа с буфером никуда не исчезает и проще она не становится.
Она реально становится проще. Даже в случае непредсказуемого размера сообщений, и особенно — если буфера достаточно.
_> Алгоритм остаётся тем же: выделил некий буфер, прочёл, проверил сколько реально нужно памяти, если надо увеличил буфер и снова читаешь. Если протокол подразумевает пакеты, то в SCTP тебе сообщают длину пакета, в TCP нужно самому взять первые 2 или 4 байта, чтобы узнать длину пакета. Вся разница в 2-х строчках кода. И ради этого трахаться с более сложной документацией для SCTP?
Там не из-за чего "трахаться", для данного уровня всё элементарно.
_>Я уже 15 лет работаю с обоими этими протоколами, и не устаю восхищаться разработчиками TCP. С этим протоколом я будучи полным нубом разобрался за пару дней. На штудирование SCTP ушла неделя, и я до сих пор регулярно заглядываю в доки проверяя, все ли детали я учёл.
Когда используете более сложные особенности — да. Когда используете его на уровне TCP с границами сообщений — не о чем заглядывать.
Восхищаться разработчиками TCP можно — до определённого предела, пока не понимаешь, что мириады индусов всех национальностей не умеют и не будут уметь работать с ним.
_>Да и давайте уж смотреть на вещи реально. Если считать работу с буфером "архисложной", то тогда что говорить о работе с таймерами, об обработке сетевых ошибок, да и об обработке полученных данных? Работа с буфером укладывается в 150-200 строк С-кода, на фоне остального кода это тривиальный мизер.
Это тривиальный мизер, когда вы знаете об этом. А когда кодер об этом не знает — он просто игнорирует проблему.
Я видел много протоколов, где в принципе не предусмотрены границы сообщений, и надо или гарантировать не более одного сообщения за итерацию с каждой стороны, или применять тяжёлые формы неестественного интеллекта для поиска границ.
Например, я сейчас работаю с FIX. Гарантия правильного опознания границ для всех случаев — может быть только при грамматическом разборе потока при условии словаря всех атрибутов. Реально 90% применяющих плевали на это и детектируют самым тупым образом.
_> Я еще в первые месяцы написания сетевых программ сляпал себе крошечный модуль-администратор для буфера и с тех пор не думаю об этом. Этот модуль я пользую и для TCP и для SCTP.
N>Во многих случаях я это гарантированно знаю за счёт ограничений протокола. И всё равно важнее то, что каждый возврат из recv*() для SCTP содержит части не более одного сообщения.
И чем же это важно? Это однозначно плохо для пропускной способности протокола. Каждый системный вызов дорого обходится. Я так наоборот делаю всё возможное, чтобы за один системный вызов вытащить как можно больше данных. Просто с меня требуют максимальную пропускную способность. Опять же, с точки зрения обработки данных абсолютно без разницы сколько у тебя пакетов в буфере. Алгоритм остаётся прежним "пакет в начале буфера, обработай, удали обработанное, смести начало буфера, у тебя опять пакет в начале буфера".
_>>Всё, что я пытаюсь сказать, знание границ пакета ничего не упрощает. Работа с буфером никуда не исчезает и проще она не становится.
N>Она реально становится проще. Даже в случае непредсказуемого размера сообщений, и особенно — если буфера достаточно.
Ну да, если ты веришь, что буфера достаточно, то значит ты создаёшь потенциальную дыру. Писать всё равно приходится исходя из положения, что буфера недостаточно. Из практического опыта, если не использовать спец-свойства SCTP типа мультихома, то код для TCP мало отличается от кода для SCTP.
_>> Алгоритм остаётся тем же: выделил некий буфер, прочёл, проверил сколько реально нужно памяти, если надо увеличил буфер и снова читаешь. Если протокол подразумевает пакеты, то в SCTP тебе сообщают длину пакета, в TCP нужно самому взять первые 2 или 4 байта, чтобы узнать длину пакета. Вся разница в 2-х строчках кода. И ради этого трахаться с более сложной документацией для SCTP?
N>Там не из-за чего "трахаться", для данного уровня всё элементарно.
Для начала нужно разобраться со всем многообразием уровней предлагаемых SCTP и понять, какой же уровень "данный". Собственно ничего другого я не имею в виду. Разобравшись с доками действительно выясняется, что SCTP можно использовать точно также как TCP
N>Восхищаться разработчиками TCP можно — до определённого предела, пока не понимаешь, что мириады индусов всех национальностей не умеют и не будут уметь работать с ним.
Ну так с уверенностью можно сказать, что эти самые мириады не будут уметь работать и с SCTP. С другой стороны, имеется куча народа умеющих работать с TCP, количество же людей умеющих пользовать SCTP гораздо скромнее. Да и сам протокол используется только в узкоспециализированных местах. Не идёт он в массы
N>Это тривиальный мизер, когда вы знаете об этом. А когда кодер об этом не знает — он просто игнорирует проблему.
Эти слова не привязаны к TCP протоколу. Можно сказать, что знания о partial read в SCTP этот тривиальный мизер, который кодер просто игнорирует, надеясь, что его буфер всегда достаточного размера и он всегда получит полную запись. А в результате все получают очередной говнокод.
N>Я видел много протоколов, где в принципе не предусмотрены границы сообщений, и надо или гарантировать не более одного сообщения за итерацию с каждой стороны, или применять тяжёлые формы неестественного интеллекта для поиска границ.
А какое это имеет отношение к дискуссии о преимуществах SCTP по отношению к TCP? Дурацкий протокол можно придумать вне зависимости от используемого транспорта. С другой стороны, очень часто требования предъявляемые к протоколу не дают возможности задавать чёткие границы для пакетов. Тот же HTTP протокол используется в ситуациях, когда ответ может генериться кусками и куски могут быть слишком большими для буферизации. Так что чётких границ тут не задашь. Опять же, наличие чётких границ не даёт гарантии, что протокол хороший. SMPP протокол даёт чёткие границы пакетов (хоть и работает над TCP), но в пределах этих границ делает много глупостей, делающих работу с этим протоколом заморочной.
_>> Я еще в первые месяцы написания сетевых программ сляпал себе крошечный модуль-администратор для буфера и с тех пор не думаю об этом. Этот модуль я пользую и для TCP и для SCTP.
N>Одинаковым кодом? Звучит крайне подозрительно.
Хм. Под "администрированием буфера" я понимаю "выделить место для стольких то байт", "отметить такое-то количество байт как данные", "убрать такое-то количество данных в начале", "убрать такое-то количество данных с конца", "дать доступ к данным в начале буфера". Эти операции остаются одинаковыми для обоих протоколов.
Когда этот протокол появится в стандартной поставке какой-нибудь Windows 14, когда он же появится в мобильных платформах — массово, тогда и можно будет его использовать.
Иначе это получится программа для общения между двумя линуксами, причем оба линукса должны контролироваться автором программы — чтобы там SCTP заработал. Не у всех такие задачи.
Здравствуйте, Слава, Вы писали:
N>>SCTP.
С>Когда этот протокол появится в стандартной поставке какой-нибудь Windows 14, когда он же появится в мобильных платформах — массово, тогда и можно будет его использовать.
В линуксах он уже много лет из коробки => есть в андроиде. (Хотя не знаю насчёт его явовского API.)
В BSD тоже много лет из коробки => скорее всего, есть в iOS на тех же условиях.
Для винды есть реализации, включая бесплатные, но для меня лично это как проблемы индейцев — она мне не платформа.
С>Иначе это получится программа для общения между двумя линуксами, причем оба линукса должны контролироваться автором программы — чтобы там SCTP заработал.
Для этого много лет не нужно никаких усилий, просто запускаешь и работает.
С> Не у всех такие задачи.
Согласен. Случай он разный бывает. В одной подопечной железяке мозгов даже на TCP не хватает, остаётся UDP.
Здравствуйте, v_andal, Вы писали:
_>И чем же это важно? Это однозначно плохо для пропускной способности протокола. Каждый системный вызов дорого обходится. Я так наоборот делаю всё возможное, чтобы за один системный вызов вытащить как можно больше данных. Просто с меня требуют максимальную пропускную способность.
Твоя позиция и ваша специфика понятны, но ты зациклился на ней и упорно не хочешь вникнуть в то, что я говорю.
Я несколько раз (два — сам, ещё пару — через ближайших коллег, и слышал ещё) сталкивался со следующей ситуацией. Есть какая-то самопальная железка или прошивка к чему-то IPMI-BMC-подобному, в которую года 3 назад из-за улучшения аппаратных возможностей впихнули Linux, обрадовались облегчению, уволили всех толковых и посадили толпу выпускников заборостроительного ПТУ. Железка регулярно посылает данные мониторинга (телеметрию, whatever). Её можно отправлять по UDP, тогда проблем с границами нет, но есть шанс потерь. Кто-то из среднего начальства взвивается и говорит "потерь быть не должно", люди переключаются на TCP, и тут оказывается, что автор отправляющего агента Кришназевул Абдулкумар (иногда его зовут Ху Ли) искренне считает, что что одним send() отправлено, то одним recv() и получится, и никакой маркировки длины или эскейпинга не придумывает (каждый байт у него на строжайшем учёте, за лишний байт бьют по рукам и изгоняют в дерёвню, формат запутан и недиагностируем). Всё работает в его лаборатории на коленке, а когда начинаются проблемы с реальной загрузкой приложения и сети, он и его начальство (у которого мозгов ещё меньше, но больше наглости и изворотливости) посылают ко всем индийским лешим, утверждая, что проблемы не его стороне. Прочитать, что TCP отдаст за один recv() два пакета, и понять границы после этого невозможно, уже не укладывается в его квадратно-гнездовую башку. Вопрос не в максимальной производительности или количестве данных за один вызов, это не стоит проблемой — внутренняя обработка значительно сложнее сисколла. Вопрос в корректности передачи и разбора.
Вот именно поэтому я говорю, что из-за таких проблем надо в качестве подложки по умолчанию считать SCTP, а TCP применять только в трёх случаях — или неустранимое наследство, или требуется максимальная производительность на относительно мелких порциях, или поток вообще не ложится в концепцию сообщений крупнее октета (вряд ли это относится к чему-то более новому, чем telnet или ftp data).
(К тому же для задачи типа телеметрии или мультимедиа SCTP вкусен ещё возможностью сочетать настойчивость в доставке сообщения с ограничением количества попыток или времени этих попыток — что в принципе невозможно по TCP без разрыва соединения и требует написания собственной подложки для ретрансмитов в случае UDP.)
Ты можешь сказать, что я преувеличиваю долю таких случаев, что такие задачи, о которых я говорю, занимают жалкие доли процента от всего трафика. И я с этим соглашусь. Но именно от количества случаев, когда надо сочинять свой протокол поверх предоставляемого ОС транспорта, этих случаев очень много (и я всерьёз считаю, что их более половины). Это всё не относится к HTTP и прочим чудесам, занимающим 99% мирового трафика — это самопал, но это тема данного топика.
_> Алгоритм остаётся прежним "пакет в начале буфера, обработай, удали обработанное, смести начало буфера, у тебя опять пакет в начале буфера".
Фазы "смести начало буфера" в случае SCTP нет. "Удали обработанное" сводится к полной вычистке буфера. Так что тут реально проще. Но опять же дело не в этом. Я полностью согласен с тезисом, что при необходимости выжать максимум скорости получается множество слоёв сверху, по сравнению с которым работа с буфером — мелочь. Но см. выше про случаи из моего мира.
_>Ну да, если ты веришь, что буфера достаточно, то значит ты создаёшь потенциальную дыру. Писать всё равно приходится исходя из положения, что буфера недостаточно.
Я могу сделать так, что если после sctp_recvmsg() не вижу MSG_EOR, то соединение тупо рвётся сразу, и генерируется аларм "источник сошёл с ума". Для описанных применений это полностью адекватно.
N>>Там не из-за чего "трахаться", для данного уровня всё элементарно. _>Для начала нужно разобраться со всем многообразием уровней предлагаемых SCTP и понять, какой же уровень "данный". Собственно ничего другого я не имею в виду. Разобравшись с доками действительно выясняется, что SCTP можно использовать точно также как TCP
Игнорируя поддержку границ? А зачем?
_>Ну так с уверенностью можно сказать, что эти самые мириады не будут уметь работать и с SCTP.
Будут уметь, просто потому, что они натренированы, как собачки, написать заданное в инструкции имя сисколла и подставить ему заданные параметры, и это будет работать. В случае же TCP им нужно скормить готовую библиотеку, которая будет держать буфер вызывать коллбэк при получении полного сообщения, написать её сами или догадаться, что её надо написать, они не могут.
_>Эти слова не привязаны к TCP протоколу. Можно сказать, что знания о partial read в SCTP этот тривиальный мизер, который кодер просто игнорирует, надеясь, что его буфер всегда достаточного размера и он всегда получит полную запись. А в результате все получают очередной говнокод.
См. выше про специфику таких случаев.
_>А какое это имеет отношение к дискуссии о преимуществах SCTP по отношению к TCP? Дурацкий протокол можно придумать вне зависимости от используемого транспорта. С другой стороны, очень часто требования предъявляемые к протоколу не дают возможности задавать чёткие границы для пакетов. Тот же HTTP протокол используется в ситуациях, когда ответ может генериться кусками и куски могут быть слишком большими для буферизации. Так что чётких границ тут не задашь. Опять же, наличие чётких границ не даёт гарантии, что протокол хороший. SMPP протокол даёт чёткие границы пакетов (хоть и работает над TCP), но в пределах этих границ делает много глупостей, делающих работу с этим протоколом заморочной.
Кто бы спорил. Я работал с SIP и FIX. Оба — ужас на крыльях ночи.
_>Хм. Под "администрированием буфера" я понимаю "выделить место для стольких то байт", "отметить такое-то количество байт как данные", "убрать такое-то количество данных в начале", "убрать такое-то количество данных с конца", "дать доступ к данным в начале буфера". Эти операции остаются одинаковыми для обоих протоколов.
Для SCTP, повторяю, тебе не нужны операции "убрать в начале" (а для обоих — "убрать с конца"). У тебя остаётся для приёмного буфера — очистить буфер, дописать в конец буфера, отдать буфер на рассмотрение. Для передающего — передать буфер целиком (добавить в конец списка), убрать переданный из начала списка. В случае действительно сложной политики стиля random early drop можно делать удаления из середины, в случае QoS — расставлять приоритеты, это будет общее с TCP, но это ты не описал.
Здравствуйте, netch80, Вы писали:
N>Здравствуйте, v_andal, Вы писали:
N>Вот именно поэтому я говорю, что из-за таких проблем надо в качестве подложки по умолчанию считать SCTP, а TCP применять только в трёх случаях — или неустранимое наследство, или требуется максимальная производительность на относительно мелких порциях, или поток вообще не ложится в концепцию сообщений крупнее октета (вряд ли это относится к чему-то более новому, чем telnet или ftp data).
Боже мой. Да тупой индус программер наворочает дерьма для SCTP столько же, сколько он его льёт для TCP. Он просто вообще не сможет разобраться, как с ним работать. Утонет на фазе создания ассоциации. От глупости и незнания нельзя защититься более продвинутым протоколом. Поэтому, подобные аргументы в топку. Качественная программа не будет иметь значительных отличий.
N>(К тому же для задачи типа телеметрии или мультимедиа SCTP вкусен ещё возможностью сочетать настойчивость в доставке сообщения с ограничением количества попыток или времени этих попыток — что в принципе невозможно по TCP без разрыва соединения и требует написания собственной подложки для ретрансмитов в случае UDP.)
Для разных задач бывают нужны разные инструменты. Я не молюсь на TCP, я всего лишь считаю, что это очень хороший базовый протокол. Уходить от него стоит только в случаях не вписывающихся в "базу".
N>Фазы "смести начало буфера" в случае SCTP нет. "Удали обработанное" сводится к полной вычистке буфера. Так что тут реально проще. Но опять же дело не в этом. Я полностью согласен с тезисом, что при необходимости выжать максимум скорости получается множество слоёв сверху, по сравнению с которым работа с буфером — мелочь. Но см. выше про случаи из моего мира.
И эту разницу ты и считаешь "архисложной"? Только не надо меня опять отсылать к кодерам не знающим, что творят. Если для человека добавление одной-двух строчек кода — архисложно, то ему уже ничем не помочь. ИМХО
N>Будут уметь, просто потому, что они натренированы, как собачки, написать заданное в инструкции имя сисколла и подставить ему заданные параметры, и это будет работать.
Не смеши. Работать это дерьмо никогда не будет, точнее будет до ближайшей нестандартной ситуации в сети. И без разницы, какой протокол использовали.
N>Для SCTP, повторяю, тебе не нужны операции "убрать в начале" (а для обоих — "убрать с конца"). У тебя остаётся для приёмного буфера — очистить буфер, дописать в конец буфера, отдать буфер на рассмотрение. Для передающего — передать буфер целиком (добавить в конец списка), убрать переданный из начала списка. В случае действительно сложной политики стиля random early drop можно делать удаления из середины, в случае QoS — расставлять приоритеты, это будет общее с TCP, но это ты не описал.
Собственно, операция "убрать в начале" с количеством байт равным содержимому буфера и есть "очистить буфер". Так сказать, частный случай
Операция "убрать с конца" есть только потому, что я этот буфер использую и для подготовки пакетов к отправке. Заодно она оказалась удобной и для чтения. Резервируешь 10K, получаешь только 4K, остальные убираешь "с конца". Что касается "сложной политики", то в моих случаях она не используется, поэтому и операцию я не добавлял.
Собственно я не пытаюсь предложить универсальный API для буфера. Я всего лишь привёл пример буфера который может использоваться и для SCTP и для TCP. Безусловно, есть частные случаи, когда управление буфером будет требовать других операций, только обычно это определяется уже уровнем над транспортом, а не самим транспортом.
Резюме. Всё наше разногласие сводится к тезису о том, что тупой программер сможет делать более качественный код, если ему подсунуть SCTP вместо TCP. Если тебе хочет верить в эту глупость — то я ничего против не имею. Я же не настолько наивен. Для нормального программиста в базовом случае, разницы между SCTP и TCP нет, но документация для TCP проще и разобраться с ней получится быстрее. Собственно поэтому, большинство индусов знакомы (поверхностно) именно с TCP, а не с SCTP
Здравствуйте, v_andal, Вы писали:
_>Резюме. Всё наше разногласие сводится к тезису о том, что тупой программер сможет делать более качественный код, если ему подсунуть SCTP вместо TCP. Если тебе хочет верить в эту глупость — то я ничего против не имею. Я же не настолько наивен. Для нормального программиста в базовом случае, разницы между SCTP и TCP нет, но документация для TCP проще и разобраться с ней получится быстрее. Собственно поэтому, большинство индусов знакомы (поверхностно) именно с TCP, а не с SCTP
Они знакомы именно с TCP, потому что ему 40 лет и он успешно занял нишу, а SCTP активно всего 10 (а для Windows и вообще, считай, 0) и в эту нишу тяжело и нудно просачивается.
В остальном я согласен, я действительно предсказываю (не априорно, а на основании своего опыта), что тупой программер, поставленный на правильные рельсы, будет значительно меньше глупостей творить в случае SCTP, чем в случае TCP. У меня есть примеры успешного такого решения перед глазами. Один, самый эффективный, правда, не AF_INET+SCTP, а AF_UNIX+SOCK_SEQPACKET, но результат чрезвычайно вкусный. С SCTP похоже, но не настолько впечатляюще — может, потому, что у меня нет индусов.
N>>Вот именно поэтому я говорю, что из-за таких проблем надо в качестве подложки по умолчанию считать SCTP, а TCP применять только в трёх случаях — или неустранимое наследство, или требуется максимальная производительность на относительно мелких порциях, или поток вообще не ложится в концепцию сообщений крупнее октета (вряд ли это относится к чему-то более новому, чем telnet или ftp data). _>Боже мой. Да тупой индус программер наворочает дерьма для SCTP столько же, сколько он его льёт для TCP. Он просто вообще не сможет разобраться, как с ним работать. Утонет на фазе создания ассоциации.
connect на конкретный хост и порт — что может быть проще? Сложности с построением ассоциации пропускаем.
N>>Фазы "смести начало буфера" в случае SCTP нет. "Удали обработанное" сводится к полной вычистке буфера. Так что тут реально проще. Но опять же дело не в этом. Я полностью согласен с тезисом, что при необходимости выжать максимум скорости получается множество слоёв сверху, по сравнению с которым работа с буфером — мелочь. Но см. выше про случаи из моего мира. _>И эту разницу ты и считаешь "архисложной"? Только не надо меня опять отсылать к кодерам не знающим, что творят. Если для человека добавление одной-двух строчек кода — архисложно, то ему уже ничем не помочь. ИМХО
Ещё раз. Дело не в сложности как таковой. Дело в ловушке, которая позволяет пропустить этот шаг в лабораторных условиях TCP, показать, что и без него всё работает, и наплевать на проблемы тех, кто будет пользоваться результатом в реальных условиях. Идеальный программист в идеальных условиях, да, такого не допустит. Реальный чужой программист, заинтересованный не в результате, а в оплате времени и карьерных KPI — сделает, и пока ты пробьёшься через 5-10 административных слоёв для доказательства, что он был неправ, ты успеешь поседеть.
N>>Будут уметь, просто потому, что они натренированы, как собачки, написать заданное в инструкции имя сисколла и подставить ему заданные параметры, и это будет работать. _>Не смеши. Работать это дерьмо никогда не будет, точнее будет до ближайшей нестандартной ситуации в сети. И без разницы, какой протокол использовали.
Пример такой нестандартной ситуации? (Файрволлы и NAT не предлагать)
Здравствуйте, netch80, Вы писали:
N>Здравствуйте, v_andal, Вы писали:
_>>Резюме. Всё наше разногласие сводится к тезису о том, что тупой программер сможет делать более качественный код, если ему подсунуть SCTP вместо TCP. Если тебе хочет верить в эту глупость — то я ничего против не имею. Я же не настолько наивен. Для нормального программиста в базовом случае, разницы между SCTP и TCP нет, но документация для TCP проще и разобраться с ней получится быстрее. Собственно поэтому, большинство индусов знакомы (поверхностно) именно с TCP, а не с SCTP
N>Они знакомы именно с TCP, потому что ему 40 лет и он успешно занял нишу, а SCTP активно всего 10 (а для Windows и вообще, считай, 0) и в эту нишу тяжело и нудно просачивается.
Да и сам протокол тяжеловат...
N>connect на конкретный хост и порт — что может быть проще? Сложности с построением ассоциации пропускаем.
Хе, чтобы пропустить то, что можно пропустить и выцепить то, что что нужно выцепить, талант надо иметь. А с талантом без разницы какой протокол штудировать
N>Ещё раз. Дело не в сложности как таковой. Дело в ловушке, которая позволяет пропустить этот шаг в лабораторных условиях TCP, показать, что и без него всё работает, и наплевать на проблемы тех, кто будет пользоваться результатом в реальных условиях.
Так блин, такой программист и partial read в SCTP проигнорирует, на тех же условиях.
N>Пример такой нестандартной ситуации? (Файрволлы и NAT не предлагать)
А если подсунуть удалённому хосту заведомо большой пакет (выходящий за пределы системных буферов), вынуждающий его скармливать этот пакет в несколько приёмов?
Или мы говорим исключительно о протоколах внутреннего использования? Или начнёшь заверять, что индус отказывающийся верить, что в TCP пакет может прийти разбитым, вдруг чудесным образом поверит, что в SCTP это возможно? И это после того, как его заверят, что SCTP в отличие от TCP сохраняет границы пакета? Увольте, в такие чудеса я не верю.
Здравствуйте, lnkuser, Вы писали:
L>Подскажите пожалуйста хоть в какую сторону рыть, сутки проб и поисков не дали результата...
L>Пишу простенький веб-сервер сугубо для своих нужно, нужно отправлять и получать JSON.
Нужен буффер для чтения, который умещает максимальный json запрос. Читать в буффер данные, пока не придёт последняя } скобка — это и будет
json запрос. А то, что осталось в буфере сдвигать в начало и по новой.
Здравствуйте, v_andal, Вы писали:
_>Боже мой. Да тупой индус программер наворочает дерьма для SCTP столько же, сколько он его льёт для TCP. Он просто вообще не сможет разобраться, как с ним работать. Утонет на фазе создания ассоциации. От глупости и незнания нельзя защититься более продвинутым протоколом. Поэтому, подобные аргументы в топку. Качественная программа не будет иметь значительных отличий.
Вот несколько умных мыслей из другого источника:
> >Также как гонять unbounded потоки байт по TCP малой полезности идея (в 100% случаев нужны сообщения, а не поток) > > Абсолютно голословное утверждение. Сообщения с проверкой доставки совершенно бесполезны при вещании потокового видео, в интерактивных играх, при передаче низкоприоритетной телеметрии и т.п. До тех пор, пока каналы передачи данных не будут гарантировать доставку данных за определенный промежуток времени, будут востребованы потоковые протоколы, позволяющие терять определенный процент данных в обмен на плавное ухудшение качества сервиса. Например, показывать вместо 48 кадров в секунду 24 лучше чем вообще прерывать трансляцию видео.
Комментатор сознательно решает не замечать логику аргумента.
Вещание потокового видео — серия относительно коротких файлов (в районе мегабайта на файл). Интерактивная игра — серия сообщений, либо HTTP (где один фетч — это по сути один мессадж), либо тот же WebSocket — где обмен сообщениями идёт через message-oriented транспорт, или тупо наверчивают фрейминг а-ля "тут пишем 4 байта длины, потом JSON". Это всё каждый факин раз изобретается заново.
Передача низкоприоритетной телеметрии, это, в лучшем случае, UDP, в среднем — line separated TCP (тот же фрейминг, но не length-prefixed, а \n-separated), а в худшем — SNMP, который суть что? Правильно, TLV.
SMTP — это message oriented транспорт. Один заголовок SMTP-exchange (типа EHLO) или боди целиком — это отдельные сообщения. Сейчас парсинг их осуществляется иногда поиском завершителя строки \n, иногда — поиском пустой строки (\n\n), иногда — поиском точки на пустой строке. В одном и том же факин протоколе! Нет уж, дайте нам нативный message oriented transport, дальше уж мы сами накрутим поверх этого логику, надоело парсить в телах \n-ы.
Здравствуйте, Слава, Вы писали:
С>SMTP — это message oriented транспорт. Один заголовок SMTP-exchange (типа EHLO) или боди целиком — это отдельные сообщения. Сейчас парсинг их осуществляется иногда поиском завершителя строки \n, иногда — поиском пустой строки (\n\n), иногда — поиском точки на пустой строке. В одном и том же факин протоколе! Нет уж, дайте нам нативный message oriented transport, дальше уж мы сами накрутим поверх этого логику, надоело парсить в телах \n-ы.
SMTP протокол это динозавр. Он возник во времена когда к 8-битным данным плохо относились, да и пропускная способность ценилась. Поэтому он чисто текстовый, со всеми вытекающими заморочками. Сейчас систему email можно вообще всю иначе сделать, только кто же будет работающую систему ломать? Вон даже IPv6 никак не оживёт, хоть вроде бы и нужен, что уж про email говорить, когда здесь и так всё работает. Так что можно ныть на тему заморочности SMTP или HTTP, только парсить их всё равно придётся.
Ну а по-поводу "нативный message oriented transport" я уже раньше сказал, если кому-то нужен этот костыль — пользуйтесь на здоровье. Я не вижу никакой сложности в разборе потока. Основная сложность всегда в логике накрученной поверх полученных данных. Безусловно, схема "длина пакета + пакет" удобнее, чем "найди конец пакета", но и это не катастрофа. С другой стороны, протоколы на основе ASN со всеми их бессчётными TLV тоже доводят до белого каления.
На мой взгляд, сетевой транспорт не должен заботится о границах данных, это не диван, цифровые данные можно дробить и склеивать без особых последствий. Собственно разбивка нужна, так как сетевое железо не блещет однообразием возможностей. Склеивание же на системном уровне осложняется размерами буфера, так что гораздо разумнее оставить склеивание конечному потребителю, по крайней мере это последовательнее, чем часть пакетов склеивать, а часть отдавать кусками. ИМХО.
Если уж мечтать об усовершенствованиях, то лучше мечтать о более совершенном routing. В общем-то мультихом мог бы быть реализован на этом уровне, без того, чтобы захламлять софт
Здравствуйте, netch80, Вы писали:
N>Я несколько раз (два — сам, ещё пару — через ближайших коллег, и слышал ещё) сталкивался со следующей ситуацией. Есть какая-то самопальная железка или прошивка к чему-то IPMI-BMC-подобному, в которую года 3 назад из-за улучшения аппаратных возможностей впихнули Linux, обрадовались облегчению, уволили всех толковых и посадили толпу выпускников заборостроительного ПТУ. Железка регулярно посылает данные мониторинга (телеметрию, whatever). Её можно отправлять по UDP, тогда проблем с границами нет, но есть шанс потерь. Кто-то из среднего начальства взвивается и говорит "потерь быть не должно", люди переключаются на TCP, и тут оказывается, что автор отправляющего агента Кришназевул Абдулкумар (иногда его зовут Ху Ли) искренне считает, что что одним send() отправлено, то одним recv() и получится, и никакой маркировки длины или эскейпинга не придумывает (каждый байт у него на строжайшем учёте, за лишний байт бьют по рукам и изгоняют в дерёвню, формат запутан и недиагностируем). Всё работает в его лаборатории на коленке, а когда начинаются проблемы с реальной загрузкой приложения и сети, он и его начальство (у которого мозгов ещё меньше, но больше наглости и изворотливости) посылают ко всем индийским лешим, утверждая, что проблемы не его стороне. Прочитать, что TCP отдаст за один recv() два пакета, и понять границы после этого невозможно, уже не укладывается в его квадратно-гнездовую башку. Вопрос не в максимальной производительности или количестве данных за один вызов, это не стоит проблемой — внутренняя обработка значительно сложнее сисколла. Вопрос в корректности передачи и разбора. N>Вот именно поэтому я говорю, что из-за таких проблем надо в качестве подложки по умолчанию считать SCTP, а TCP применять только в трёх случаях — или неустранимое наследство, или требуется максимальная производительность на относительно мелких порциях, или поток вообще не ложится в концепцию сообщений крупнее октета (вряд ли это относится к чему-то более новому, чем telnet или ftp data).
Это очень интересный изолированный сценарий: переход от датаграммного протокола к потоковому. Вот для него, конечно же, tcp — плохой выбор, надо переходить от датаграммного протокола без гарантий к датаграммному с гарантиями — например к sctp.
Хотя в целом это всё — попытка решить административную проблему техническими средствами, что заведомо невозможно.
Мы говорим о весьма сложной задаче — проектирование прикладного протокола поверх чего-то более-менее стандартного.
Это задача явно за пределами компетентности ПТУшника, потому что network is hard. Если разработчик не в состоянии понять, почему udp не подходит для потока или tcp для датаграмм, то он и всё остальное тоже гарантированно протупит. У него шансы получить работающую реализацию примерно такие же, как и выиграть в Вегасе.
А если мы говорим о реализации готового протокола, то всё гораздо лучше — потому что проектирование обычно выполнено вменяемыми людьми.
В частности, в HTTP вопрос детектирования границ решается однозначно и независимо от границ каких-либо пакетов.
И все остальные протоколы, построенные поверх потокового соединения, имеют встроенные возможности детектирования границ.
HTTP в этом смысле чрезмерно сложен — поскольку у него в одних случах границы определяются ескейпингом (плюс специальные меры для изъятия искусственных границ), а в других — префиксом длины. К счастью, код разбора протокола можно либо взять готовый, либо построить из простых кирпичиков, которые убирают всю эту адову мешанину с глаз долой.
Рукопашно-реализованный протокол обычно строится каким-то одним способом, и его навелосипедить проще, чем построить HTTP сервер или HTTP клиент с нуля.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.