table of contents
UDP(7) | Podręcznik programisty Linuksa | UDP(7) |
NAZWA¶
udp - protokół datagramów użytkownika dla IPv4
SKŁADNIA¶
#include <sys/socket.h>
#include <netinet/in.h>
udp_socket = socket(PF_INET, SOCK_DGRAM, 0);
OPIS¶
Jest to implementacja opisanego w RFC768 protokołu datagramów użytkownika. Implementuje ona usługę bezpołączeniowych, niepewnych pakietów datagramowych. Kolejność pakietów może ulec zmianie przed ich dotarciem do celu, mogą one też zostać powielone. UDP generuje i sprawdza sumy kontrolne, aby wykryć błędy transmisji.
Podczas tworzenia gniazda UDP, jego adresy: lokalny i zdalny są nieokreślone. Datagramy można wysyłać natychmiast za pomocą sendto(2) lub sendmsg(2) podając jako argument prawidłowy adres docelowy. Gdy dla gniazda jest wywołane connect(2), ustawiany jest domyślny adres docelowy i od tego momentu można wysyłać datagramy za pomocą send(2) lub write(2) nie podając adresu docelowego. Nadal możliwe jest wysyłanie do innych adresów docelowych podając adres funkcji sendto(2) lub sendmsg(2). Aby odbierać pakiety, gniazdo może zostać najpierw przypisane do adresu lokalnego za pomocą bind(2). W przeciwnym przypadku, warstwa gniazd automatycznie przypisze wolny port lokalny spoza zakresu zdefiniowanego przez net.ipv4.ip_local_port_range i przypisze gniazdo do INADDR_ANY.
Wszystkie operacje odbioru zwracają tylko jeden pakiet. Gdy pakiet jest mniejszy niż przekazany bufor, zwracane są tylko dane o rozmiarze pakietu, gdy pakiet jest większy niż bufor, pakiet jest obcinany i ustawiany jest znacznik MSG_TRUNC. MSG_WAITALL nie jest wspierane.
Opcje IP mogą być wysyłane lub odbierane za pomocą opcji gniazda opisanych w ip(7). Są one przetwarzane przez jądro tylko wtedy, gdy włączona jest odpowiednia kontrolka wejścia/wyjścia (ale nadal są przekazywane do programu użytkownika, nawet gdy kontrolka jest wyłączona). Zobacz ip(7).
Gdy przy wysyłaniu ustawiony jest znacznik MSG_DONTROUTE, adres docelowy musi odnosić się do lokalnego adresu interfejsu i pakiet jest wysyłany jedynie do tego interfejsu.
UDP rozczłonkowuje pakiet, gdy jego całkowity rozmiar przekracza wartość MTU (Maximum Transmission Unit) dla interfejsu. Bardziej przyjazną dla sieci alternatywą jest korzystanie z badania MTU ścieżki, jak opisano w rozdziale IP_PMTU_DISCOVER ip(7).
FORMAT ADDRESU¶
UDP stosuje format adresu IPv4 sockaddr_in opisany w ip(7).
OBSŁUGA BŁĘDÓW¶
Wszystkie błędy krytyczne są przekazywane do programu użytkownika jako wartość zwracana, nawet gdy gniazdo nie jest połączone. Dotyczy to także błędów asynchronicznych otrzymywanych z sieci. Można też otrzymać błąd dotyczący pakietu wcześniej wysłanego z danego gniazda. To zachowanie różni się od wielu innych implementacji gniazd BSD, które nie przekazują żadnych błędów, gdy gniazdo nie jest połączone. Zachowanie Linuksa ma oparcie w RFC1122.
Dla zgodności z kodem odziedziczonym możliwe jest ustawienie opcji SOL_SOCKET SO_BSDCOMPAT, aby otrzymywać błędy zdalne tylko wtedy, gdy gniazdo jest połączone (z wyjątkiem EPROTO i EMSGSIZE). Jednak zamiast włączać tę opcję lepiej poprawić kod tak, by obsługiwał prawidłowo błędy. Błędy wygenerowane lokalnie są zawsze przekazywane.
Gdy włączona jest opcja IP_RECVERR, wszystkie błędy są przechowywane w kolejce błędów gniazda i mogą być odczytywane za pomocą recvmsg(2) z ustawionym znacznikiem MSG_ERRQUEUE.
IOCTL¶
Do poniższych kontrolek wejścia/wyjścia można uzyskać dostęp za pomocą funkcji ioctl(2). Prawidłowa składnia to:
int value; error = ioctl(tcp_socket, ioctl_type, &value);
- SIOCINQ
- Pobiera wskaźnik do argumentu całkowitego. Zwraca rozmiar następnego oczekującego datagramu w podanej liczbie bajtów lub 0, gdy nie czeka żaden pakiet.
- SIOCOUTQ
- Zwraca liczbę bajtów danych w lokalnej kolejce pakietów wychodzących. Wspierane przez Linuksa 2.4 i późniejsze wersje.
Ponadto wspierane są wszystkie kontrolki wejścia/wyjścia opisane w ip(7) i socket(7).
BŁĘDY¶
Przy wysyłaniu lub odbieraniu za poiśrednictwem gniazd UDP mogą wystąpić wszyskie błędy zdefiniowane dla socket(7) lub ip(7).
ECONNREFUSED Z adresem docelowym nie był skojarzony żaden odbiorca. Może to być spowodowane przez uprzednie wysłanie pakietu za pośrednictwem danego gniazda.
WERSJE¶
IP_RECVERR pojawiło się w Linuksie 2.2.
PODZIĘKOWANIA¶
Tę strone podręcznika napisał Andi Kleen.
ZOBACZ TAKŻE¶
RFC768 dla protokołu datagramów użytkownika.
RFC1122 dla wymagań hostów.
RFC1191 dla opisu badania MTU ścieżki.
1998-10-02 | Linux |