Как датаграмма TCP поступает на клиентский компьютер? - PullRequest
0 голосов
/ 01 мая 2018

Я пытаюсь понять некоторые концепции, касающиеся передачи данных TCP.

Предположим, мы используем сокет (в C) для отправки и получения GET HTTP запросов на веб-сайт. Что касается принимающей стороны, то, что я видел, это реализация ниже. По сути, буфер response создается и итеративно заполняется.

memset(response, 0, sizeof(response));
total = sizeof(response)-1;
received = 0;
while (received < total) {
    bytes = recv(sockfd, response + received, total - received, 0);
    if (bytes < 0)
        error("ERROR reading response from socket");
    if (bytes == 0)
        break;
    received += bytes;
}

Следующие две вещи мне не очень понятны

  1. Откуда response получает данные, кеш из ОС или данные непосредственно с веб-сайта? Я не изучал операционные системы, что затрудняет мне комплексный процесс буферизации.
  2. Кроме того, теоретически TCP будет проверять потери при передаче, где это происходит? Когда я выполнял программирование сокетов, я не видел никаких обработчиков, касающихся потери передачи, автоматически ли это обрабатывается socket?

Ответы [ 2 ]

0 голосов
/ 01 мая 2018

Откуда ответ получает данные, кеш из ОС или данные прямо с сайта? Я не изучал операционные системы, которые затрудняет мне комплексный процесс буферизации.

Пакеты TCP принимаются от сетевого устройства (карта Ethernet, адаптер Wi-Fi и т. Д.), А их полезные данные помещаются во временный буфер внутри стека TCP / IP. Когда ваша программа вызывает recv(), некоторые или все эти данные копируются из временного буфера в буфер вашей программы (response).

Стек TCP / IP не выполняет никакого кэширования данных, кроме описанного выше. (например, если веб-браузер хочет кэшировать локальную копию веб-страницы, чтобы ему не приходилось загружать ее второй раз, это будет зависеть от самого веб-браузера, чтобы сделать это на уровне приложения; TCP / Стек IP и ОС не будут делать это самостоятельно)

Кроме того, теоретически TCP будет проверять потери при передаче, причем это случилось? Когда я делаю программирование сокетов, я не видел обработчики относительно потери передачи, это автоматически обрабатывается гнездо

Он прозрачно обрабатывается внутри стека TCP. В частности, каждый пакет TCP имеет контрольную сумму и порядковый номер, включенные в его заголовок, а стек TCP проверяет этот порядковый номер каждого полученного пакета, чтобы убедиться, что он соответствует следующему номеру в последовательности (относительно предыдущий пакет он получил из того же потока TCP). Если это не ожидаемый номер следующего пакета, то стек TCP знает, что пакет каким-то образом потерян, и отвечает, отправляя запрос на удаленный компьютер о повторной отправке отброшенных пакетов. Обратите внимание, что стек TCP может отбрасывать последующие пакеты по мере необходимости, пока не будет возобновлена ​​первоначально ожидаемая последовательность, поскольку требуется доставлять данные полезной нагрузки в ваше приложение в точном порядке, в котором они были отправлены (т. Е. Это не так. разрешено доставлять «более поздние» байты до «более ранних» байтов, даже если некоторые из «более ранних» байтов были потеряны и должны были быть повторно переданы).

0 голосов
/ 01 мая 2018

Откуда ответ получает данные, кеш из ОС? Я не изучал операционные системы, что затрудняет мне комплексный процесс буферизации.

Может быть, а может и нет, вам все равно, как пользователь этой функции. Все это гарантируется протоколом сокета TCP . Однако, если вы забудете прочитать сокет, данные сокета будут заполнены. Существует ограничение на количество данных, которые вы можете поставить в очередь.

Кроме того, теоретически TCP будет проверять потери при передаче, где это происходит? Когда я выполнял программирование сокетов, я не видел никаких обработчиков, касающихся потери передачи, автоматически ли это обрабатывается сокетом?

Да. Тебе не нужно беспокоиться об этом. Красиво, не правда ли?


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

// not necessary as you should only read the bytes affected by recv()
// memset(response, 0, sizeof(response));
// should declare total and received here
size_t total = sizeof(response) - 1;
size_t received = 0;
while (received < total) {
  // should declare byte only here
  ssize_t bytes = recv(sockfd, response + received, total - received, 0);
  if (bytes < 0)
    error("ERROR reading response from socket");
  if (bytes == 0)
    break;
  received += (size_t)bytes;
}
// as you want read a string don't forget
response[received] = '\0';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...