Я использую winsock в своем приложении для управления соединением клиент-сервер и использую неблокирующие сокеты для этого. Но иногда, когда я получаю FD_READ
сообщение, кажется, что recv()
возвращает не один, а два пакета.
Я попытался изменить размеры пакетов, чтобы они отличались друг от друга, а затем сравнил их с количеством данных. recv()
возвращается Я на 100% уверен, что время от времени получаю два пакета. Я думаю, что моя функция пинга должна быть обвинена. В моем приложении есть ветка, которая время от времени отправляет сообщение ping. Затем другая сторона отвечает другим сообщением. Не уверен, что это лучший способ сделать это, но неважно, сейчас это не имеет значения.
Что я знаю наверняка, так это то, что иногда эти сообщения «смешиваются», поэтому recv()
возвращает «запрос пинга» и «ответ пинга» одновременно. Как это случилось? не recv()
должен возвращать только тот объем данных, который send()
звонок отправлен? Даже если иногда клиент или сервер получает сообщение «ping request» и отвечает на него, при отправке своего собственного сообщения «ping request», даже если такой неудачный выбор времени возможен, не должна ли другая сторона отличать один пакет от другого и возвращать один на FD_READ
сообщение?
TCP — это поток данных, а не поток пакетов. UDP — это поток пакетов. Как сказал Энтони, если вы используете TCP, вы должны обработать, где заканчивается один раздел данных и начинается следующий.
Вероятно, это тот случай, когда вы действительно получили два пакета между последним вызовом recv и временем получения двух пакетов. recv не собирается получать по одному пакету за раз, он считывает все данные, имеющиеся в буфере. Это означает, что может быть доступно более одного сообщения данных или может быть доступна только часть сообщения. (Если это достаточно большое сообщение, оно будет разбито на несколько пакетов.) Ваша задача — декодировать ваши собственные данные. Простой способ сделать это — добавить заголовок с некоторой информацией, которая может вам помочь, например, идентификатор сообщения или указание ожидаемого размера данных. Обычно нижний колонтитул с CRC для проверки целостности данных (и обеспечения того, что у вас есть полное сообщение) также не повредит.