Różnice między wybraną wersją a wersją aktualną.
Nowa wersja | Poprzednia wersja | ||
sk2:sfml [2023/11/29 23:37] jkonczak utworzono |
sk2:sfml [2023/11/30 13:15] (aktualna) jkonczak |
||
---|---|---|---|
Linia 1: | Linia 1: | ||
- | ======= Moduł do obsługi sieci w SFML ======= | + | ===== Instalacja bibliotek deweloperskich w laboratoriach ===== |
+ | Aby zainstalować potrzebne pakiety na __Linuksie SK prog__, należy wykonać: | ||
+ | <html><div style="margin-top:-1.2em;line-height:1.2em"/></html> | ||
+ | <code> | ||
+ | su | ||
+ | apt update | ||
+ | apt install libsfml-dev | ||
+ | </code> | ||
+ | |||
+ | Aby zainstalować potrzebne pakiety na __Linuksie lokalnym__, należy wykonać: | ||
+ | <html><div style="margin-top:-1.2em;line-height:1.2em"/></html> | ||
+ | <code> | ||
+ | sudo zypper install -y sfml2-devel | ||
+ | </code> | ||
====== Dokumentacja SFML ====== | ====== Dokumentacja SFML ====== | ||
[[https://www.sfml-dev.org/tutorials/2.6/#network-module|Zbiór samouczków SFML]] | [[https://www.sfml-dev.org/tutorials/2.6/#network-module|Zbiór samouczków SFML]] | ||
Linia 36: | Linia 49: | ||
promują użycie aktywnego czekania, tzn. aplikacja będzie zużywać procesor nawet | promują użycie aktywnego czekania, tzn. aplikacja będzie zużywać procesor nawet | ||
jeśli nic się nie dzieje. | jeśli nic się nie dzieje. | ||
- | Aby uniknąć aktywnego czekania, można dodawać co jakiś czas sleepy; w SFML jest | + | Aby uniknąć nadmiernego użycia procesora, można dodawać co jakiś czas sleepy; w SFML jest |
- | to "oficjalnie" opakowne w funkcję ''[[https://www.sfml-dev.org/documentation/2.6.1/classsf_1_1Window.php#af4322d315baf93405bf0d5087ad5e784|setFramerateLimit]]'' | + | to "oficjalnie" opakowne w funkcję ''[[https://www.sfml-dev.org/documentation/2.6.1/classsf_1_1Window.php#af4322d315baf93405bf0d5087ad5e784|setFramerateLimit]]''. |
</small> | </small> | ||
Mimo posiadania modułu do obsługi połączeń sieciowych, funkcja ''[[https://www.sfml-dev.org/documentation/2.6.1/classsf_1_1WindowBase.php#a6a143de089c8716bd42c38c781268f7f|pollEvent]]'' | Mimo posiadania modułu do obsługi połączeń sieciowych, funkcja ''[[https://www.sfml-dev.org/documentation/2.6.1/classsf_1_1WindowBase.php#a6a143de089c8716bd42c38c781268f7f|pollEvent]]'' | ||
nie wspiera zdarzeń z gniazd. | nie wspiera zdarzeń z gniazd. | ||
- | Obsługę gniazd w pętli zdarzeń należy zbudować ręcznie. | + | \\ |
+ | **Obsługę gniazd w pętli zdarzeń należy zbudować ręcznie.** | ||
===== Budowanie kodu i CMake ===== | ===== Budowanie kodu i CMake ===== | ||
Aby zbudować kod używający SFML, należy dodać do opcji kompilatora łączenie z | Aby zbudować kod używający SFML, należy dodać do opcji kompilatora łączenie z | ||
- | odpowiednimi bibliotekami: ''sfml-system'', ''sfml-graphics'', ''sfml-network'', | + | odpowiednimi bibliotekami: \\ ''sfml-system'', ''sfml-graphics'', ''sfml-network'', |
''sfml-audio'', ''sfml-window''. | ''sfml-audio'', ''sfml-window''. | ||
Ręcznie, z linii poleceń można podać (np. dla programu potrzebującego modułów graphics i network): | Ręcznie, z linii poleceń można podać (np. dla programu potrzebującego modułów graphics i network): | ||
- | <html><div style="margin:-1.2em 0 -1.2em 0"/></html> | + | <html><div style="margin-top:-1.2em"/></html> |
<code bash>c++ prog.cpp -o prog -lsfml-graphics -lsfml-network</code> | <code bash>c++ prog.cpp -o prog -lsfml-graphics -lsfml-network</code> | ||
Dla systemu automatyzacji budowania CMake należy do pliku ''CMakeLists.txt'' dodać: | Dla systemu automatyzacji budowania CMake należy do pliku ''CMakeLists.txt'' dodać: | ||
- | <html><div style="margin:-1.2em 0 -1.2em 0"/></html> | + | <html><div style="margin-top:-1.2em"/></html> |
<code cmake> | <code cmake> | ||
- | find_package(SFML 2.6 COMPONENTS system network REQUIRED) | + | find_package(SFML 2.5 COMPONENTS system network REQUIRED) |
target_link_libraries(prog … sfml-system sfml-network … ) | target_link_libraries(prog … sfml-system sfml-network … ) | ||
</code> | </code> | ||
- | <html><div style="margin:-1.2em 0 -1.2em 0"/></html> | + | <html><div style="margin-top:-1.2em"/></html> |
SFML __nie__ ustawia zmiennych zawierających listę modułów do linkowania, trzeba | SFML __nie__ ustawia zmiennych zawierających listę modułów do linkowania, trzeba | ||
je podać ręcznie. | je podać ręcznie. | ||
Linia 66: | Linia 80: | ||
<small> | <small> | ||
Przykład kompletnego pliku ''CMakeLists.txt'': | Przykład kompletnego pliku ''CMakeLists.txt'': | ||
- | <html><div style="margin:-1.2em 0 0 0"/></html> | + | <html><div style="margin-top:-1.2em"/></html> |
<code cmake> | <code cmake> | ||
cmake_minimum_required(VERSION 3.12) | cmake_minimum_required(VERSION 3.12) | ||
project(myProg) | project(myProg) | ||
set(CMAKE_CXX_STANDARD 20) | set(CMAKE_CXX_STANDARD 20) | ||
- | find_package(SFML 2.6 COMPONENTS graphics system network REQUIRED) | + | find_package(SFML 2.5 COMPONENTS graphics system network REQUIRED) |
add_executable(myProg main.cpp window.h window.cpp) | add_executable(myProg main.cpp window.h window.cpp) | ||
target_link_libraries(myProg sfml-graphics sfml-network) | target_link_libraries(myProg sfml-graphics sfml-network) | ||
Linia 80: | Linia 94: | ||
Klasy do obsługi sieci są dostępne po dodaniu do kodu dyrektywy: | Klasy do obsługi sieci są dostępne po dodaniu do kodu dyrektywy: | ||
- | <html><div style="margin:-1.2em 0 0 0"/></html> | + | <html><div style="margin-top:-1.2em"/></html> |
<code c++>#include <SFML/Network.hpp></code> | <code c++>#include <SFML/Network.hpp></code> | ||
Linia 111: | Linia 125: | ||
* ''send'' - wysyła dane | * ''send'' - wysyła dane | ||
* ''receive'' - odbiera dane | * ''receive'' - odbiera dane | ||
+ | | ||
+ | **Uwaga:** klasy oferowane przez SFML nie mają konstruktorów kopiujących (//copy constuctor//) __ani przesuwających (//move constructor//)__. | ||
==== Tryb nieblokujący ==== | ==== Tryb nieblokujący ==== | ||
Linia 127: | Linia 143: | ||
\\ | \\ | ||
Odpowiednio nowe połączenie, ilość wysłanych / odebranych bajtów jest wpisywana do dodatkowego | Odpowiednio nowe połączenie, ilość wysłanych / odebranych bajtów jest wpisywana do dodatkowego | ||
- | argumentu przekazywanego przez referencję. | + | argumentu przekazywanego przez referencję, np: |
+ | <html><div style="margin-top:-1.2em"/></html> | ||
+ | <html><div style="line-height:1.2em"></html> | ||
+ | <code C++> | ||
+ | char buffer[1024]; | ||
+ | size_t receivedBytes; | ||
+ | if (sock.receive(buffer, 1024, receivedBytes) == sf::Socket::Done) { | ||
+ | sf::String receivedBufferAsString(std::string(buffer, receivedBytes)); | ||
+ | (…) | ||
+ | </code> | ||
+ | <html><div style="margin-top:-1.2em"/></html> | ||
+ | <code C++> | ||
+ | std::unordered_map<int, sf::TcpSocket> clients; | ||
+ | if (servSock.accept(clients[clientIdSequencer]) == sf::Socket::Done) { | ||
+ | int clientId = clientIdSequencer++; | ||
+ | clients[clientId].send(helloPacket); | ||
+ | (…) | ||
+ | </code> | ||
+ | <html></div></html> | ||
==== Zadania ==== | ==== Zadania ==== | ||
Linia 151: | Linia 185: | ||
Przykładowo, do wysłania i odbioru danych można: | Przykładowo, do wysłania i odbioru danych można: | ||
- | <html><div style="margin:-1.2em 0 -1.2em 0"/></html> | + | <html><div style="margin-top:-1.2em"/></html> |
- | <html><div style="line-height:1.1em"></html> | + | <html><div style="line-height:1.2em"></html> |
<code C++> | <code C++> | ||
enum MessageType : sf::Uint8 { Foo = 1, Bar, Baz }; | enum MessageType : sf::Uint8 { Foo = 1, Bar, Baz }; | ||
Linia 186: | Linia 220: | ||
Dla poprawienia modularności i czytelności kodu można dodać własne operatory: | Dla poprawienia modularności i czytelności kodu można dodać własne operatory: | ||
- | <html><div style="margin:-1.2em 0 0 0"/></html> | + | <html><div style="margin-top:-1.2em"/></html> |
- | <html><div style="line-height:1.1em"></html> | + | <html><div style="line-height:1.2em"></html> |
<code C++> | <code C++> | ||
sf::Packet &operator<<(sf::Packet &packet, const FooMessage &msg) { | sf::Packet &operator<<(sf::Packet &packet, const FooMessage &msg) { | ||
Linia 238: | Linia 272: | ||
\\ | \\ | ||
Klasa ''sf::TcpSocket'' w prywatnym polu przechowuje częściowe dane przychodzącego | Klasa ''sf::TcpSocket'' w prywatnym polu przechowuje częściowe dane przychodzącego | ||
- | pakietu ([[https://github.com/SFML/SFML/blob/2.6.x/include/SFML/Network/TcpSocket.hpp#L219|kod]]). | + | pakietu ([[https://github.com/SFML/SFML/blob/2.6.x/include/SFML/Network/TcpSocket.hpp#L219|kod1]], |
+ | [[https://github.com/SFML/SFML/blob/2.6.x/src/SFML/Network/TcpSocket.cpp#L379|kod2]]). | ||
\\ | \\ | ||
Pakiet podany jako argument jest wypełniany danymi tylko w ostatnim wywołaniu funkcji ''receive''. | Pakiet podany jako argument jest wypełniany danymi tylko w ostatnim wywołaniu funkcji ''receive''. | ||
Linia 275: | Linia 310: | ||
Przykład użycia klasy ''sf::SocketSelector'' do stworzenia serwera czatu: | Przykład użycia klasy ''sf::SocketSelector'' do stworzenia serwera czatu: | ||
- | <html><div style="margin:-1.2em 0 0 0"/></html> | + | <html><div style="margin-top:-1.2em"/></html> |
- | <html><div style="line-height:1.1em"></html> | + | <html><div style="line-height:1.2em"></html> |
<code c++> | <code c++> | ||
#include <SFML/Network.hpp> | #include <SFML/Network.hpp> | ||
Linia 316: | Linia 351: | ||
SFML oferuje też klasy do wysłania żądań HTTP i obsługi FTP, ale nie obsługuje | SFML oferuje też klasy do wysłania żądań HTTP i obsługi FTP, ale nie obsługuje | ||
- | powszechnego dziś dla protokołu HTTP szyfrowania. | + | powszechnego dziś dla protokołu HTTP szyfrowania (tzn. nie zadziała żadna strona |
+ | z adresem zaczynającym się od ''https:/%%%%/''). | ||
===== Przykład z GUI ===== | ===== Przykład z GUI ===== | ||
Linia 325: | Linia 361: | ||
objętość kodu który trzeba napisać żeby cokolwiek osiągnąć w tej bibliotece. | objętość kodu który trzeba napisać żeby cokolwiek osiągnąć w tej bibliotece. | ||
Powyższy przykład ma 277 linii kodu. Dla porównania daleko bardziej funkcjonalny | Powyższy przykład ma 277 linii kodu. Dla porównania daleko bardziej funkcjonalny | ||
- | klient TCP w Qt (z poprzednich zajęć) ma 115 linii kodu i to już okazało się dla | + | klient TCP w Qt (z poprzednich zajęć) ma 115 linii kodu i to już okazało się dla |
części osób zaporową liczbą. | części osób zaporową liczbą. | ||