Różnice między wybraną wersją a wersją aktualną.
Both sides previous revision Poprzednia wersja Nowa wersja | Poprzednia wersja | ||
sk2:sockets_caveats [2023/10/17 12:20] jkonczak [Funkcje blokujące / nieblokujące] |
sk2:sockets_caveats [2023/10/17 12:45] (aktualna) jkonczak [Opcje gniazd] |
||
---|---|---|---|
Linia 47: | Linia 47: | ||
Można zmienić domyśle blokujące zachowanie przestawiając gniazdo w //tryb nieblokujący//. | Można zmienić domyśle blokujące zachowanie przestawiając gniazdo w //tryb nieblokujący//. | ||
- | Jeśli wykonanie żądanej funkcji na gnieździe w trybie nieblokującym nie jest możliwe bez czekania, to wykonanie funkcji nie powodzi się (zwracany jest wynik ''-1'') a zmienna ''errno'' jest ustawiana na ''EAGAIN'' lub ''EWOULDBLOCK''((Wyjątkiem jest funkcja ''connect'', która rozpoczyna nawiązywanie połączenia w tle, zwraca ''-1'' i ustawia ''errno'' na ''EINPROGRESS''.)). Gniazdo przestawia się w tryb nieblokujący podobnie jak każdy inny deskryptor pliku:<code cpp>fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK)</code> | + | Jeśli wykonanie żądanej funkcji na gnieździe w trybie nieblokującym nie jest możliwe bez czekania, to wykonanie funkcji nie powodzi się (zwracany jest wynik ''-1'') a zmienna ''errno'' jest ustawiana na ''EAGAIN'' lub ''EWOULDBLOCK''((Wyjątkiem jest funkcja ''connect'', która rozpoczyna nawiązywanie połączenia w tle, zwraca ''-1'' i ustawia ''errno'' na ''EINPROGRESS''.)). \\ Gniazdo przestawia się w tryb nieblokujący podobnie jak każdy inny deskryptor pliku: |
- | Niektóre funkcje sieciowe (np. ''recv'', ''send'') pozwalają na ustawienie w polu flag wartości ''MSG_DONTWAIT'', która wykonuje żądaną operację w trybie nieblokującym niezależnie od tego w jakim trybie pracuje gniazdo:<code cpp>recv(fileDescriptor, buff, buffSize, MSG_DONTWAIT);</code> | + | <html><div style="margin:-1.4em 0 -1.4em 0"></html> |
+ | <code cpp>fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK)</code> | ||
+ | <html></div></html> | ||
+ | Niektóre funkcje sieciowe (np. ''recv'', ''send'') pozwalają na ustawienie w polu flag wartości ''MSG_DONTWAIT'', która wykonuje żądaną operację w trybie nieblokującym niezależnie od tego w jakim trybie pracuje gniazdo: | ||
+ | <html><div style="margin-top:-1.4em"></html> | ||
+ | <code cpp>recv(fileDescriptor, buff, buffSize, MSG_DONTWAIT);</code> | ||
+ | <html></div></html> | ||
+ | Uwaga: w BSD/POSIX socket API każde nowo utworzone gniazdo działa w trybie blokującym, nawet jeżeli gniazdo zostało utworzone w wyniku działania funkcji ''accept'' na nasłuchującym gnieździe działającym w trybie nieblokującym. | ||
+ | <small> | ||
+ | W Linuksie można ustawiać tryb nieblokujący wykorzystując też niebędące częścią standardu POSIX rozszerzenia: 1) jeżeli ostatni argument funkcji ''socket'' będzie zsumowany z ''SOCK_NONBLOCK'', to nowo stworzone gniazdo będzie w trybie nieblokującym (''[[https://man7.org/linux/man-pages/man2/socket.2.html|man 2 socket]]''), 2) jeżeli zamiast funkcji ''accept'' wykorzysta się odpowiednik tej funkcji rozszerzony o pole flag – ''accept4'' – i poda flagę ''SOCK_NONBLOCK'' (''[[https://man7.org/linux/man-pages/man2/accept4.2.html|man 2 accept4]]'') | ||
+ | </small> | ||
==== Zadania ===== | ==== Zadania ===== | ||
Linia 94: | Linia 104: | ||
===== Kolejność danych i (nie)zawodność ===== | ===== Kolejność danych i (nie)zawodność ===== | ||
//Zadanie 10.// Wykonaj z roota poniższe polecenie, które spowoduje pomieszanie kolejności pakietów wysłanych przez interfejs ''lo'': | //Zadanie 10.// Wykonaj z roota poniższe polecenie, które spowoduje pomieszanie kolejności pakietów wysłanych przez interfejs ''lo'': | ||
+ | <html><div style="margin-top:-1.4em"></html> | ||
<code> | <code> | ||
tc qdisc add dev lo root netem delay 5ms 5ms distribution normal loss 10% | tc qdisc add dev lo root netem delay 5ms 5ms distribution normal loss 10% | ||
</code> | </code> | ||
+ | <html></div></html> | ||
- | Aby przywrócić domyślne zachowanie, wpisz: | + | Aby przywrócić domyślne zachowanie po wykonaniu ćwiczeń, możesz wpisać: |
+ | <html><div style="margin-top:-1.4em"></html> | ||
<code> | <code> | ||
tc qdisc del root dev lo | tc qdisc del root dev lo | ||
</code> | </code> | ||
+ | <html></div></html> | ||
//Zadanie 11.// Uruchom ponownie programy z zadań 5 i 7. | //Zadanie 11.// Uruchom ponownie programy z zadań 5 i 7. | ||
Linia 108: | Linia 122: | ||
//Zadanie 13.// Wykonaj z roota poniższe polecenie, które spowoduje ograniczenie prędkości wysyłania pakietów i przetestuj program z poprzedniego zadania: | //Zadanie 13.// Wykonaj z roota poniższe polecenie, które spowoduje ograniczenie prędkości wysyłania pakietów i przetestuj program z poprzedniego zadania: | ||
+ | <html><div style="margin-top:-1.4em"></html> | ||
<code> | <code> | ||
tc qdisc add dev lo root tbf rate 10kbps burst 1.5kb limit 10kb | tc qdisc add dev lo root tbf rate 10kbps burst 1.5kb limit 10kb | ||
</code> | </code> | ||
+ | <html></div></html> | ||
<html><small></html> | <html><small></html> | ||
Linia 153: | Linia 169: | ||
</code>++++ | </code>++++ | ||
- | Funkcja ''fcntl'' (''man fcntl open'') pozwala na ustawienie (''F_SETFL'') opcji ''O_NONBLOCK'' potrzebnej do nieblokującej obsługi gniazd. (''O_NONBLOCK'' można też ustawić sumując ostatni argument funkcji ''socket'' z ''SOCK_NONBLOCK''.) | + | Funkcja ''fcntl'' (''man fcntl open'') pozwala na ustawienie (''F_SETFL'') opcji ''O_NONBLOCK'' potrzebnej do nieblokującej obsługi gniazd. |