przejście do zawartości
Jan Kończak
Narzędzia użytkownika
Zaloguj
Narzędzia witryny
Narzędzia
Pokaż stronę
Poprzednie wersje
Odnośniki
Ostatnie zmiany
Menadżer multimediów
Indeks
Zaloguj
Ostatnie zmiany
Menadżer multimediów
Indeks
Jesteś tutaj:
start
»
sk2
»
sockets_caveats
sk2:sockets_caveats
Ta strona jest tylko do odczytu. Możesz wyświetlić źródła tej strony ale nie możesz ich zmienić.
====== Interface gniazd BSD (2/2) ====== ===== Kody źródłowe do zadań ===== Z doświadczeń lat ubiegłych wynika, że sprawne pisanie prostych programów stanowi problem dla części uczestników zajęć. Stąd w trakcie tych zajęć proszę korzystać z gotowych kodów źródłowych, analizując je przez uruchomieniem: **{{:sk2:l3.tar.xz|Kody źródłowe zadań 1-9,12}}** <html><small></html>Aby zbudować programy ręcznie, wykonaj:<code>mkdir build cd build cmake .. make</code> <html></small></html> Programy serwera i klienta można uruchamiać na jednym komputerze, łącząc się z klienta na adres 127.0.0.1 lub localhost. ===== Read i Write - ilość odczytanych / zapisanych danych ===== Polecenie ''read'', ''recv'',… często zwracają mniej danych niż podana w argumentach wielkość bufora. Powód? Mniej danych przyszło lub skończyło się miejsce w buforze odbiorczym (''setsockopt(socket, SOL_SOCKET, SO_RCVBUF, …)''). Polecenia ''write'', ''send'',… może też zwrócić w pewnych okolicznościach mniejszy rozmiar wysłanych danych niż podany rozmiar buforu. Jest to spowodowane zapchaniem systemowego buforu wysyłania (czyli jeśli dane są dostarczane do wysłania szybciej niż można je wysyłać). Normalnie funkcje zapisujące blokują się do momentu aż w buforze będzie dość miejsca. Jeśli jednak ustawi się opcję ''O_NONBLOCK'' (typowa w wielu zastosowaniach), to funkcje takie jak ''write'', ''send'', … zapiszą tylko część danych. Dlatego zarówno przy odbieraniu jak i wysyłaniu trzeba zwracać uwagę na zwracaną ilość przetworzonych danych. //Zadanie 1.// Stwórz serwer TCP, który w pętli akceptuje nowe połączenia i je ignoruje (tzn. nie odbiera ani nie wysyła danych, nie zamyka połączeń). //Zadanie 2.// Stwórz klienta TCP który: * łączy się pod podany adres * w pętli: * wysyła dane * wypisuje kolejny numer i ilość wysłanych danych Połącz klienta do serwera z zadania 1. <html><small></html> Możesz sprawdzić poleceniem ''netstat'', np. ''netstat -tn'', ile bajtów jest w buforze odbiorczym/nadawczym (Recv-Q i Send-Q) <html></small></html> //Zadanie 3.// Stwórz klienta TCP który: * łączy się pod podany adres * ustawia tryb nieblokujący (gotowy kod: ''fcntl(sockFd, F_SETFL, O_NONBLOCK, 1);'' ) * w pętli: * wysyła dane * wypisuje kolejny numer i ilość wysłanych danych * jeśli wysłał mniej danych niż chciał, kończy się Połącz klienta do serwera z zadania 1.((W tym zadaniu waro porównac wynik dla klienta z lokalnego komputera i ze zdalnego komputera)) ==== Protokół strumieniowy / zorientowany na wiadomość ==== //Zadanie 4.// Napisz serwer TCP który po odebraniu połączenia, do jego zamknięcia, wykonuje w pętli: * odbiera do 10 bajtów * wypisuje ile bajtów odebrał i co odebrał //Zadanie 5a.// Napisz klienta TCP który wysyła cały alfabet po jednej literze. Podłącz się (wielokrotnie) do serwera z zadania 4. \\ //Zadanie 5b.// Napisz klienta TCP który wysyła wielokrotnie((20-50 razy)) po kilkanaście liter. Podłącz się (wielokrotnie) do serwera z zadania 4. \\ <html><small></html>(W zadaniach 5a i 5b łącz się do swojego komputera.)<html></small></html> //Zadanie 6.// Powtórz zadanie 4 dla UDP. //Zadanie 7.// Powtórz zadanie 5a i 5b dla UDP. //Zadanie 8.// Jak w strumieniu danych – czyli w połączeniu TCP – przesyłać dane tak by serwer wiedział kiedy cała wiadomość dotrze? //Zadanie 9.// Jak w protokole UDP zapewnić, że cała wiadomość została odebrana? ===== 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'': <code> tc qdisc add dev lo root netem delay 5ms 5ms distribution normal loss 10% </code> Aby przywrócić domyślne zachowanie, wpisz: <code> tc qdisc del root dev lo </code> //Zadanie 11.// Uruchom ponownie programy z zadań 5 i 7. //Zadanie 12.// Przygotuj program, który wyśle 1000 pakietów UDP zawierających kolejne liczby. //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: <code> tc qdisc add dev lo root tbf rate 10kbps burst 1.5kb limit 10kb </code> //Zadanie 14.// Jak w protokole UDP radzić sobie z kolejnością pakietów? Jak radzić sobie ze zgubieniem pakietów? ===== Opcje gniazd ===== Funkcja ''setsockopt'' pozwala dostosować zachowanie gniazd do potrzeb programisty. Bliźniacze ''getsockopt'' pozwala na odczyt opcji gniazd. \\ Podobnie jak np. ''ioctl'', funkcja ''setsockopt'' pozwala zmieniać zachowanie na wielu poziomach (np. gniazda / protokołu warstwy sieci / protokołu warstwy transportu). Drugi argument to właśnie wybór poziomu, trzeci - wybór opcji, czwarty to wartość opcji. \\ Parametry (opcje) które można ustawić są opisane w rozdziale 7 podręcznika systemowego. Poniżej lista najważniejszych: * Ogólne opcje (''man 7 socket'', poziom ''SOL_SOCKET''): * ''SO_BROADCAST'' – wymagane do UDP broadcastu * ''SO_KEEPALIVE'' – włącza mechanizm TCP keepalive [[http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html]] * ''SO_LINGER'' – pozwala przed zamknięciem gniazda wysłać zakolejkowane dane * ''SO_RCVBUF'' i ''SO_SNDBUF'' – ustawienie rozmiaru systemowych buforów odbiorczych / nadawczych * ''SO_REUSEADDR'' – pozwala ignorować połączenia w stanie TIME_WAIT przy ustalaniu lokalnego adresu gniazda (wywoływaniu bind) [[https://tools.ietf.org/html/rfc793#page-22]] * Opcje protokołu IP (''man 7 ip'', poziom ''IPPROTO_IP''): * ''IP_ADD_MEMBERSHIP'' oraz ''IP_DROP_MEMBERSHIP'' – pozwala dodać siebie do grupy multicastowej * Opcje protokołu TCP (''man 7 tcp'', poziom ''IPPROTO_TCP''): * ''TCP_NODELAY'' – wyłącza algorytm Nagle'a (wyłącza buforowanie wyjścia jeśli danych jest mało a poprzednie nie zostały potwierdzone) 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''.)
sk2/sockets_caveats.1571141210.txt.gz
· ostatnio zmienione: 2019/10/15 14:06 przez
jkonczak
Narzędzia strony
Pokaż stronę
Poprzednie wersje
Odnośniki
Złóż / rozłóż wszystko
Do góry