Różnice między wybraną wersją a wersją aktualną.
Nowa wersja | Poprzednia wersja | ||
sk2:good_practices [2020/11/09 19:47] jkonczak utworzono |
sk2:good_practices [2022/11/21 21:52] (aktualna) jkonczak |
||
---|---|---|---|
Linia 1: | Linia 1: | ||
- | ==== Code patterns ==== | + | ===== Code patterns ===== |
- | === Typowe podejścia do odbierania wiadomości === | + | ==== Typowe podejścia do odbierania wiadomości ==== |
Metoda 1: (do użycia tylko jeśli rozmiar wiadomości jest wysyłany na początku lub jest z góry znany) | Metoda 1: (do użycia tylko jeśli rozmiar wiadomości jest wysyłany na początku lub jest z góry znany) | ||
Linia 13: | Linia 13: | ||
Metoda 2: | Metoda 2: | ||
* przygotowuje się obiekt/funkcję parsującą strumieniowe dane, która: | * przygotowuje się obiekt/funkcję parsującą strumieniowe dane, która: | ||
- | * przyjmuje porcję danych dowolnego rozmiaru | + | * przyjmuje porcję danych dowolnego rozmiaru |
- | * wywoływana jest wielokrotnie dla kolejnych porcji danych | + | * wywoływana jest wielokrotnie dla kolejnych porcji danych |
- | * analizuje dane które przyszły | + | * analizuje dane które przyszły |
- | * pamięta w jakim stanie się znajduje | + | * pamięta w jakim stanie się znajduje |
- | * po przygotowaniu całych wiadomości zwraca je lub wywołuje funkcję do obsługi wiadomości | + | * po przygotowaniu całych wiadomości zwraca je lub wywołuje funkcję do obsługi wiadomości |
- | * <html><small></html>//przykład #1:// funkcja dodaje kolejną porcję do bufora, następnie dopóki w buforze znajdzie znak końca wiadomości usuwa gotową wiadomość z bufora \\ //przykład #2:// funkcja buduje na bieżąco strukturę danych reprezentującą przychodzący json<html></small></html> | + | * <html><small></html>//przykład #1:// funkcja dodaje kolejną porcję do bufora, następnie dopóki w buforze znajdzie znak końca wiadomości usuwa gotową wiadomość z bufora \\ //przykład #2:// funkcja buduje na bieżąco strukturę danych reprezentującą przychodzący json \\ //przykład #3:// funkcja odbiera nazwy, rozmiar i zawartość kolejnych plików i zapisuje je na bieżąco na dysk<html></small></html> |
* dane są odbierane w takich procjach jak przychodzą i są przekazywane powyższej funkcji | * dane są odbierane w takich procjach jak przychodzą i są przekazywane powyższej funkcji | ||
- | === Produkowanie wiadomości z bufora === | + | ==== Produkowanie wiadomości z bufora ==== |
Zmieniając wiadomości (struktury / obiekty w języku programowania) w dane do wysłania w sieć (ciąg bajtów) (=serializacja) i na odwrót (=deserializacja), można: | Zmieniając wiadomości (struktury / obiekty w języku programowania) w dane do wysłania w sieć (ciąg bajtów) (=serializacja) i na odwrót (=deserializacja), można: | ||
Linia 35: | Linia 35: | ||
* tworzy się testy jednostkowe które sprawdzają poprawność przygotowanych metod | * tworzy się testy jednostkowe które sprawdzają poprawność przygotowanych metod | ||
- | === Typowe podejścia do wysyłania wiadomości === | + | ==== Typowe podejścia do wysyłania wiadomości ==== |
Metoda 1: | Metoda 1: | ||
Linia 50: | Linia 50: | ||
- wyślij nieblokująco wszystko co się da (pamiętaj o zwalnianiu pamięci) | - wyślij nieblokująco wszystko co się da (pamiętaj o zwalnianiu pamięci) | ||
- jeśli wysłano wszystko – przestań czekać na zdarzenie zapisu | - jeśli wysłano wszystko – przestań czekać na zdarzenie zapisu | ||
- | * jeśli progam potrzebuje pisać z wielu wątków, potrzeba jest synchronizacja (zamek) na obgługę zapisów | + | * jeśli program potrzebuje pisać z wielu wątków, potrzeba jest synchronizacja (zamek) na obsługę zapisów |
Metoda 2: | Metoda 2: | ||
* dla każdego połączenia trzymany jest wątek do wysyłania, lista wiadomości, zamek i zmienna warunkowa | * dla każdego połączenia trzymany jest wątek do wysyłania, lista wiadomości, zamek i zmienna warunkowa | ||
Linia 71: | Linia 71: | ||
* ile łącznie danych (w bajtach) czeka na wysłanie | * ile łącznie danych (w bajtach) czeka na wysłanie | ||
- | ==== Good practices ==== | + | ==== Zadania ==== |
- | === Podejście niskopoziomowe / wysokopoziomowe === | + | //Zadanie 1.// W plikach {{:sk2:ctr_srv.cpp|}} i {{:sk2:ctr_cli.cpp|}} znajduje się odpowiednio serwer i przykładowy klient usługi 'licznika'. |
+ | * Przeczytaj kod metody ''main()'' w serwerze i przetestuj program netcatem | ||
+ | * Przeczytaj kod metody ''main()'' i ''doWork()'' klienta. Jakiego stanu licznika spodziewałby się naiwny programista po przerwaniu programu klienta? | ||
+ | * Serwer i klient nie radzą sobie ze sklejaniem się wiadomości czy odebraniem tylko części wiadomości w wywołaniu ''read()''. Popraw kod. | ||
- | Przy programach nie wymagających wysokiej wydajności zwykle szuka się rozwiązań wymagających jak najmniej czasu od programisty - czyli szuka się bibliotek które robią większosć rzeczy za programistę. | + | ===== Good practices ===== |
- | Dla osiągniecia wysokiej wydajności zaleca się korzystanie z wydajnych, zwykle niskopoziomowych mechanizmów - albo bezpośrednio, albo za pomocą bibliotek nastawionych na wydajność (a nie wygodę użytkownika). Takie biblioteki są dostępne na różnym poziome abstrackji, porównaj np. [[https://www.boost.org/doc/libs/release/libs/asio/|boost asio]] i [[https://en.wikipedia.org/wiki/Libevent|libevent]]). | + | ==== Podejście niskopoziomowe / wysokopoziomowe ==== |
+ | |||
+ | Przy programach nie wymagających wysokiej wydajności zwykle szuka się rozwiązań wymagających jak najmniej czasu od programisty - czyli szuka się bibliotek które robią większość rzeczy za programistę. | ||
+ | |||
+ | Dla osiągnięcia wysokiej wydajności zaleca się korzystanie z wydajnych, zwykle niskopoziomowych mechanizmów - albo bezpośrednio, albo za pomocą bibliotek nastawionych na wydajność (a nie wygodę użytkownika). Takie biblioteki są dostępne na różnym poziome abstrakcji, porównaj np. [[https://www.boost.org/doc/libs/release/libs/asio/|boost asio]] i [[https://en.wikipedia.org/wiki/Libevent|libevent]]). | ||
Wysokowydajne mechanizmy niskopoziomowe to: | Wysokowydajne mechanizmy niskopoziomowe to: | ||
* Linux: epoll (omawiany na zajęciach) | * Linux: epoll (omawiany na zajęciach) | ||
Linia 83: | Linia 90: | ||
* MS Windows: [[https://docs.microsoft.com/en-us/windows/win32/fileio/i-o-completion-ports|IOCP]] | * MS Windows: [[https://docs.microsoft.com/en-us/windows/win32/fileio/i-o-completion-ports|IOCP]] | ||
- | === Web services === | + | ==== Web services ==== |
Wiele [[https://en.wikipedia.org/wiki/Web_service|usług sieciowych]] korzysta z ustandaryzowanych protokołów wymiany wiadomości, np. [[https://en.wikipedia.org/wiki/Representational_state_transfer|REST]] czy [[https://en.wikipedia.org/wiki/SOAP|SOAP]] | Wiele [[https://en.wikipedia.org/wiki/Web_service|usług sieciowych]] korzysta z ustandaryzowanych protokołów wymiany wiadomości, np. [[https://en.wikipedia.org/wiki/Representational_state_transfer|REST]] czy [[https://en.wikipedia.org/wiki/SOAP|SOAP]] | ||
- | === Middleware === | + | ==== Middleware ==== |
- | Dostępnych też jest wiele //middleware// (warstw pośredniczących) które pozwalają programiście używać sieci bez pisania kodu obsługjącego sieć, np: | + | Dostępnych też jest wiele //middleware// (warstw pośredniczących) które pozwalają programiście używać sieci bez pisania kodu obsługującego sieć, np: |
* [[https://en.wikipedia.org/wiki/Remote_procedure_call|RPC]] / [[https://en.wikipedia.org/wiki/Distributed_object_communication|RMI]] | * [[https://en.wikipedia.org/wiki/Remote_procedure_call|RPC]] / [[https://en.wikipedia.org/wiki/Distributed_object_communication|RMI]] | ||
* [[https://pl.wikipedia.org/wiki/Message_Passing_Interface|MPI]] | * [[https://pl.wikipedia.org/wiki/Message_Passing_Interface|MPI]] | ||
Linia 95: | Linia 102: | ||
* [[https://en.wikipedia.org/wiki/Actor_model|model aktorów]] | * [[https://en.wikipedia.org/wiki/Actor_model|model aktorów]] | ||
- | === Kryptografia, kompresja... === | + | ==== Kryptografia, kompresja... ==== |
Często w komunikacji sieciowej korzysta się z dodatkowych warstw abstrakcji między TCP a wiadomościami aplikacyjnymi do osiągnięcia: | Często w komunikacji sieciowej korzysta się z dodatkowych warstw abstrakcji między TCP a wiadomościami aplikacyjnymi do osiągnięcia: | ||
* bezpieczeństwa (integralności, poufności, autentyczności) wykorzystując [[https://en.wikipedia.org/wiki/Transport_Layer_Security|SSL lub TLS]] | * bezpieczeństwa (integralności, poufności, autentyczności) wykorzystując [[https://en.wikipedia.org/wiki/Transport_Layer_Security|SSL lub TLS]] | ||
- | * kompresję danych (o ile dane dają się kompresować) wykorzystując np. [[https://en.wikipedia.org/wiki/Zlib|deflate, zlib]], [[https://en.wikipedia.org/wiki/LZ4_(compression_algorithm)|lz4]] | + | * kompresji danych (o ile dane dają się kompresować) wykorzystując np. [[https://en.wikipedia.org/wiki/Zlib|deflate, zlib]], [[https://en.wikipedia.org/wiki/LZ4_(compression_algorithm)|lz4]], [[https://en.wikipedia.org/wiki/Zstd|zstd]] |
- | === Testowanie === | + | ==== Testowanie ==== |
Aplikacje korzystające z sieci powinny dodatkowo zostać przetestowane pod kątem: | Aplikacje korzystające z sieci powinny dodatkowo zostać przetestowane pod kątem: |