tanszek:oktatas:informacios_rendszerek_integralasa:java_socket
This is an old revision of the document!
Table of Contents
Alapvető adattovábbítási protokollok
TCP (Transmission Control Protocol)
- Megbízható: A TCP biztosítja az adatok pontos, sorrendben történő kézbesítését, visszaigazolások és újraküldések segítségével.
- Kapcsolatorientált: A kommunikáció megkezdése előtt kapcsolatot kell létesíteni a két fél között.
- Áramlásszabályozás és zsúfoltságkezelés: Szabályozza az adatátvitel sebességét a hálózat és a végpontok aktuális állapota alapján.
- Alkalmazások: Webböngészés (HTTP/HTTPS), e-mail (SMTP, IMAP/POP3), fájlátvitel (FTP), és más, a megbízható adatátvitelt igénylő alkalmazások.
UDP (User Datagram Protocol)
- Nem megbízható: Nem garantálja az adatok sorrendjét vagy sikeres kézbesítését; nincs újraküldés vagy sorrend helyreállítás.
- Kapcsolatmentes: Nem igényel előzetes kapcsolatfelépítést az adatok küldése előtt, lehetővé téve a gyors adattovábbítást.
- Könnyűsúlyú: Kevesebb fejlécinformációt használ, ami kevesebb hálózati terhelést jelent.
- Alkalmazások: Streaming média (videó, audio), online játékok, VoIP (Voice over Internet Protocol), és más időkritikus alkalmazások, ahol a sebesség fontosabb, mint a megbízhatóság.
QUIC (Quick UDP Internet Connections) (2021-es szabvány)
- Gyors kapcsolatfelépítés: A QUIC csökkenti a kapcsolatfelépítés idejét, mivel kevesebb kézbesítési körre van szükség a kapcsolat létrehozásához, ami gyorsabb weboldal-betöltést tesz lehetővé.
- Multiplexált adatfolyam: Egyetlen QUIC-kapcsolat több adatfolyamot is képes kezelni, ezáltal csökkentve az úgynevezett “fejlécblokkolást”, ami a TCP kapcsolatokban előfordulhat.
- Párhuzamos adatátvitel: A QUIC lehetővé teszi több adatfolyam egyidejű létrehozását és kezelését egyetlen kapcsolaton belül. Ez javítja az adatátvitel hatékonyságát, mivel az egyik folyam átmeneti késése vagy blokkolása nem akadályozza a többi folyam adatátvitelét.
- Fejlécblokkolás elkerülése: A TCP-nél tapasztalt fejlécblokkolás problémája, amikor egy adott adatfolyam késleltetése blokkolja a többi folyamat adatátvitelét, a QUIC multiplexálásával teljesen megszűnik. Ezzel gyorsabb és hatékonyabb webes élményt nyújt a felhasználóknak.
- Független hiba- és áramlásszabályozás: Minden QUIC-adatfolyam saját hiba- és áramlásszabályozással rendelkezik, ami azt jelenti, hogy egy folyam problémái nem befolyásolják a többi folyam teljesítményét.
- Dinamikus prioritások: A QUIC lehetővé teszi az adatfolyamok prioritásának dinamikus módosítását, amely segít optimalizálni az erőforrások felhasználását és javítja az alkalmazások válaszidejét.
- Titkosítás: A QUIC alapértelmezés szerint biztosítja az adatok végponttól végpontig történő titkosítását, használva a TLS (Transport Layer Security) legújabb verzióit, ezáltal javítva az adatbiztonságot.
- Kapcsolat migráció: A QUIC képes fenntartani egy aktív kapcsolatot még akkor is, ha a felhasználó eszköze hálózatot vált (például Wi-Fi-ről mobil adatra), ami folyamatosabb élményt nyújt a mobil felhasználók számára.
- Áramlásszabályozás és zsúfoltságkezelés: A QUIC saját áramlásszabályozást és zsúfoltságkezelést implementál, amelyek optimalizálják az adatátvitelt a változó hálózati körülmények között.
- Alkalmazások: A QUIC-t széles körben használják webböngészéshez, videó streaminghez, online játékokhoz, és más, nagy sebességű és megbízhatóságot igénylő internetes alkalmazásokhoz.
Gyakorló feladat
Készítsen egy egyszerűsített FTP (file transport) klienst és szervert, amelynél a kliens elküldhet vagy letölthet szöveges file-okat a szerverről. Általános funkció leírás:
- ) Kliens becsatlakozik a szerverhez és küld egy listázás üzenetet
- ) Szerver visszaküldi a tárolt file-ok listáját (vagy előzőleg feltöltött file-ok listáját)
- ) Kliens kilistázza a fileokat, és bekéri a felhasználótól, hogy milyen műveletet szeretne végezni? Feltöltés vagy letöltés? ('u' vagy 'd')
- ) Mindkét esetben be kell írni a file nevét kiterjesztéssel együtt
- ) A kliens elküldi a szerverre a kiválasztott file-t, vagy letölti a kiválasztott file-t egy adott könyvtárba.
Szerver nézőpont:
- ) Becsatlakozás után felolvassa a file-okat a /store alkönyvtárból és a listázás üzenet megérkezése után a fájlneveket elküldi a kliensnek.
- ) Várakozunk a kliens 'u' vagy 'd' műveletére
- ) Klienstől kapunk egy filenevet és ha 'd' (download) a művelet, akkor felolvassuk a file-t és visszaküldjük a tartalmát
- ) Ha a művelet 'u' (feltöltés), akkor nyitunk egy új file-t a megadott néven és várjuk az adatokat, amiket kiírunk a file-ba.
Kliens nézőpont
- ) A kliens becsatlakozik és várja a visszajövő fájlok listáját, majd ha megjön akkor kiírjuk a konzolra
- ) Bekérjük a “u” vagy “d” billentyűt
- ) Majd kérjük a file-nevet is.
- ) a kliens a /files könvytárából olvassa a file-okat, vagy a letöltött file-t is ide hozza létre
- ) “d” billentyű esetén létrehozza a /files/<filename> állományt és a szerverről jövő adatokat beleírja
- ) “u” billentyű esetén a /files/<filename> állományt elküldi a szervernek
Kiinduló minták
1.) Hagyományos blokkolt TCP alapú socket szerver
Socket szerver kód
import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.ServerSocket; import java.net.Socket; public class Server { ServerSocket providerSocket; Socket connection = null; ObjectOutputStream out; ObjectInputStream in; String message; Server() { } void run() { try { // 1. szerver socket létrehozása providerSocket = new ServerSocket(8080); // 2. kapcsolódásra várakozás connection = providerSocket.accept(); // 3. Input és Output streamek megadása out = new ObjectOutputStream(connection.getOutputStream()); in = new ObjectInputStream(connection.getInputStream()); // 4. socket kommunikáció do { try { message = (String) in.readObject(); System.out.println("client>" + message); if (message.equals("bye")) { sendMessage("bye"); } } catch (ClassNotFoundException classnot) { System.err.println("Data received in unknown format"); } } while (!message.equals("bye")); } catch (IOException ioException) { ioException.printStackTrace(); } finally { // 4: kapcsolat lezárása try { in.close(); out.close(); providerSocket.close(); } catch (IOException ioException) { ioException.printStackTrace(); } } } void sendMessage(String msg) { try { out.writeObject(msg); out.flush(); System.out.println("server>" + msg); } catch (IOException ioException) { ioException.printStackTrace(); } } public static void main(String args[]) { Server server = new Server(); while (true) { server.run(); } } }
Socket kliens kód
import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.net.UnknownHostException; public class Client { Socket requestSocket; ObjectOutputStream out; ObjectInputStream in; String message; Client() { } void run() { try { // 1. socket kapcsolat létrehozása requestSocket = new Socket("localhost", 8080); // 2. Input and Output streamek out = new ObjectOutputStream(requestSocket.getOutputStream()); in = new ObjectInputStream(requestSocket.getInputStream()); // 3: Kommunikáció do { try { sendMessage("Hello szerver"); sendMessage("bye"); message = (String) in.readObject(); } catch (Exception e) { System.err.println("data received in unknown format"); } } while (!message.equals("bye")); } catch (UnknownHostException unknownHost) { System.err.println("You are trying to connect to an unknown host!"); } catch (IOException ioException) { ioException.printStackTrace(); } finally { // 4: Kapcsolat zárása try { in.close(); out.close(); requestSocket.close(); } catch (IOException ioException) { ioException.printStackTrace(); } } } void sendMessage(String msg) { try { out.writeObject(msg); out.flush(); System.out.println("client>" + msg); } catch (IOException ioException) { ioException.printStackTrace(); } } public static void main(String args[]) { Client client = new Client(); client.run(); } }
2.) Hagyományos UDP alapú kommunikáció
2.a) Az alábbi Ágens küld egy üzenetet és a 8080-as porton várja a választ rá, ugyancsak UDP-vel. Az eclipse fejlesztőkörnyezetben a consolon beírt szöveget ctrl+z leütésével lehet elküldeni.
Feladat: módosítsuk a kódot, hogy át tudjon küldeni egy beégetett nevű, és létező, 2 kbyte-nál nagyobb szöveges vagy kép állományt és ellenőrizzük a sikeres küldést.
package org.ait; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class UDPClient { public static void main(String args[]) throws Exception { BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); DatagramSocket clientSocket = new DatagramSocket(); InetAddress IPAddress = InetAddress.getByName("localhost"); byte[] sendData = new byte[1024]; byte[] receiveData = new byte[1024]; String sentence = inFromUser.readLine(); sendData = sentence.getBytes(); DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 8080); clientSocket.send(sendPacket); DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); clientSocket.receive(receivePacket); String modifiedSentence = new String(receivePacket.getData()); System.out.println("átalakítva:" + modifiedSentence); clientSocket.close(); } }
2.b) Az UDP szerver a 8080-as porton várja az ágensek üzeneteit és nagybetűre konvertálva visszaküldi a kliens UDP socketre.
package org.ait; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class UDPServer { public static void main(String args[]) throws Exception { DatagramSocket serverSocket = new DatagramSocket(8080); byte[] bytesReceived = new byte[1024]; byte[] bytesSent = new byte[1024]; DatagramPacket receivePacket = new DatagramPacket(bytesReceived, bytesReceived.length); // itt várakozik ameddig adat jön a 8080-as porton serverSocket.receive(receivePacket); String szoveg = new String(receivePacket.getData()); System.out.println("kaptam: " + szoveg); InetAddress IPAddress = receivePacket.getAddress(); int port = receivePacket.getPort(); String nagybetűsSzöveg = szoveg.toUpperCase(); bytesSent = nagybetűsSzöveg.getBytes(); // visszaküldi DatagramPacket sendPacket = new DatagramPacket(bytesSent, bytesSent.length, IPAddress, port); serverSocket.send(sendPacket); serverSocket.close(); } }
tanszek/oktatas/informacios_rendszerek_integralasa/java_socket.1709325679.txt.gz · Last modified: 2024/03/01 20:41 by knehez