Ten projekt demonstruje implementację prostych aplikacji rozproszonych typu klient-serwer, zbudowanych z użyciem języków C oraz Java i wykorzystujących protokoły TCP oraz UDP. Programy te ilustrują zasady komunikacji sieciowej, implementację serwerów obsługujących wielu klientów oraz różnice między podejściem połączeniowym (TCP) a bezpołączeniowym (UDP). Każdy serwer odpowiada na proste zapytania klientów, wykonując obliczenia i zwracając wyniki.
Źródło: GeeksForGeeks
TCP to protokół połączeniowy, który zapewnia niezawodną, uporządkowaną i dwukierunkową wymianę danych między urządzeniami w sieci. W TCP każde połączenie jest inicjowane za pomocą tzw. handshake (potwierdzenie nawiązania połączenia), a przesyłane dane są podzielone na segmenty, które są numerowane i potwierdzane. Jeśli segment danych zaginie lub pojawi się w nieprawidłowej kolejności, protokół TCP automatycznie zarządza retransmisją. To sprawia, że TCP jest idealny do przesyłania danych, gdzie ważna jest integralność, np. w przeglądarce internetowej, poczcie e-mail lub przesyłaniu plików.
Serwer TCP nasłuchuje na określonym porcie i oczekuje na połączenia klientów. Po odebraniu połączenia od klienta, serwer uruchamia nowy wątek (w Javie) lub zarządza wieloma klientami jednocześnie przy użyciu funkcji select
(w C). Każdy klient może przesłać liczbę, która jest następnie przetwarzana na serwerze (obliczenie kwadratu liczby), a wynik jest odesłany do klienta. Dzięki protokołowi TCP komunikacja jest niezawodna, a serwer może zarządzać kilkoma równoczesnymi połączeniami bez utraty danych.
Klient TCP łączy się z serwerem, przesyła liczbę i odbiera wynik. Implementacja w C i Javie pozwala na nawiązanie połączenia z serwerem, wysłanie danych i odbiór wyniku. Klienty w obu językach mogą wysyłać liczby wielokrotnie w jednej sesji, co umożliwia wygodną interakcję z serwerem.
UDP to protokół bezpołączeniowy, który pozwala na szybką transmisję danych bez dodatkowego zabezpieczenia przed utratą pakietów czy konieczności potwierdzania ich dostarczenia. UDP wysyła dane w formie niezależnych datagramów, co czyni go bardzo wydajnym i minimalizuje opóźnienia w przesyle. W przeciwieństwie do TCP, UDP nie gwarantuje pełnej niezawodności, co czyni go odpowiednim do aplikacji, gdzie czas reakcji jest ważniejszy niż integralność danych, takich jak streaming wideo, gry online czy komunikacja głosowa w czasie rzeczywistym.
Serwer UDP nasłuchuje na porcie i odbiera pojedyncze datagramy z liczbami wysyłanymi przez klientów. W przeciwieństwie do TCP, UDP nie wymaga stałego połączenia, więc serwer nie tworzy nowych wątków ani nie zarządza wieloma połączeniami. Po otrzymaniu liczby serwer oblicza jej kwadrat i odsyła wynik bezpośrednio do adresu IP i portu, z którego przyszło żądanie. Jest to implementacja lekka, odpowiednia do zastosowań, w których dopuszczalna jest utrata danych lub krótkie, jednorazowe wiadomości.
Klient UDP wysyła pojedyncze liczby do serwera, a następnie oczekuje na wynik w postaci datagramu. Każdy datagram wysyłany przez klienta jest samodzielną wiadomością, co oznacza, że nie ma tu zarządzania połączeniami, a klient może szybko wysłać wiele liczb. Implementacje w C i Javie umożliwiają użytkownikowi wysyłanie liczby i odbieranie odpowiedzi, co świetnie nadaje się do testowania transmisji bezpołączeniowej.