Почему мой сокет TCP / IP получает непоследовательные объемы данных за чтение? - PullRequest
0 голосов
/ 07 февраля 2020

Я работаю над проектом с Socket TCP / IP (Сервер- C# и Клиент- Python). Потоковое видео после иногда, данные Recv Socket разбиваются. Мои данные имеют размер баффа = 22000 байт, если он будет разделен, он станет:

buff = 1460
buff = 20600

Я не знаю почему, я исследовал некоторые методы с MTU, фрагментация, Windows размер, .... но безрезультатно Специально, если я установил, что процесс будет казаться меньше.

self.sk.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 1048576) 

введите описание изображения здесь - Изображение о данных разделено

enter image description here

Это мое гнездо Recv.

buff = self.sk.recv(1048576)
print("BUFF RECEIVE  :::  ::::: ---->>>>>      ",len(buff))
if buff == b'' :
  self.sk=None
  buff = None
  return buff

Предложения : Это только что произошло в Chrome Браузер (это означает, что потоковое видео не может быть, если потеря данных). Но на Firefox, это не так. Кажется, мигает момент, если потеря данных, но он может продолжить поток после. введите описание изображения здесь - Chrome и FireFox

Ответы [ 2 ]

1 голос
/ 08 февраля 2020

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

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

Что касается почему TCP может вести себя так, как вы наблюдали - он, вероятно, реагирует на условия сети (отброшенные пакеты, обратная связь из стека TCP принимающего хоста и т. Д. c) и пытается сделать передачу максимально эффективной с учетом его текущая среда. Это на 100% зависит от стека TCP, как он хочет передавать данные, и разные стеки TCP могут вести себя по-разному, что хорошо, если они следуют правилам спецификации TCP.

0 голосов
/ 16 февраля 2020

Через долгое время я нашел ответ на свой вопрос.

Решение проблемы с границей сообщений сокета клиента TCP / IP

** 1 / * * Когда вы отправляете пакет с сервера на клиент с отправкой (записью). На стороне клиента прием иногда не дает полных данных. Это не значит, что отправка / запись на сервер не отправляет достаточно данных. Просто потому, что это TCP / Протокол IP, Receive не является выпускником, и пакет будет фрагментирован на стороне клиента (ваш код).

** 2 / ** Эту проблему можно решить, добавив дополнительный шаблон на стороне отправки / записи на стороне сервера. Например, send (data) -> send (Pattern + data) и на стороне клиента вы можете использовать patern для проверки данных.

** 3 / ** Ограничения этого метода, пакета после фрагментации , он может «объединяться» или иногда не может. Например, ваши данные для отправки = 4000, а на стороне клиента, вы получите = 1460 + 2540. Это то, что я понял с моей проблемой.

...