Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Сало залік.docx
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
133 Кб
Скачать
☆

55. Обмін дата грамами

Як вже говорилося , датаграми використовуються в програмах досить рідко. У більшості випадків надійність передачі критична для програми, і замість винаходу власного надійного протоколу поверх UDP програмісти воліють використовувати TCP. Тим не менш, іноді датаграми виявляються корисні . Наприклад , їх зручно використовувати при транслюванні звуку або відео по мережі в реальному часі , особливо при широкомовному транслюванні .

Оскільки для обміну датаграму не потрібно встановлювати з'єднання , використовувати їх набагато простіше. Створивши сокет за допомогою socket і bind , ви можете тут же використовувати його для відправлення або отримання даних. Для цього вам знадобляться функції sendto і recvfrom .

int sendto ( int sockfd , const void * msg , int len ​​, unsigned int flags ,

               const struct sockaddr * to , int tolen ) ;

int recvfrom ( int sockfd , void * buf , int len ​​, unsigned int flags ,

                 struct sockaddr * from , int * fromlen ) ;

Функція sendto дуже схожа на send . Два додаткових параметра to і tolen використовуються для вказівки адреси одержувача . Для завдання адреси використовується структура sockaddr , як і у випадку з функцією connect . Функція recvfrom працює аналогічно recv . Отримавши чергове повідомлення , вона записує його адресу в структуру , на яку посилається from , а записане кількість байт - в змінну , адресуемую покажчиком fromlen . Як ми знаємо , аналогічним чином працює функція accept .

Деяку плутанину вносять приєднані датаграмною сокети ( connected datagram sockets ) . Справа в тому , що для сокета з типом SOCK_DGRAM теж можна викликати функцію connect , а потім використовувати send і recv для обміну даними. Потрібно розуміти , що ніякого з'єднання при цьому не встановлюється. Операційна система просто запам'ятовує адресу , який ви передали функції connect , а потім використовує його при відправці даних. Зверніть увагу , що приєднаний сокет може отримувати дані тільки від сокета , з яким він з'єднаний .

Для ілюстрації процесу обміну датаграму я написав дві невеликі програми - sender (лістинг 3 ) і receiver (лістинг 4 ) . Перша відправляє повідомлення " Hello there ! " і " Bye bye ! " , а другий отримує їх і друкує на екрані. Програма sender демонструє застосування як звичайного , так і приєднаного сокета , а receiver використовує звичайний .

Листинг 3. Программа sender.

#include <sys/types.h>

#include <sys/socket.h>

#include <netinet/in.h>

char msg1[] = "Hello there!\n";

char msg2[] = "Bye bye!\n";

int main()

{

int sock;

struct sockaddr_in addr;

sock = socket(AF_INET, SOCK_DGRAM, 0);

if(sock < 0)

{

perror("socket");

exit(1);

}

addr.sin_family = AF_INET;

addr.sin_port = htons(3425);

addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

sendto(sock, msg1, sizeof(msg1), 0,

(struct sockaddr *)&addr, sizeof(addr));

connect(sock, (struct sockaddr *)&addr, sizeof(addr));

send(sock, msg2, sizeof(msg2), 0);

close(sock);

return 0;

}