Я работаю над надежной программой передачи файлов, которая использует UDP. (за курс по компьютерным сетям.)
У меня такой вопрос - ну, рассмотрим такой сценарий:
Отправитель имеет (например) 12 байтов данных для отправки. Таким образом, отправитель выполняет этот вызов:
sendto(fd, &buf, 12, 0, (struct sockaddr *)&cliaddr,sizeof(cliaddr));
Это отправляет 12 байтов данных ненадежным способом. Первые 4 байта этих данных являются полем «длина сообщения». В этом случае первые 4 байта могут иметь значение 0x0000000C
Получатель хочет прочитать первые 4 байта, используя recvfrom (). Видя, что размер сегмента составляет 12 байтов, он хочет прочитать оставшиеся 8 байтов. Таким образом, получатель может выглядеть так:
/* read the segment size */
recvfrom(sockfd,&buf,4,0,(struct sockaddr *)&cliaddr,&len);
/* do some arithmetic, use bzero(), etc */
/* read the rest of the data */
recvfrom(sockfd,&buf,8,0,(struct sockaddr *)&cliaddr,&len);
Когда я выполняю этот код, я могу получить первые 4 байта без проблем. Но когда я пытаюсь получить оставшиеся данные, эти данные, похоже, теряются. В моем выводе я получаю мусор - похоже, что некоторая часть следующих 12 байтов отправителя отправлена () - ing.
Это ожидаемое поведение? То есть, если один вызов recvfrom () не читает все отправленные данные, разве не гарантируется, что эти данные (оставшиеся 8 байтов) мне доступны?
Кажется, что стандартный метод отправки заголовка сегмента (включая его размер), за которым следует полезная нагрузка, не работает. Означает ли это, что мне нужно отправить 2 отдельных сегмента - один, содержащий только информацию заголовка, а затем второй сегмент с полезной нагрузкой? Или я просто неправильно использую эти системные вызовы (или я пропускаю флаг или setsockopt ()?)