Ślad: • ppz

Zajecia 10. - Obsluga sieci w Java - zadania do samodzielnego wykonania

Action unknown: siteexport_addpage
Writing /home/grochu/public_html/wiki/data/meta/zajecia/java/sidebar.meta failed
Unable to save metadata file. Hint: disk full; file permissions; safe_mode setting.

Zajecia 10. - Obsluga sieci w Java - zadania do samodzielnego wykonania

Organizacja

  • Czas: 20-30 min
  • Forma: samodzielnie lub w parach
  • Zakres: od podstaw TCP/UDP do prostych uslug HTTP

Zadanie A (latwe): Klient TCP - kalkulator sumy

Wymagania:

  • Serwer TCP odbiera linie w formacie a+b (np. 12+30)
  • Serwer zwraca wynik jako tekst
  • Klient wysyla jedno dzialanie i wyswietla odpowiedz

Wskazowki:

  • po stronie serwera uzyj split(„\+”)
  • waliduj wejscie i obsluz bledny format
  • zamykaj zasoby przez try-with-resources

Rozwiazanie (przykladowy serwer):

try (ServerSocket server = new ServerSocket(5001)) {
    while (true) {
        try (Socket client = server.accept();
             BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
             PrintWriter out = new PrintWriter(client.getOutputStream(), true)) {
 
            String expr = in.readLine();
            String[] parts = expr.split("\\+");
            if (parts.length != 2) {
                out.println("BLAD FORMATU");
                continue;
            }
            int a = Integer.parseInt(parts[0].trim());
            int b = Integer.parseInt(parts[1].trim());
            out.println(a + b);
        } catch (Exception ex) {
            // obsluga pojedynczego klienta
        }
    }
}

Zadanie B (latwe/srednie): UDP licznik wiadomosci

Wymagania:

  • Odbiorca UDP nasluchuje na porcie 6001
  • Dla kazdego datagramu wypisuje tresc i numer kolejnosci
  • Po odebraniu STOP konczy dzialanie

Wskazowki:

  • porownuj tekst po trim()
  • uzyj stalego bufora i nowego DatagramPacket na kazde receive

Rozwiazanie (przykladowe):

int counter = 0;
try (DatagramSocket socket = new DatagramSocket(6001)) {
    byte[] buffer = new byte[1024];
    while (true) {
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
        socket.receive(packet);
        String text = new String(packet.getData(), 0, packet.getLength(), StandardCharsets.UTF_8).trim();
        counter++;
        System.out.println(counter + ": " + text);
        if ("STOP".equalsIgnoreCase(text)) break;
    }
}

Zadanie C (srednie): Klient HTTP - pobieranie JSON

Wymagania:

  • Pobierz dane z endpointu HTTP GET
  • Wypisz kod statusu i 3 wybrane pola z JSON (np. id, title, completed)
  • Dodaj obsluge timeout

Wskazowki:

Rozwiazanie (przykladowe):

HttpClient client = HttpClient.newBuilder()
    .connectTimeout(Duration.ofSeconds(5))
    .build();
 
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://jsonplaceholder.typicode.com/todos/1"))
    .timeout(Duration.ofSeconds(5))
    .GET()
    .build();
 
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status: " + response.statusCode());
System.out.println(response.body());

Zadanie D (srednie+): Wielowatkowy czat TCP (wersja mini)

Wymagania:

  • Serwer akceptuje wielu klientow
  • Kazda wiadomosc klienta jest rozglaszana do pozostalych
  • Obsluz rozlaczenie klienta

Wskazowki:

  • lista klientow: CopyOnWriteArrayList<PrintWriter>
  • kazdy klient w osobnym watku
  • przed broadcast usun nieaktywne polaczenia

Rozwiazanie (szkic):

static List<PrintWriter> clients = new CopyOnWriteArrayList<>();
 
void handle(Socket socket) {
    try (socket;
         BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
         PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {
 
        clients.add(out);
        String line;
        while ((line = in.readLine()) != null) {
            for (PrintWriter c : clients) {
                if (c != out) c.println(line);
            }
        }
    } catch (IOException ignored) {
    } finally {
        // usun writer klienta z listy
    }
}

Zadanie E (trudniejsze): Mini REST API - notatki

Wymagania:

  • Serwer HTTP z endpointami:
    • GET /notes - lista notatek (JSON)
    • POST /notes - dodanie notatki (tekst)
  • Przechowywanie w pamieci (List<String>)

Wskazowki:

  • start: HttpServer.create(new InetSocketAddress(8081), 0)
  • dla POST odczytaj body z exchange.getRequestBody()
  • ustaw odpowiednie kody: 200, 201, 405

Rozwiazanie (szkic):

List<String> notes = Collections.synchronizedList(new ArrayList<>());
 
server.createContext("/notes", exchange -> {
    String method = exchange.getRequestMethod();
    if ("GET".equalsIgnoreCase(method)) {
        String json = notes.stream().map(s -> "\"" + s + "\"").collect(Collectors.joining(",", "[", "]"));
        byte[] bytes = json.getBytes(StandardCharsets.UTF_8);
        exchange.sendResponseHeaders(200, bytes.length);
        try (OutputStream os = exchange.getResponseBody()) {
            os.write(bytes);
        }
    } else if ("POST".equalsIgnoreCase(method)) {
        String body = new String(exchange.getRequestBody().readAllBytes(), StandardCharsets.UTF_8).trim();
        notes.add(body);
        exchange.sendResponseHeaders(201, -1);
    } else {
        exchange.sendResponseHeaders(405, -1);
    }
});

Zadanie F (dla chetnych): HTTPS + naglowek autoryzacji

Wymagania:

  • Wyslij zapytanie HTTPS GET z naglowkiem Authorization: Bearer …
  • Wypisz status i czas odpowiedzi
  • Dodaj retry do 3 prob dla bledow 5xx

Wskazowki:

  • zmierz czas przez System.nanoTime()
  • token przekazuj z argumentu programu albo zmiennej srodowiskowej
  • nie loguj calego tokenu

Rozwiazanie (fragment):

long start = System.nanoTime();
HttpRequest req = HttpRequest.newBuilder()
    .uri(URI.create("https://example.com/api/me"))
    .header("Authorization", "Bearer " + token)
    .GET()
    .build();
 
HttpResponse<String> res = client.send(req, HttpResponse.BodyHandlers.ofString());
long ms = (System.nanoTime() - start) / 1_000_000;
System.out.println("Status=" + res.statusCode() + ", czas=" + ms + "ms");

Kryteria oceny

  • Dzialajaca komunikacja klient-serwer
  • Poprawna obsluga bledow i timeoutow
  • Czytelnosc kodu i podzial odpowiedzialnosci
  • Plus: watki, walidacja danych, sensowne logowanie

Proponowany dobor zadan na 20-30 min

  • Grupa poczatkujaca: A + B
  • Grupa srednia: A + C + fragment D
  • Grupa zaawansowana: C + D lub E (+F dla chetnych)