Гарантировано ли, что TCP прибудет в порядке?

Если я отправлю два TCP-сообщения, нужно ли обрабатывать случай, когда последнее приходит раньше первого? Или он гарантированно прибудет в том порядке, в котором я его отправлю? Я предполагаю, что это не специфичный для Twisted пример, потому что он должен соответствовать стандарту TCP, но если кто-нибудь, знакомый с Twisted, может дать ответ, специфичный для Twisted, для моего собственного спокойствия, это будет оценено по достоинству :-)


person Smashery    schedule 06.11.2009    source источник
comment
Поскольку TCP не знает, где начинаются и заканчиваются ваши сообщения, как он может изменить их порядок, даже если захочет?   -  person David Schwartz    schedule 17.09.2011


Ответы (4)


Пока два сообщения были отправлены по одному и тому же TCP-соединению, порядок сохраняется. Если между одной и той же парой процессов открыто несколько соединений, у вас могут возникнуть проблемы.

Что касается Twisted или любой другой асинхронной системы событий: я ожидаю, что вы получите сообщения dataReceived в порядке получения байтов. Однако, если вы начнете перекладывать работу на отложенные вызовы, вы можете, эм... "исказить" свой поток управления до неузнаваемости.

person Jeffrey Hantin    schedule 06.11.2009

TCP ориентирован на соединение и предлагает своим клиентам доставку по порядку. Конечно, это относится к уровню соединения: отдельные соединения независимы.

Обратите внимание, что обычно мы имеем в виду «потоки TCP» и «сообщения UDP».

Какую бы клиентскую библиотеку вы ни использовали (например, Twisted), базовое TCP-соединение не зависит от нее. TCP будет доставлять «протокольные сообщения» вашему клиенту. Под «протокольным сообщением» я, конечно же, подразумеваю протокол, который вы используете на уровне TCP.

Кроме того, обратите внимание, что операции ввода-вывода являются асинхронными по своей природе и очень зависят от загрузки системы, а также усугубляют задержки и потери в сети, вы не можете полагаться на порядок сообщений между соединениями TCP.

person jldupont    schedule 06.11.2009
comment
Что вы подразумеваете под между соединениями TCP? - person simplename; 02.08.2017

TCP «гарантирует», что получатель получит восстановленный поток байтов в том виде, в каком он был первоначально отправлен отправителем. Однако между конечными точками отправки/получения TCP (т. е. физической сетью) данные могут быть получены не по порядку, фрагментированы, повреждены и даже потеряны. TCP учитывает эти проблемы, используя механизм рукопожатия, который вызывает повторную передачу плохих пакетов. Стек TCP на приемнике помещает эти пакеты в том порядке, в котором они были переданы, поэтому при чтении из сокета TCP вы получаете данные в том виде, в котором они были отправлены изначально.

При вызове метода doRead в Подкрутил, данные читаются из сокета до размера буфера. Эти данные могут представлять собой одно сообщение, частичное сообщение или несколько сообщений. Извлечение сообщений из буфера зависит от вас, но вам гарантируется, что в этот момент байты находятся в том порядке, в котором они были переданы.

Извините, что мутил воду своим предыдущим сообщением...

person Matt Davis    schedule 06.11.2009
comment
пожалуйста, пересмотрите свой ответ, так как вы очень ошибаетесь. API, предоставляемый TCP, очень похож на поток с упорядоченной доставкой байтов. Здесь вы имеете в виду базовый метод транспортировки (т.е. пакеты), которые, конечно, не гарантируют, что они будут доставлены по порядку. - person jldupont; 07.11.2009
comment
К вашему сведению, уровень сервера для TCP — это IP, который, конечно, не требует установления соединения и не гарантирует доставку порядка пакетов. - person jldupont; 07.11.2009
comment
Я запутался в вашем объяснении - во втором предложении вы пишете, что данные могут быть повреждены (для TCP-клиента?), а в третьем вы пишете, что они не будут повреждены, потому что TCP обработает такой случай. Так что же может увидеть TCP-клиент — данные повреждены или гарантированно верны? Также с порядком данных, вы имеете в виду, что при прямом соединении порядок гарантирован, но для непрямого соединения TCP-клиент может видеть данные не по порядку? - person astrowalker; 08.11.2016

TCP — это поток, UDP — это сообщение. Вы путаете термины. Для TCP верно то, что поток будет поступать в том же порядке, в котором он был отправлен. В TCP нет отдельных сообщений, байты появляются по мере их поступления, интерпретация их как сообщений зависит от вас.

person Jochen Ritzel    schedule 06.11.2009
comment
Re: термины - Да, конечно. Однако Twisted абстрагирует это в отдельные сообщения (поэтому интерпретация их как сообщений не зависит от меня). - person Smashery; 07.11.2009
comment
И стоит отметить, что, хотя у вас может быть две записи на стороне отправителя, они могут свернуться в одно чтение на стороне получателя, и наоборот — в зависимости от размеров буфера и условий сети. - person Andrew Y; 07.11.2009
comment
Нет, Twisted не абстрагирует TCP в сообщения. Вы получите кусок байтов (в крайних случаях до одного байта за раз) в базовом протоколе. - person truppo; 07.11.2009
comment
Я думаю, что это правильно с точки зрения приложения. С точки зрения протокола, TCP — это, по сути, UDP с множеством расширений для обработки соединений, повторной отправки потерянных пакетов, упорядочения прибытия и так далее. Это хорошо заметно в API Unix: одни и те же вызовы API, ориентированные на потоки (запись, чтение) и вызовы, ориентированные на пакеты (отправка, revc), работают на обоих типах сокетов. Конечно, вы не можете манипулировать UDP-соединением на уровне субпакетов, в то время как вы можете читать/записывать TCP-соединения на уровне потока байтов. - person peterh; 06.02.2019