Как узнать, является ли это последний пакет, отправленный с доски объявлений

Я пишу читатель доски объявлений (BBS) на IOS. Я использую библиотеку GCDAsyncSocket для обработки отправки и получения пакетов. У меня проблема в том, что сервер всегда разделяет данные для отправки на несколько пакетов. Я вижу, что это происходит, распечатывая полученную строку в функции didReceiveData().

Из readme GCDAsyncSocket я понимаю, что TCP является потоком. Я также знаю, что есть некоторые механизмы конца потока, такие как LF с двойным CR в конце. Я использовал WireShark для анализа пакетов, но в последнем пакете данных нет никаких признаков какого-либо паттерна. Сайт не принадлежит мне, поэтому я не смог отправить определенные байты. Должен быть какой-то способ обнаружить последний пакет, иначе как клиенты BBS обрабатывают отображение данных?

1 ответ

LF с двойным CR не являются концом потока. Например, это лишь часть подробностей протокола HTTP, но это не имеет никакого отношения к закрытию потока. HTTP 1.1 позволяет мне отправлять несколько ответов в одном потоке, с двойным CR LF после заголовка HTTP, без конца потока.

Поток сокета TCP вернет 0 при чтении, когда он будет закрыт с другого конца, блокирующий или неблокирующий.

Таким образом, предполагая, что сервер закроет сокет после завершения отправки вам, вы можете выполнить цикл и выполнить чтение блокировки, а если вернет> 0, обработать данные, а затем снова прочитать. если < 0, обработайте код ошибки (может быть фатальным или нет), а если == 0, сокет закрыт с другой стороны, не читайте снова.

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

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

Другие вопросы по тегам