Narzędzia użytkownika

Narzędzia witryny


Pasek boczny

sk2:sockets_full

To jest stara wersja strony!


Interface gniazd BSD (1/2)

Schemat kolejności wywołać funkcji bibliotecznych znajduje się na:
http://www.cs.put.poznan.pl/ddwornikowski/sieci/sieci2/bsdsockets.html#rys-1

Serwer TCP

Aby oczekiwać na przychodzące połączenia TCP, po stworzeniu gniazda (socket(…)) wystarczy wywołać 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(…) używa się funkcji bind(…) do ustawienia lokalnego adresu gniazda. Funkcja bind przyjmuje jako argument strukturę sockaddr.

Lokalny adres IP można ustawić na dowolny – INADDR_ANY lub wybrany przez siebie – np. 127.0.0.1 (INADDR_LOOPBACK) jeśli połączenia mają być ograniczone do localhosta.

Po wywołaniu funkcji listen system operacyjny system operacyjny czeka na połączenia. Do odebrania nowego połączenia należy użyć funkcji accept(…). Funkcja accept zwróci nowe gniazdo reprezentujące nawiązane połączenie.

Zadanie 1: Napisz program, który:

  • stworzy gniazdo,
  • ustali adres (bind),
  • rozpocznie oczekiwanie na połączenia (listen),
  • zaakceptuje połączenie (accept); na razie drugi i trzeci argument funkcji accept ustaw na 0 lub nullptr,
  • wyśle tam dane (stały ciąg znaków),
  • zakończy program.

Zadanie 2a: Krótko1) po zamknięciu programu serwera sprawdź poleceniem netstat -tn w jakim stanie jest połączenie. Przypomnij sobie co oznacza ten stan - 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.

const int one = 1;
setsockopt(sockFd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));

Zadanie 3: Zakomentuj wywołanie bind, uruchom program i odczytaj z wyników komendy netstat -tlpn na jakim porcie nasłuchuje twój serwer. Następnie połącz się do niego.

Zadanie 4: Zmodyfikuj program tak, by w pętli obsługiwał nowe połączenia

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)
  • adres zmiennej, która w momencie wywołania accept na wpisany rozmiar przekazanej struktury

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).

Zadanie 5: Dodaj do programu wyświetlanie z jakiego adresu IP i numeru portu nawiązano połączenie

UDP vs TCP - przypomnienie

TCP: Strumieniowy. Połączeniowy. Kontrola przepływu. Niezawodny (reliable).
UDP: Zorientowany na wiadomość. Bezpołączeniowy, bezstanowy. Brak kontroli przepływu. Best-effort.

Tworząc gniazdo UDP należy użyć następujących argumentów:

socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)
// lub: socket(PF_INET, SOCK_DGRAM, 0)

UDP nie nawiązuje połączenia – do odbioru i wysyłania wiadomości należy używać funkcji sendto i recvfrom (lub recv/read, jeśli nie obchodzi nas nadawca).
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.

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.

Zadanie 6. Odpowiedz na pytanie dlaczego DNS używa UDP zamiast TCP do zapytań.

Klient UDP

Zadanie 7. 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.

Serwer UDP

Zadanie 8. Napisz program, który korzystając z protokołu UDP odbierze dane i odeśle je pod adres nadawcy zmieniając wielkość liter.
Jeśli nie wiesz jak zmienić wielkość liter, to for(char *it=str; (*it=toupper(*it)); ++it);

Zadanie 9. Napisz program, który będzie w pętli odbierać dane i odsyłać je pod adresy wszystkich wcześniejszych nadawców.

sk2/sockets_full.1508152733.txt.gz · ostatnio zmienione: 2017/10/16 13:18 przez jkonczak