Двухсторонний UDP-клиент и сервер?

#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 (что он уже делает) достаточно.