TCP Socket Transfer - PullRequest
       22

TCP Socket Transfer

1 голос
/ 17 декабря 2010

Некоторое время назад у меня возник вопрос о том, почему мой сокет иногда получал только 653 октета (например), когда я отправлял 1024 октета, и благодаря Rakis я понял: ОС позволяет получать данные произвольно размерами.

На этот раз мне нужно подтверждение:)

На любой ОС (ну, по крайней мере, на GNU / Linux и Windows), на любом языке (здесь я использую Python), если я отправлю случайный пакетчисло байтов, может быть 2 байта, может быть 12000 байтов, скажем, X, когда я пишу socket.send (X), я абсолютно уверен, что X будет получен ПОЛНОСТЬЮ (независимо от каких-либо кусков, на которые принимающая ОС делит его)на другом конце сокета ДО того, как я сделаю еще один socket.send (любая строка)?

Или другими словами, если у меня есть код:

socket.send(X)
socket.send(Y)

Даже если X> MTU, поэтому он будет обязан отправлять несколько пакетов, будет ли он ждать, пока каждый пакет будет отправлен и подтвержденконечной точкой сокета перед отправкой Y?Хорошо написав, что заставляет меня поверить, что ответ - да, это гарантировано, и именно в этом заключается цель установки сокета в режиме блокировки, но я хочу быть уверенным: D

Заранее спасибо, Nolhian

Ответы [ 4 ]

2 голосов
/ 17 декабря 2010

Нет, вы не можете.

Все, что вы знаете, это то, что клиент будет получать данные по порядку, предполагая, что действительно получает их все. Нет способа узнать (на уровне приложения), получил ли клиент все данные, не имея своего рода «ACK» в протоколе уровня приложения.

2 голосов
/ 17 декабря 2010

Вам гарантировано, что X будет получено (на уровне приложения) до Y, если это сокет потока.Если это сокет дейтаграммы, никаких гарантий.

В зависимости от реализации сети, возможно, что на более низком уровне X будет отправлено, потеряно при передаче, затем Y будет отправлено, а X будет повторноотправлено, потому что подтверждение не получено.

Даже в режиме блокировки socket.send (Y) может выполняться еще до того, как X сделает это «на провод», потому что ОС будет буферизовать сетевой трафик.

0 голосов
/ 17 декабря 2010

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


Вернуться к вашему вопросу:

ждет, пока каждый пакет не будет отправлен и подтвержден конечной точкой сокета, прежде чем отправить Y

Итак, вы могли бы сказать:

  • ДА, он действительно ждет отправки и
  • НЕТ, оно не ждет подтверждения

Предложение:

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

0 голосов
/ 17 декабря 2010

Абсолютно ли я гарантирую, что X будет ПОЛУЧЕНО ПОЛУЧЕНО (независимо от каких-либо кусков, на которые делит его принимающая ОС) на другом конце сокета ДО ТОГО, как я сделаю еще один socket.send (любая строка)?

Нет. Как правило, больше данных может быть отправлено без ожидания принимающей стороны в определенных пределах:

  • на отправляющей стороне у вас будет максимальный объем данных, который вы можете поставить в очередь для передачи, пока клиент не подтвердит получение какого-либо сообщения (но, как правило, ОС клиента будет достаточно много подтверждать и буферизовать, прежде чем он откажется от дальнейших данных, пока приложение обработало несколько), после чего отправляющий сокет может начать блокировать

    • заставляет дизайн приложения учитывать, как ставить в очередь и буферизовать чрезмерные объемы данных, вместо того, чтобы наивно написанные приложения использовали чрезмерные объемы предоставленной операционной системой буферной памяти
    • снижает скорость повторной передачи, когда принимающая сторона заполняется данными, слишком быстрыми для их обработки
    • избегает отправки огромных объемов данных, несмотря на то, что сетевое соединение было потеряно

Таким образом, строго говоря и для больших передач, отправитель должен быть спроектирован так, чтобы обрабатывать сокеты, заблокированные от дальнейших отправлений (либо зная, что это нормально для блокировки при попытке (возможно, из-за выделенного потока отправки), либо ожидая, пока это станет возможным чтобы отправить больше через неблокирующие сокеты или выбрать / опросить).

Независимо от того, что может потребоваться повторная передача и буферизация, вы МОЖЕТЕ быть уверены в том, что принимающая сторона должна будет прочитать все буквы «X», прежде чем ей начнут передаваться последующие отправленные данные «Y» (если только просит, чтобы это было иначе, например, данные Out of Band).

...