Обработка частичного возврата из recv () TCP в C

Когда я пишу класс, большинство методов попадает в две категории:

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

Статические методы полезны, потому что только путем рассмотрения его подписи, Вы знаете, что вызов его не использует или изменяет состояние текущего экземпляра.

Берут этот пример:

public class Library
{
    private static Book findBook(List<Book> books, string title)
    {
        // code goes here
    }
}

, Если экземпляр состояния библиотеки когда-нибудь завинчивается, и я пытаюсь выяснить, почему, я могу исключить findBook как преступник, только от его подписи.

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

13
задан Sergey Brunov 4 August 2016 в 15:12
поделиться

3 ответа

Да, вам понадобится несколько вызовов recv () , пока у вас не будут все данные.

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

Лучше, если полученные вами данные каким-то образом кодируют длина общих данных. Читайте столько данных, пока не узнаете их длину, затем считывайте, пока не получите данные длина . Для этого возможны различные подходы; распространенным является создание буфера, достаточно большого для хранения всех данных, если вы знаете его длину.

Другой подход - использовать буферы фиксированного размера и всегда пытаться получить мин (отсутствует, размер буфера) ,

15
ответ дан 1 December 2019 в 21:25
поделиться

Первое, что вам нужно знать при программировании TCP / IP: 1 запись / отправка вызов может занять несколько вызовов recv для приема, а для нескольких вызовов записи / отправки может потребоваться всего 1 вызов recv для приема. И все, что между ними.

Вам нужно будет выполнить цикл, пока не будут собраны все данные. Возвращаемое значение recv () сообщает вам, сколько данных вы получили. Если вы просто хотите получить все данные по TCP-соединению, вы можете зацикливаться, пока recv () не вернет 0 - при условии, что другой конец закроет TCP-соединение, когда он закончит отправку.

Если вы отправляете записи / строки / пакеты / команды или что-то подобное, вам необходимо создать свой собственный протокол через TCP, который может быть таким простым, как «команды разделяются \ n ».

Самый простой способ прочитать / проанализировать такую ​​команду - это читать по 1 байту за раз, создание буфера с полученными байтами и проверка наличия байта \ n каждый раз. Чтение 1 байта крайне неэффективно, поэтому вы должны читать большие куски за раз.

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

11
ответ дан 1 December 2019 в 21:25
поделиться

Да, вы должны перебирать recv () , пока не получите '\ 0' или произошла ошибка (отрицательное значение из recv ) или 0 из recv () . Для первого варианта: только если этот ноль является частью вашего протокол (его отправляет сервер). Однако из вашего кода кажется, что ноль - это просто возможность использовать содержимое буфера как C-строка (на стороне клиента).

Проверка возвращаемого значения 0 из recv : это означает, что соединение было закрыто (это могло быть частью вашего протокола, что это происходит.)

0
ответ дан 1 December 2019 в 21:25
поделиться