Narzędzia użytkownika

Narzędzia witryny


sk2:sockets_intro

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_intro [2019/10/06 19:56]
jkonczak [C++]
sk2:sockets_intro [2023/10/10 16:54] (aktualna)
jkonczak [Hello world]
Linia 1: Linia 1:
 ====== Wstęp – przypomnienia ====== ====== Wstęp – przypomnienia ======
 +
 +\\
  
 ==== C++ ==== ==== C++ ====
-Większość przykładów w materiałach i programów pisanych na laboratoriach jest w C++.\\+Większość przykładów w materiałach i programów pisanych na laboratoriach jest w C+////+.\\
 Stąd przypominam jak obsługiwać kompilator GCC / clang w Linuksie. ​ Stąd przypominam jak obsługiwać kompilator GCC / clang w Linuksie. ​
  
 Przykładowe polecenie do kompilacji przykładów ze strony: Przykładowe polecenie do kompilacji przykładów ze strony:
  
-''​g+////+ --std=c+////+17 -Wall -O0 -g -pthread -o example example.cpp''​+<​html><​code>​g++ --std=c++20 -Wall -O0 -g <​html><​span style="​color:​gray;">​-pthread</​span> ​-o example example.cpp</​code></​html>​
  
 |''​c+////​+''​|domyślny kompilator C+////+. Zwykle link do ''​g+////​+''​ lub ''​clang+////​+''​| |''​c+////​+''​|domyślny kompilator C+////+. Zwykle link do ''​g+////​+''​ lub ''​clang+////​+''​|
 |''​c+////​+ zrodlo.cpp -o prog''​|kompiluje plik ''​zrodlo.cpp''​ do programu ''​prog''​| |''​c+////​+ zrodlo.cpp -o prog''​|kompiluje plik ''​zrodlo.cpp''​ do programu ''​prog''​|
-|''​c+////​+ -Wall       z.cpp -o p''​|włącza wszystkie ostrzeżenia kompilatora (''​-W''​ = warn, ''​all''​ = wszystkie)|+|''​c+////​+ -Wall       z.cpp -o p''​|włącza wszystkie(("​Wszystkie"​ oznacza wybrany zbiór ostrzeżeń o nazwie wszystkie, poza ''​-Wall''​ warto też dodać ''​-Wextra''​ i rozważyć dodanie ''​-pedantic''​. Szczegóły w dokumentacji kompilatora [[https://​gcc.gnu.org/​onlinedocs/​gcc/​Warning-Options.html|gcc]]/​[[https://​clang.llvm.org/​docs/​UsersManual.html#​enabling-all-diagnostics|clang]])) ​ostrzeżenia kompilatora (''​-W''​ = warn, ''​all''​ = wszystkie)|
 |''​c+////​+ -O0 -g      z.cpp -o p''​|wyłącza optymalizacje i dodaje do programu dane umożliwiające debugowanie| |''​c+////​+ -O0 -g      z.cpp -o p''​|wyłącza optymalizacje i dodaje do programu dane umożliwiające debugowanie|
-|''​c+////​+ --std=c+////​+17 z.cpp -o p''​|włącza używanie standardu ISO C+////+ z 2017 roku| +|''​c+////​+ --std=c+////​+20 z.cpp -o p''​|włącza używanie standardu ISO C+////+ z 2020 roku| 
-|''​c+////+ -pthread ​   z.cpp -o p''​|włącza obsługę wątków standardu POSIX|  +|<​html><​code><​span style="​color:​gray;">​c++ -pthread ​   z.cpp -o p</​span></​code></​html>​|<​html><​span style="​color:​gray;"></​html>​włącza obsługę wątków standardu POSIX \\ wymagane do wersji glibc ≤ 2.33 [[https://developers.redhat.com/articles/2021/12/17/why-glibc-234-removed-libpthread|[1]]] [[https://lists.gnu.org/archive/html/info-gnu/2021-08/msg00001.html|[2]]]<​html></​span></​html>​|
-<​html><​!--<​small><​/html>W przykładach nie pojawiają się nowości z obowiązującego C+////+17 i przyszłego C+////+20, co nie znaczy że macie się ograniczać do C+////+11.<​html></​small>--></​html>​+
  
 Przykładowy plik cmake: Przykładowy plik cmake:
 <file cmake CMakeLists.txt>​ <file cmake CMakeLists.txt>​
-cmake_minimum_required(VERSION 3.1)+cmake_minimum_required(VERSION 3.12)
 project(projname) project(projname)
 if(NOT CMAKE_BUILD_TYPE) if(NOT CMAKE_BUILD_TYPE)
     set(CMAKE_BUILD_TYPE "​Debug"​)     set(CMAKE_BUILD_TYPE "​Debug"​)
 endif() endif()
-set(CMAKE_CXX_STANDARD ​17)+set(CMAKE_CXX_STANDARD ​20)
 find_package(Threads) find_package(Threads)
-add_executable(example example.cpp) +link_libraries(Threads::​Threads) 
-target_link_libraries(example ${CMAKE_THREAD_LIBS_INIT})+add_executable(example1 example1.cpp) 
 +add_executable(example2 example2.cpp) 
 +target_link_libraries(example2 Threads::​Threads)
 </​file>​ </​file>​
 ==== Obsługa plików w POSIX ==== ==== Obsługa plików w POSIX ====
-Interface obsługi gniazd BSD jest bardzo zbliżony do API specyfikowanego przez POSIX do obsługi plików (który znacie z PW). \\ <​html><​small>​ BSD socket API został przyjęty jako standard przez większość systemów operacyjnych,​ m. inn. został bez większych zmian wpisany w standard POSIX.</​small></​html>​+Interface obsługi gniazd BSD jest bardzo zbliżony do API specyfikowanego przez POSIX do obsługi plików (który znacie z PSiW). \\ <​html><​small>​ BSD socket API został przyjęty jako standard przez większość systemów operacyjnych,​ m. inn. został bez większych zmian wpisany w standard POSIX.</​small></​html>​
  
 //Zadanie 1.// Napisz program który otworzy plik o nazwie '​date'​ i wypisze jego zawartość. Poniżej "​pusty"​ plik źródłowy. Pomiń obsługę błędów. (Jeśli nie wiesz skąd wziąć plik ''​date'',​ wpisz w konsolę: ''​date>​date''​ .) \\ Do obsługi pliku i standardowego wejścia / wyjścia użyj funkcji ''​open'',​ ''​read'',​ ''​write''​ i ''​close''​. \\ //Zadanie 1.// Napisz program który otworzy plik o nazwie '​date'​ i wypisze jego zawartość. Poniżej "​pusty"​ plik źródłowy. Pomiń obsługę błędów. (Jeśli nie wiesz skąd wziąć plik ''​date'',​ wpisz w konsolę: ''​date>​date''​ .) \\ Do obsługi pliku i standardowego wejścia / wyjścia użyj funkcji ''​open'',​ ''​read'',​ ''​write''​ i ''​close''​. \\
 Opis funkcji znajdziesz na stronach podręcznika systemowego (np. ''​man open''​). Opis funkcji znajdziesz na stronach podręcznika systemowego (np. ''​man open''​).
 <file cpp z1.cpp> <file cpp z1.cpp>
-#include <​iostream>​ 
 #include <​fcntl.h>​ #include <​fcntl.h>​
 #include <​unistd.h>​ #include <​unistd.h>​
Linia 49: Linia 51:
 ==== Adresacja połączeń na warstwie transportu ==== ==== Adresacja połączeń na warstwie transportu ====
  
-//Zadanie 3.// Jakie adresy (numery) są potrzebne by móc przesłać wiadomość do programu na konkretnym ​komputerze?+//Zadanie 3.// Jakie adresy (numery) są potrzebne by móc przesłać wiadomość do konkretnego ​programu na wybranym ​komputerze?
  
 Przypomnienie programów ''​netcat''​ / ''​socat''​ oraz programów ''​netstat''​ / ''​ss''​ ([[sk1:​transport#​monitorowanie_biezacych_polaczen|link do materiałów z SK1]]) Przypomnienie programów ''​netcat''​ / ''​socat''​ oraz programów ''​netstat''​ / ''​ss''​ ([[sk1:​transport#​monitorowanie_biezacych_polaczen|link do materiałów z SK1]])
Linia 55: Linia 57:
 //Zadanie 4.// Prześlij między sobą dowolny tekst używając programu ''​netcat''​ lub ''​socat''​ //Zadanie 4.// Prześlij między sobą dowolny tekst używając programu ''​netcat''​ lub ''​socat''​
  
-//Zadanie 5.// Nawiąż połączenie na port 13 (daytime) twojego komputera.+//Zadanie 5.// Nawiąż połączenie na port 13 (daytime) twojego komputera. ​\\  
 +<​html><​small></​html>​Jeżeli używasz własnego komputera i port 13 nie odpowiada, uruchom i pozostaw działającą w osobnym terminalu komendę \\ ''​socat tcp-listen:​1313,​fork,​reuseaddr exec:​date''​   i do tego oraz dalszych ćwiczeń używaj port 1313.<​html></​small></​html>​
  
 <​html><​small></​html>​Więcej informacji o "​useful debugging and measurement tools":​ <​html><​small></​html>​Więcej informacji o "​useful debugging and measurement tools":​
Linia 65: Linia 68:
  
 Gniazdo (socket) – interfejs między systemem operacyjnym a programem użytkownika używany do dwukierunkowej komunikacji poza program.\\ Gniazdo (socket) – interfejs między systemem operacyjnym a programem użytkownika używany do dwukierunkowej komunikacji poza program.\\
-<​html><​small></​html>​Porównaj z: FIFO (named pipe, nazwany potok; było na SOP i PW)<​html></​small></​html>​+<​html><​small></​html>​Porównaj z: FIFO (named pipe, nazwany potok; było na SOP i PSiW)<​html></​small></​html>​
  
 API stworzone dla systemu BSD zostało przyjęte przez praktycznie wszystkie systemy operacyjne (POSIX socket API, WinSock). API stworzone dla systemu BSD zostało przyjęte przez praktycznie wszystkie systemy operacyjne (POSIX socket API, WinSock).
Linia 81: Linia 84:
 Przykład wysłania liczby 0x010F, czyli 271, czyli 0b0000000100001111 Przykład wysłania liczby 0x010F, czyli 271, czyli 0b0000000100001111
 |byte order\bit order|MSB first|LSB first| | | |byte order\bit order|MSB first|LSB first| | |
-|little endian|0000111100000001|1111000010000000| x86 |<​html><​div style="​margin-top:​1em">​ARM,​ IA-64 (Itanium), SPARC≥v9</​div></​html>​|+|little endian|0000111100000001|1111000010000000| x86/​x86_64 ​|<​html><​div style="​margin-top:​1em">​ARM,​ IA-64 (Itanium), SPARC≥v9, RISC-V</​div></​html>​|
 |big endian|0000000100001111|1000000011110000|Motorola 68k, SPARC<​v9,​ z/Arch| :::| |big endian|0000000100001111|1000000011110000|Motorola 68k, SPARC<​v9,​ z/Arch| :::|
 | |  I²C, SDH  |  Ethernet, RS232, USB  | | | |  I²C, SDH  |  Ethernet, RS232, USB  | |
Linia 95: Linia 98:
 uint16_t networkEndianessPort = htons(hostEndianessPort);​ uint16_t networkEndianessPort = htons(hostEndianessPort);​
 </​code>​ </​code>​
-Opis funkcji pomocniczych[[http://​www.cs.put.poznan.pl/​ddwornikowski/​sieci/​sieci2/​bsdsockets.html#​funkcje-pomocnicze]]+Opis funkcji pomocniczych ​– patrz ''​man byteorder''​ lub [[http://​www.cs.put.poznan.pl/​ddwornikowski/​sieci/​sieci2/​bsdsockets.html#​funkcje-pomocnicze|strona Darka Dwornikowskiego]]
  
 ==== Zapis adresu gniazda ==== ==== Zapis adresu gniazda ====
Linia 102: Linia 105:
 **Adres IP** oraz **numer portu** (<​html><​small>​lub ścieżkę dla gniazd unix</​small></​html>​) trzeba podać w odpowiedniej strukturze. **Adres IP** oraz **numer portu** (<​html><​small>​lub ścieżkę dla gniazd unix</​small></​html>​) trzeba podać w odpowiedniej strukturze.
  
-Do przekazywania adresu gniazda funkcje ​używają struktury ​**''​sockaddr''​** (w C – ''​struct sockaddr''​).+Do przekazywania adresu gniazda funkcje ​wymagają wskaźnika na strukturę ​**''​sockaddr''​** (w C – ''​struct sockaddr''​).
 Ta struktura nie pozwala na bezpośrednie wykorzystanie. Zamiast tego dla IPv4 należy używać **''​sockaddr_in''​** (w C – ''​struct sockaddr_in''​) Ta struktura nie pozwala na bezpośrednie wykorzystanie. Zamiast tego dla IPv4 należy używać **''​sockaddr_in''​** (w C – ''​struct sockaddr_in''​)
  
-Opis struktury''​man 7 ip'' ​lub ''​man netinet_in.h''​ lub  +Opis struktury ​– patrz ''​man 7 ip'' ​''​man netinet_in.h''​ lub  
-[[http://​www.cs.put.poznan.pl/​ddwornikowski/​sieci/​sieci2/​bsdsockets.html#​glowne-funkcje-interfejsu-gniazd]]+[[http://​www.cs.put.poznan.pl/​ddwornikowski/​sieci/​sieci2/​bsdsockets.html#​glowne-funkcje-interfejsu-gniazd|strona Darka]]
  
 <​html><​small></​html>​ <​html><​small></​html>​
Linia 125: Linia 128:
     * rodzina adresów IPv4 – stała ''​AF_INET''​     * rodzina adresów IPv4 – stała ''​AF_INET''​
     * port – 13 (port usługi daytime; pamiętaj o porządku bajtów - ''​htons''​)     * port – 13 (port usługi daytime; pamiętaj o porządku bajtów - ''​htons''​)
-    * adres IP – 127.0.0.1 (localhost, do konwersji użyj ''​inet_addr''​ lub ''​inet_aton''​);​ \\ można też ustawić adres na stałą ''​htonl(INADDR_LOOPBACK)''​. \\  <​html><​small></​html>​ Uwaga: ''​.sin_addr''​ to struktura typu ''​in_addr''​ z jedną składową ''​.s_addr''​ typu ''​uint32_t''​ \\ ''​inet_addr''​ przyjmuje wskaźnik na strukturę, natomiast ''​inet_aton''​ zwraca liczbę którą trzeba przypisać składowej ''​.s_addr'':​ \\ <code cpp>​sockaddr_in nazwa_zmiennej;​+    * adres IP – 127.0.0.1 (localhost, do konwersji użyj ''​inet_addr''​ lub ''​inet_aton''​);​ \\ można też ustawić adres na stałą ''​htonl(INADDR_LOOPBACK)''​. \\  <​html><​small></​html>​ Uwaga: ''​.sin_addr''​ to struktura typu ''​in_addr''​ z jedną składową ''​.s_addr''​ typu ''​uint32_t''​ \\ ''​inet_aton''​ przyjmuje wskaźnik na strukturę, natomiast ''​inet_addr''​ zwraca liczbę którą trzeba przypisać składowej ''​.s_addr'':​ \\ <code cpp>​sockaddr_in nazwa_zmiennej;​
 wersja 1: nazwa_zmiennej.sin_addr.s_addr = inet_addr("​8.8.8.8"​);​ wersja 1: nazwa_zmiennej.sin_addr.s_addr = inet_addr("​8.8.8.8"​);​
 wersja 2: inet_aton("​8.8.8.8",​ &​nazwa_zmiennej.sin_addr);​ wersja 2: inet_aton("​8.8.8.8",​ &​nazwa_zmiennej.sin_addr);​
Linia 133: Linia 136:
     * trzeci argument funkcji connect to rozmiar struktury opisującej adres – ''​sizeof()''​ zmiennej lub typu     * trzeci argument funkcji connect to rozmiar struktury opisującej adres – ''​sizeof()''​ zmiennej lub typu
   * przed wywołaniem funkcji ''​close()''​ zamykał połączenie funkcją ''​shutdown()'';​ \\ <​html><​small></​html>​w funkcji ''​shutdown()''​ można osobno zakończyć nadawanie i odbiór, drugi argument określa co zakończyć –  ''​SHUT_RD''​ /  ''​SHUT_WR''​ / ''​SHUT_RDWR''<​html></​small></​html>​   * przed wywołaniem funkcji ''​close()''​ zamykał połączenie funkcją ''​shutdown()'';​ \\ <​html><​small></​html>​w funkcji ''​shutdown()''​ można osobno zakończyć nadawanie i odbiór, drugi argument określa co zakończyć –  ''​SHUT_RD''​ /  ''​SHUT_WR''​ / ''​SHUT_RDWR''<​html></​small></​html>​
-Opis funkcji – strona Darka lub ''​man 3 …''​ / ''​man 3p …''​\\+Opis funkcji – [[https://​www.cs.put.poznan.pl/​ddwornikowski/​sieci/​sieci2/​bsdsockets.html#​glowne-funkcje-interfejsu-gniazd|strona Darka]] lub ''​man 3 …''​ / ''​man 3p …''​\\
 Potrzebne pliki nagłówkowe to: Potrzebne pliki nagłówkowe to:
 <code cpp> <code cpp>
sk2/sockets_intro.1570384564.txt.gz · ostatnio zmienione: 2019/10/06 19:56 przez jkonczak