====== Zajecia 10. - Obsluga sieci w Java - cwiczenia demonstracyjne (hands-on) ====== ===== Organizacja czesci praktycznej ===== * Czas: 20-30 min * Forma: prowadzacy koduje na zywo, grupa odtwarza kroki * Cel: od prostego ECHO TCP do mini HTTP API ===== Proponowana kolejnosc demo ===== * Demo 1 (latwe): ECHO TCP klient-serwer * Demo 2 (latwe/srednie): UDP ping (datagram) * Demo 3 (srednie): HTTP klient z ''HttpClient'' * Demo 4 (srednie+): mini serwer HTTP * Demo 5 (opcjonalne): podstawowe retry + timeout ===== Demo 1: ECHO TCP (latwe) ===== Cel: * poznac ''ServerSocket'', ''Socket'', strumienie tekstowe Wskazowki: * serwer: petla ''accept()'' * klient: ''println'' + ''readLine'' * uruchom serwer przed klientem Rozwiazanie - serwer: import java.io.*; import java.net.*; public class EchoTcpServer { public static void main(String[] args) throws IOException { try (ServerSocket server = new ServerSocket(5000)) { System.out.println("Serwer TCP: 5000"); while (true) { Socket client = server.accept(); new Thread(() -> handle(client)).start(); } } } private static void handle(Socket client) { try (client; BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream())); PrintWriter out = new PrintWriter(client.getOutputStream(), true)) { String line = in.readLine(); out.println("ECHO: " + line); } catch (IOException e) { e.printStackTrace(); } } } Rozwiazanie - klient: import java.io.*; import java.net.*; public class EchoTcpClient { public static void main(String[] args) throws IOException { try (Socket socket = new Socket("127.0.0.1", 5000); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) { out.println("Ala ma kota"); System.out.println(in.readLine()); } } } ===== Demo 2: UDP ping (latwe/srednie) ===== Cel: * poznac ''DatagramSocket'' i ''DatagramPacket'' Wskazowki: * bufor odbiorczy ustaw np. na 1024 bajty * uzyj ''packet.getLength()'' przy odczycie * UDP nie gwarantuje dostarczenia Rozwiazanie - odbiorca: import java.net.*; import java.nio.charset.StandardCharsets; public class UdpReceiver { public static void main(String[] args) throws Exception { try (DatagramSocket socket = new DatagramSocket(6000)) { byte[] buffer = new byte[1024]; DatagramPacket packet = new DatagramPacket(buffer, buffer.length); socket.receive(packet); String text = new String(packet.getData(), 0, packet.getLength(), StandardCharsets.UTF_8); System.out.println("Odebrano: " + text); } } } Rozwiazanie - nadawca: import java.net.*; import java.nio.charset.StandardCharsets; public class UdpSender { public static void main(String[] args) throws Exception { try (DatagramSocket socket = new DatagramSocket()) { byte[] data = "ping-udp".getBytes(StandardCharsets.UTF_8); DatagramPacket packet = new DatagramPacket( data, data.length, InetAddress.getByName("127.0.0.1"), 6000 ); socket.send(packet); } } } ===== Demo 3: HTTP klient (srednie) ===== Cel: * wykonac zapytanie GET przez ''HttpClient'' Wskazowki: * ustaw timeout po stronie klienta * wypisz ''statusCode'' i fragment odpowiedzi * przy bledach sieciowych obsluz ''IOException'' Rozwiazanie: import java.net.URI; import java.net.http.*; import java.time.Duration; public class HttpGetDemo { public static void main(String[] args) throws Exception { HttpClient client = HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(5)) .build(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://api.github.com")) .header("Accept", "application/json") .GET() .build(); HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println("Status: " + response.statusCode()); System.out.println(response.body().substring(0, Math.min(200, response.body().length()))); } } ===== Demo 4: Mini serwer HTTP (srednie+) ===== Cel: * przygotowac endpoint ''/time'' zwracajacy JSON Wskazowki: * uzyj ''com.sun.net.httpserver.HttpServer'' * ustaw ''Content-Type'' i kod odpowiedzi 200 * zamknij ''OutputStream'' po zapisie odpowiedzi Rozwiazanie: import com.sun.net.httpserver.HttpServer; import java.io.OutputStream; import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; import java.time.Instant; public class MiniHttpServer { public static void main(String[] args) throws Exception { HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0); server.createContext("/time", exchange -> { String body = "{\"time\":\"" + Instant.now() + "\"}"; exchange.getResponseHeaders().add("Content-Type", "application/json; charset=utf-8"); byte[] bytes = body.getBytes(StandardCharsets.UTF_8); exchange.sendResponseHeaders(200, bytes.length); try (OutputStream os = exchange.getResponseBody()) { os.write(bytes); } }); server.start(); System.out.println("HTTP server: http://localhost:8080/time"); } } ===== Demo 5 (opcjonalne): retry i timeout ===== Cel: * pokazac podejscie do niestabilnej sieci Wskazowki: * ogranicz liczbe prob (np. 3) * roznicuj opoznienie miedzy probami * retry glownie dla bledow 5xx i timeout Rozwiazanie: for (int attempt = 1; attempt <= 3; attempt++) { try { HttpResponse r = client.send(request, HttpResponse.BodyHandlers.ofString()); if (r.statusCode() < 500) { System.out.println("OK w probie " + attempt); break; } } catch (Exception e) { if (attempt == 3) throw e; } Thread.sleep(200L * attempt); } ===== Szybki plan 20-30 minut ===== * Wariant 20 min: Demo 1 + Demo 3 * Wariant 30 min: Demo 1 + Demo 2 + Demo 4 * Dla zaawansowanej grupy: dorzuc Demo 5