Например, если я посылаю «a» и «b» в совершенно разных пакетах, клиент читает их как «ab».Это происходит только один раз, но это создает реальную проблему в игре.
Я думаю, вы упустили из виду фундаментальную природу TCP: это потоковый протокол, а не пакетный протокол.TCP не уважает и не сохраняет границы данных отправителя.Другими словами, TCP может свободно объединять (или разбивать!) Отправляемые вами «пакеты» и представлять их на приемнике так, как он хочет.Единственное ограничение, которое соблюдает TCP, заключается в следующем: если байт доставлен, он будет доставлен в том же порядке, в котором он был отправлен.(И ничто в Nagle не меняет этого.)
Итак, если вы дважды вызываете send
(или write
) на сервере, отправляя эти шесть байтов:
"packet" 1: A B C
"packet" 2: D E F
Ваш клиентсторона может recv
(или read
) любую из следующих последовательностей байтов:
ABC / DEF
ABCDEF
AB / CD / EF
Если ваше приложение требует знания границ между write
s отправителя, то вы обязаны сохранитьи передать эту информацию.
Как уже говорили другие, есть много способов сделать это.Вы можете, например, отправить новую строку после каждого кванта информации.Так (частично) работают HTTP, FTP и SMTP.
Вы можете отправить длину пакета вместе с данными.Обобщенная форма для этого называется TLV, для «Тип, Длина, Значение».Отправьте поле типа фиксированной длины, поле фиксированной длины, а затем значение произвольной длины.Таким образом, вы узнаете, когда вы прочитали все значение и готовы к следующему TLV.
Вы могли бы договориться, что каждый отправленный вами пакет идентичен по длине.
Полагаю, есть и другие решенияи я полагаю, что вы можете думать о них самостоятельно.Но сначала вы должны понять это: TCP может и объединит или разорвет ваши пакеты приложения.Вы можете рассчитывать на порядок доставки байтов, но не более.