From c746e560c0c05299d3a1cb39a8b023212aed07e8 Mon Sep 17 00:00:00 2001 From: Kacper Donat Date: Fri, 13 Apr 2018 18:11:50 +0200 Subject: [PATCH] Sprawozdania dalszy ciag --- sprawozdanie/sprawozdanie.tex | 144 +++++++++++++++++++++++++++++++++- 1 file changed, 140 insertions(+), 4 deletions(-) diff --git a/sprawozdanie/sprawozdanie.tex b/sprawozdanie/sprawozdanie.tex index 00b2b5d..59143bf 100644 --- a/sprawozdanie/sprawozdanie.tex +++ b/sprawozdanie/sprawozdanie.tex @@ -26,6 +26,8 @@ \usepackage{braket} \usepackage{subcaption} \usepackage{multirow} +\usepackage{etoolbox} +\usepackage{color} \pgfplotsset{compat=1.15} \usepgfplotslibrary{groupplots} @@ -34,10 +36,27 @@ \usetikzlibrary{decorations.pathmorphing, arrows.meta, positioning} \usetikzlibrary{shapes.geometric, arrows, intersections} +\newcommand{\areyousure}[1]{{\color{red}\textbf{???} #1 \textbf{???}}} +\newcommand{\todo}[1]{{\color{blue}\textbf{TODO:} #1}} + +\makeatletter +\newcommand{\member}[2]{% + \ifcsdef{last}{\node[packet, right=of \last, text width=(#2*4mm)]}{\node[packet, text width=(#2*4mm)]} (#1) {\texttt{#1}};% + \node[below=of #1] {#2}; + \def\last{#1}% +}% +\newenvironment{packet}{% + \begin{tikzpicture}[packet/.style={draw, auto, align=center, minimum height=7mm}, node distance=0]% +}{% + \end{tikzpicture}% + \let\last\undefined +} +\makeatother + % opening \title{Przetwarzanie Rozproszone - Projekt} -\author{\protect\begin{tabular}{lll} - Weronika Czarnecka & \textit{165600} & \multirow{4}{*}{Informatyka gr. 1, Semestr IV} \tabularnewline +\author{\protect\begin{tabular}{ll|l} + Weronika Czarnecka & \textit{165600} & \multirow{4}{*}{\shortstack[l]{Informatyka 2016/2017 \\ Semestr IV, gr. 1}} \tabularnewline Anna Piliczewska & \textit{165436} & \tabularnewline Maciej Borzyszkowski & \textit{165407} & \tabularnewline Kacper Donat & \textit{165581} & % @@ -49,7 +68,124 @@ \maketitle -\section{Cel projektu} -Też go szukam +\section{Zasady rozgrywki} +Gracze poruszają się po wspólnej planszy czołgami strzelając do siebie i starając się zniszczyć. Każdy gracz kontroluje +tylko i wyłącznie swój czołg. + +\section{Wykorzystane technologie} +\begin{itemize} + \item C\# + \item SFML.net + \item System.Threading + \item System.Net.Sockets +\end{itemize} + +\section{Proponowana Architektura} +Z założenia, rozgrywka ma odbywać się w czasie rzeczywistym zatem wykorzystanie protokołu \textit{TCP} mogłoby +wprowadzać niepotrzebne opóźnienia wynikające z niepotrzebnych retransmisji pakietów. Komunikacja będzie odbywała się za +pomocą datagramów UDP, które pozwalają na szybszą - acz mniej dokładną transmisję informacji pomiędzy klientami. W +wypadku normlanej rozgrywki jednak strata części pakietów jest jak najbardziej akceptowalna i nie wpłynie na rozgrywkę w +znaczący sposób. + +W projekcie przyjęto architekturę klient-klient, tj. nie występuje żaden serwer stanowiący źródło prawdy dla rozgrywki. +Zamiast tego jeden z klientów zawsze będzie miał status \textit{mastera}. Poprawnym stanem rozgrywki z definicji jest +stan symulacji \textit{mastera}. \textit{masterem} zawsze jest klient o najmniejszym \texttt{ClientId}, tj. klient, +który podłączył się najwcześniej. Takie podejście zapewnia rozwiązanie sytuacji, w której aktualny \textit{master} się +rozłączy bez konieczności przeprowadzania negocjacji. + +Dodatkowo, przyjmuje się zasadę, że każdy klient jest w 100\% odpowiedzialny za swoją część symulacji, dla której +stanowi źródło prawdy. tj. każdy gracz wysyła tylko i wyłącznie informacje o zmianach rzeczy, na które on ma wpływ - np. +pozycję własnego czołgu, czy wystrzelenie pocisku. W gestii innych klientów jest przetworzyć te informację i +zsynchronizować się. + +Takie podejście zapewnia brak konfliktu o zasoby, ponieważ każdy obiekt jest modyfikowany wyłącznie przez jedną osobę (a +co za tym idzie, jeden wątek) zatem nigdy nie nastąpi wyścig. \todo{Modyfikacja w trakcie odczytu? Ma znaczenie?} +\areyousure{Przewidziano również wystąpowanie obiektów, które nie posiadają właściciela, a ich zachowanie jest w pełni +deterministyczne zatem nie wymaga jawnej synchronizacji pomiędzy klientami.} + +Każdy klient będzi obsługiwany przez 5 osobnych wątki, których kompetencje nie kolidują ze sobą: +\begin{enumerate} + \item Renderowanie stanu symulacji + \item Aktualizacja stanu (na podstawie kolejki akcji) + \item Input z sieci (obiór pakietów, kolejkowanie) \label{input:net} + \item Input użytkownika (odczyt klawiatury itd.) \label{input:user} + \item Output sieciowy (wysyłanie pakietów, retranmisje) \label{output:net} +\end{enumerate} + +Wątki \ref{input:net} oraz \ref{input:user} będą umieszczały akcje do wykonania w jednej kolejce akcji, zatem kolejka ta +musi być \textit{thread-safe} i udostępniać atomowe metody \texttt{enqueue} i \texttt{dequeue}, gwarantujące że stan +kolejki nie zostanie uszkodzony, tj. żadna akcja nie zostanie wykonana 2-krotnie ani żadna nie zostanie zgubiona. +Zostanie to osiągnięte poprzez ustawienie Mutexa\footnote{https://msdn.microsoft.com/en-us/library/system.threading.mutex(v=vs.110).aspx} +w metodach. + +\areyousure{Zakładamy, że akcje użytkownika muszą zostać zostać umieszczone na kolejce akcji natychmiastowo, zatem nie +ma potrzeby synchronizacji z siecią.} Co za tym idzie, dostęp do kolejki pakietów (potrzebnej ze względu na możliwość +otrzymania pakietów w nieodpowiedniej kolejności) i jej obsługa będzie w całości po stronie wątku \ref{input:net} - +czyli problem wyścigów nie następuje. + +Poprzez identyczną kolejkę będzie obsługiwana wysyłka pakietów będzie obsługiwana przez identyczną kolejkę w celu +skomunikowania wątków \ref{input:user} oraz \ref{output:net}. Dodatkowo w wątku \ref{output:net} będzie działać +samodzielna kolejka odpowiadająca za retransmisję pakietów. + +Niektóre pakiety zmieniają stan rozgrywki (np. śmierć, wystrzelenie pocisku), a co za tym idzie muszą zostać +przetworzone przez wszystkich klientów w jednakowej kolejnosci i w miarę jednakowym czasie (nie ma możliwości +zagwarntowania idealnej synchronizacji). W tym celu wprowadzony zostanie system numerowania kolejnych pakietów a każdy +pakiet, będzie zawierał informację na temat stanu od którego "zależy" - tj. numeru ostatniej aktualizacji. W wypadku +gdyby doszły pakiety konkurujące ze sobą (tj. o tym samym numerze pakietu, oraz zależące od tego samego stanu) wygrywa +ten, który przyszedł pierwszy ponieważ są one od siebie niezależne. + +\subsection{Protokół} +Protokół opiera się o wysyłanie datagramów UDP między wszystkimi klientami. Ze względu na specyfikę UDP (brak gwarancji +dotarcia pakietów, brak gwarancji kolejności, brak gwarancji poprawności) przyjmuje się następujące założenia: +\begin{itemize} + \item nie wszystkie pakiety są ważne + \item wszystkie pakiety aby zostać przetworzone muszą dojść w całości poprawnie + \item pakiety są numerowane + \item przez ważne pakiety rozumiemy te, które zmieniaja stan mapy + \item pakiety mogą wymagać konkretnego poziomu stanu gry + \item pakiety zawierają timestamp aby w razie kolizji ustalić pierwszeństwo +\end{itemize} + +Ze względu na konieczność szybkiego przesyłania informacji pomiędzy klientami, zaprojektowany protokół jest protokołem +binarnym, o konstrukcji pakietu widocznej poniżej. + +\begin{figure}[H] + \center + \begin{packet} + \member{CRC32}{4} + \member{Type}{1} + \member{Size}{2} + \member{ClientId}{2} + \member{State}{4} + \member{PacketId}{4} + \node[packet, dotted, right=of PacketId, text width=6cm] (Data) {Packet Data ...}; + \end{packet} + + \caption{Budowa pakietu} +\end{figure} + +\begin{table}[H] + \centering + \begin{tabular}{l|l|l} + \textbf{Właściwość} & \textbf{Typ} & \textbf{Opis} \\ \hline + \texttt{CRC32} & \texttt{int32} & Suma kontrolna danych w pakiecie \\ + \texttt{Type} & \texttt{uint8} & Rodzaj wysyłanego pakietu \\ + \texttt{Size} & \texttt{uint16} & Rozmiar wysłanych danych, razem z pierwszym bajtem \\ + \texttt{ClientId} & \texttt{uint16} & Identyfikator klienta \\ + \texttt{State} & \texttt{uint32} & Wymagany stan gry do przetworzenia pakietu \\ + \texttt{PacketId} & \texttt{uint32} & Timestamp oryginalnego wysłania pakietu + \end{tabular} +\end{table} + +Dla ułatwienia implementacji przyjmuje się, że dla pakietów, których najstarszy bit typu (\texttt{Type \& 0xC0}) jest +ustawiony na 1 nie zachodzi potrzeba retransmisji - czyli są to pakiety mało istotne bądź szybko przedawniające się. +Przykładem takiego pakietu może być aktualizacja pozycji gracza - nie ma potrzeby retransmisji ponieważ prawdopodobnie i +tak w drodze jest następny pakiet z nowszą pozycją. + +Aby upewnić się, że transmisja ważnego pakietu się powiodła, każdy klient musi zwrócić + +\section{Rozwiązania} +O nie w tym wypadku też ciężko + \end{document}