Dydaktyka:
FeedbackProtokół UDP jest obok protokołu TCP drugim powszechnie używanym protokołem warstwy transportu.
Inaczej niż TCP, protokół UDP nie nawiązuje połączeń.
W TCP między dwoma końcami połączenia jest przesyłany strumień bajtów.
UDP zamiast tego przesyła wiadomości – datagramy, na które składa się
informacja o nadawcy i odbiorcy oraz treść.
To pozwala na komunikację z wieloma osobami używając jednego gniazda,
a granice logicznych komunikatów są określone.
Protokół TCP numeruje przesyłane bajty i potwierdza odbiór danych, co pozwala zachować ich kolejność, zadbać o ich kompletność i wysyłać dane z optymalną prędkością. Protokół UDP nie daje żadnej z tych gwarancji.
Zadanie 1 Większość ruchu w Internecie korzysta z TCP. Zastanów się, dlaczego:
Tworząc gniazdo UDP należy użyć następujących argumentów: (przykład dla IPv4)
..... = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); // lub: socket(PF_INET, SOCK_DGRAM, 0)
Jeżeli gniazdo ma pełnić rolę serwera, to trzeba wykonać na nim funkcję bind
do wybrania lokalnego numer portu.
UDP nie nawiązuje połączeń, więc na gnieździe od razu można wykonywać operacje
odbioru i wysyłania danych.
Przez to, że UDP nie nawiązuje połączenia, do odbioru i wysyłania wiadomości
należy używać funkcji sendto i recvfrom – te funkcje w argumentach
przekazują adresu odbiorcy/nadawcy.
Do odbioru danych można użyć też funkcji read i recv, ale wtedy
programista nie dowie się skąd przyszła wiadomość.
Przykład użycia funkcji sendto i recvfrom:
sockaddr_in dstAddr {...}; recvCnt = sendto(sock, "msg", 3, 0, (sockaddr*) &dstAddr, sizeof(dstAddr)); // \arg. jak w send/ \wskazanie dokąd wysłać wiadomość /
sockaddr_in srcAddr; socklen_t srcAddrLen = sizeof(srcAddr); sendCnt = recvfrom(sock, buf, 16, 0, (sockaddr*) &srcAddr, &srcAddrLen ); // \arg. jak w recv/ \ gdzie wpisać adres nadawcy /
O tym, czy gniazdo UDP pełni rolę klienta czy serwera decyduje właściwie to, czy dane są najpierw wysyłane, czy odbierane z ustalonego portu.
W formie ułatwienia BSD socket API pozwala działać gniazdom UDP w trybie
pseudo-połączeniowym - tzn. można wywołać funkcję connect (która ustali
adres odbiorcy) i dalej korzystać z send / write. Więcej możesz doczytać
tutaj.
UDP jest zorientowane na wiadomość – wysyła i odbiera całe datagramy. Jeśli funkcja odbierająca dane zadeklaruje mniejszy bufor niż rozmiar wiadomości, nadmiarowe dane zostaną odrzucone.
W związku z brakiem połączeń, nie da się na gnieździe UDP wykonać funkcji
shutdown zamykającej połączenie.
Zadanie 2 Napisz program, który korzystając z protokołu UDP wyśle dane (stały ciąg znaków) pod wskazany adres, następnie odbierze dane i się zakończy.
Zadanie 3 Napisz program, który korzystając z protokołu UDP odbierze dane
i odeśle je pod adres nadawcy zmieniając wielkość liter.
Małe litery można zmienić na wielkie używając:
for(int i = 0; i < count; ++i) buf[i] = toupper(buf[i]);
Funkcja toupper jest w bibliotece ctype.h.
Zadanie 4 Napisz program, który będzie w pętli odbierać dane i odsyłać je pod adresy wszystkich wcześniejszych nadawców.