Narzędzia użytkownika

Narzędzia witryny


sk2:sockets_full

Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

Both sides previous revision Poprzednia wersja
Nowa wersja
Poprzednia wersja
sk2:sockets_full [2019/10/14 21:00]
jkonczak [Interface gniazd BSD (1/2)]
sk2:sockets_full [2022/10/10 19:19] (aktualna)
jkonczak [Serwer TCP]
Linia 7: Linia 7:
  
 Gniazdo nasłuchujące tworzy się wywołując po stworzeniu gniazda (''​socket(…)''​) funkcję ''​listen(…)'',​ ale: jeśli wcześniej nie ustawi się adresu gniazda, system operacyjny wylosuje efemeryczny port i rozpocznie nasłuch na dowolnym adresie IP na tym porcie.\\ Gniazdo nasłuchujące tworzy się wywołując po stworzeniu gniazda (''​socket(…)''​) funkcję ''​listen(…)'',​ ale: jeśli wcześniej nie ustawi się adresu gniazda, system operacyjny wylosuje efemeryczny port i rozpocznie nasłuch na dowolnym adresie IP na tym porcie.\\
-Dlatego przed funkcją ''​listen(…)''​ **należy funkcją ''​bind(…)''​ ustawić lokalny ​adresu ​gniazda**. Funkcja ''​bind''​ przyjmuje jako argument strukturę ''​sockaddr''​.+Dlatego przed funkcją ''​listen(…)''​ **należy funkcją ''​bind(…)''​ ustawić lokalny ​adres gniazda**. Funkcja ''​bind''​ przyjmuje jako argument strukturę ''​sockaddr''​.
  
 **Lokalny adres IP nasłuchującego gniazda zwykle ustawia się na ustawić na dowolny – ''​INADDR_ANY''​**. Inny lokalny adres IP ustawia się, jeśli gniazdo ma odbierać połączenia kierowane tylko na ten adres – np. 127.0.0.1 (''​INADDR_LOOPBACK''​) jeśli połączenia mają być ograniczone do połączeń z localhosta. **Lokalny adres IP nasłuchującego gniazda zwykle ustawia się na ustawić na dowolny – ''​INADDR_ANY''​**. Inny lokalny adres IP ustawia się, jeśli gniazdo ma odbierać połączenia kierowane tylko na ten adres – np. 127.0.0.1 (''​INADDR_LOOPBACK''​) jeśli połączenia mają być ograniczone do połączeń z localhosta.
  
 **Wywołanie funkcji ''​listen''​ nakazuje systemowi operacyjnemu czekać na połączenia** (porównaj z: ''​connect''​). Wykonanie funkcji listen jest natychmiastowe – ta funkcja nie czeka na połączenie,​ tylko informuje system operacyjny że nowe połączenia przychodzące na ustawiony adres mają być kierowane na to gniazdo. \\ **Wywołanie funkcji ''​listen''​ nakazuje systemowi operacyjnemu czekać na połączenia** (porównaj z: ''​connect''​). Wykonanie funkcji listen jest natychmiastowe – ta funkcja nie czeka na połączenie,​ tylko informuje system operacyjny że nowe połączenia przychodzące na ustawiony adres mają być kierowane na to gniazdo. \\
-Argumentem funkcji ''​listen''​ jest ilość nowych połączeń które czekają w kolejce na odebranie (tj. połączeń dla których nie wykonano jeszcze funkcji ''​accept''​).+Argumentem funkcji ''​listen''​ jest ilość nowych połączeń które czekają w kolejce na odebranie (tj. połączeń dla których nie wykonano jeszcze funkcji ''​accept''​)((Argument "​backlog"​ funkcji ''​listen''​ powinien się zawierać w zakresie ''​1''​÷''​SOMAXCONN''​ (w tej chwili równe 128 w Linuksie) i jest traktowany jako podpowiedź,​ tzn. system operacyjny może używać innego limitu niż podany w argumencie ''​listen''​.)).
  
 Do odebrania nowych połączeń używa się funkcji ''​accept(…)''​. **Funkcja ''​accept''​ zwraca nowe gniazdo** reprezentujące nawiązane połączenie. Do odebrania nowych połączeń używa się funkcji ''​accept(…)''​. **Funkcja ''​accept''​ zwraca nowe gniazdo** reprezentujące nawiązane połączenie.
 +
 +<​html><​small></​html>​Tworzenie kolejnych deskryptorów plików oraz wyniki ''​lsof'',​ ''​strace''​ i ''​ss''​ są zaprezentowane [[sk2:​sockets_full:​tcp_srv_img|tutaj]]<​html></​small></​html>​
  
 //Zadanie 1:// Napisz program, który: //Zadanie 1:// Napisz program, który:
Linia 25: Linia 27:
   * zakończy program.   * zakończy program.
  
-//Zadanie 2a:// Krótko((https://​github.com/​torvalds/​linux/​search?​q=TCP_TIMEWAIT_LEN)) po zamknięciu programu serwera sprawdź poleceniem ''​netstat -tpn''​ w jakim stanie jest połączenie. Przypomnij sobie co oznacza ten stan - [[https://​tools.ietf.org/​html/​rfc793#​page-22|RFC793]]. Spróbuj w tym czasie uruchomić ponownie program serwera. \\ //Zadanie 2b:// Ustaw przed wywołaniem ''​bind''​ opcję ''​SO_REUSEADDR''​ gniazda (kod poniżej) i powtórz zadanie 2a.<code cpp>​const int one = 1;+//Zadanie 2a:// Krótko((https://​github.com/​torvalds/​linux/​search?​q=TCP_TIMEWAIT_LEN)) po zamknięciu programu serwera sprawdź poleceniem ''​netstat -tpn''​ oraz ''​ss -atnop''​ w jakim stanie jest połączenie. Przypomnij sobie co oznacza ten stan - [[https://​tools.ietf.org/​html/​rfc793#​page-22|RFC793]]. Spróbuj w tym czasie uruchomić ponownie program serwera. \\ //Zadanie 2b:// Ustaw przed wywołaniem ''​bind''​ opcję ''​SO_REUSEADDR''​ gniazda (kod poniżej) i powtórz zadanie 2a.<code cpp>​const int one = 1;
 setsockopt(sockFd,​ SOL_SOCKET, SO_REUSEADDR,​ &one, sizeof(one));</​code>​ setsockopt(sockFd,​ SOL_SOCKET, SO_REUSEADDR,​ &one, sizeof(one));</​code>​
  
Linia 35: Linia 37:
 Funkcja ''​accept''​ (podobnie jak wprowadzana za chwilę ''​recvfrom''​) może przekazać informację o adresie z którego nawiązano połączenie. W tym celu należy jej podać: Funkcja ''​accept''​ (podobnie jak wprowadzana za chwilę ''​recvfrom''​) może przekazać informację o adresie z którego nawiązano połączenie. W tym celu należy jej podać:
   * gdzie ma zapisać ten adres – tj. podać adres struktury sockaddr (drugi argument)   * gdzie ma zapisać ten adres – tj. podać adres struktury sockaddr (drugi argument)
-  * adres zmiennej, która w momencie wywołania ''​accept'' ​na wpisany rozmiar przekazanej struktury (trzeci argument)<​html><​small></​html><​code cpp>+  * adres zmiennej, która w momencie wywołania ''​accept'' ​ma wpisany rozmiar przekazanej struktury (trzeci argument)<​html><​small></​html><​code cpp>
 sockaddr_in nazwa_zmiennej;​ sockaddr_in nazwa_zmiennej;​
 socklen_t inna_zmienna = sizeof(nazwa_zmiennej);​ socklen_t inna_zmienna = sizeof(nazwa_zmiennej);​
-client = accept(ssock,​ &nazwa_zmiennej, &inna_zmienna);+client = accept(ssock, ​(sockaddr*)&nаzwa_zmiennej, &innа_zmienna);
 </​code><​html></​small></​html>​ </​code><​html></​small></​html>​
 Jeśli drugi i trzeci argument są niezerowe, ''​accept''​ wypisuje przekazaną strukturę (drugi argument) i ustawia ile bajtów przekazanej struktury wypełnił (trzeci argument). Jeśli drugi i trzeci argument są niezerowe, ''​accept''​ wypisuje przekazaną strukturę (drugi argument) i ustawia ile bajtów przekazanej struktury wypełnił (trzeci argument).
Linia 80: Linia 82:
  
 UDP jest bezpołączeniowe,​ więc nie da się na nim wykonać funkcji ''​shutdown''​. UDP jest bezpołączeniowe,​ więc nie da się na nim wykonać funkcji ''​shutdown''​.
- 
 ==== Klient UDP ==== ==== Klient UDP ====
  
sk2/sockets_full.1571079659.txt.gz · ostatnio zmienione: 2019/10/14 21:00 przez jkonczak