#c #sockets #networking #udp #posix
#c #сокеты #сеть #udp #posix
Вопрос:
Я пытаюсь реализовать базовый протокол передачи файлов, используя UDP. Я использую руководство Beej в качестве ссылки, и большая часть кода, который я опубликую, взята оттуда.
В моей программе до сих пор «говорящий» отправляет имя файла, который он хочет, «получателю».
Оттуда получатель проверяет, существует ли файл, и если да, он определяет размер файла.
Теперь вот где я сталкиваюсь с проблемами. Мне нужно, чтобы получатель отправил размер файла говорящему. Вы можете увидеть в моем коде (ссылки ниже), как я это реализовал. Однако говорящий просто зависает, как будто он все еще ожидает отправки чего-либо.
Это заставляет меня думать, что получателю нужен какой-то дополнительный код, позволяющий ему обмениваться данными с говорящим, а не просто получать от него данные (я привык к TCP, поэтому извините за недостаток знаний).
Может кто-нибудь сказать мне, какой код мне не хватает, или я неправильно использую функции? Трудно следовать руководству Beej, и он не приводит пример двусторонней связи.
Спасибо, и дайте мне знать, если вам понадобится дополнительная информация.
Слушатель: http://pastebin.com/UL1xjDnP
Говорящий: http://pastebin.com/B2zrXPgZ
РЕДАКТИРОВАТЬ: решено! Благодаря cnicutar,
Я обращался к серверу в этом коде, когда я должен был обратиться к клиенту
if ((numbytes = sendto(sockfd,buffer,strlen(buffer), 0,
p->ai_addr, p->ai_addrlen)) == -1)
что следует изменить на
if ((numbytes = sendto(sockfd,buffer,strlen(buffer), 0,
(struct sockaddr *)amp;their_addr, amp;addr_len)) == -1)
Комментарии:
1. Является ли «слушатель» сообщением «слушатель: размер файла был отправлен»?
2. Мне интересно, почему UDP? TCP — гораздо лучший протокол для передачи файлов. UDP не предлагает таких преимуществ, как последовательная доставка, повторная отправка поврежденных данных и т. Д., Что является ключевым при передаче файлов.
3. Да, прослушиватель сообщает, что размер файла был отправлен. Также я хочу изучить UDP, я думаю, что полезно знать оба.
4. @user974703 Я ответил ниже. Кроме того, отредактируйте свой вопрос и добавьте соответствующий код.
Ответ №1:
Вы отправляете не тому узлу. Вы получаете p
от getaddrinfo
, а затем отправляете ему. Итак, вы отправляете сообщение самому себе.
for(p = servinfo; p != NULL; p = p->ai_next)
/* .... */
numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0,
(struct sockaddr *)amp;their_addr, amp;addr_len)) == -1)
/* .... */
if ((numbytes = sendto(sockfd,buffer,strlen(buffer), 0,
p->ai_addr, p->ai_addrlen)) == -1)
Вероятно, вы хотите отправить его «им»:
if ((numbytes = sendto(sockfd,buffer,strlen(buffer), 0,
(struct sockaddr *)amp;their_addr, amp;addr_len)) == -1)
Комментарии:
1. бинго! в этом и заключалась проблема. Единственное, что я сейчас замечаю, это то, что последнее письмо, которое выводит говорящий (от размера файла), — это мусор. Я предполагаю, что это потому, что в конце строки, которую я отправлял, нет n?
2. @user974703 Вы, вероятно, хотите
что-то установить.
Ответ №2:
Самое простое решение — заставить вашего «отправителя» прослушивать тот же порт / ip, который он использует для отправки пакетов на сервер. Сервер может извлекать исходный ip / порт из заголовков пакетов и отправлять туда свои ответы. Если вам нужно использовать разные порты / IP-адреса для ответов, тогда ваш «отправитель» должен будет включить эту информацию в то, что он отправляет. например, «вот ваша информация, отправляйте ответы на x.x.x.x: гггг»
Комментарии:
1. Ему не нужно слушать.
recvfrom
(что он уже делает) достаточно.