====== 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