Angewandte Netzwerktechnik kompakt

Material zum Buch

zu Kapitel 7 (Wireshark-Beispiele)


Im diesem ZIP-Archiv befinden sich Wireshark-Aufzeichnungen zu den Abbildungen 7.2, 7.3 und 7.4 (Verbindungsaufbau, Datenübertragung und Verbindungsabbau), sowie zu Kapitel 7.4 (gepufferte und ungepufferte Datenstreams).

zu Kapitel 7.4 (Client / Server)


Für Kapitel 7.4 stehen uns die Klassen BeispielClient und BeispielServer, sowie BeispielClientGepuffert, BeispielServerGepuffert, BeispielServerGepuffertZweiSchleifen und BeispielServerGepuffertZweiSchleifen zur Verfügung. Die letzten vier verfügen dabei im Vergleich zu den ersten über einen gepufferten OutputStream (BufferedOutputStream).

Am Ende der Seite finden Sie eine Vorschau der sich im Archiv befindlichen Java-Klassen.

zu Kapitel 7.5 (Studentenverwaltung)


Für Kapitel 7.5 (Studentenverwaltung) stehen uns im Vergleich zu dem Archiv aus Kapitel 3.3 mit dem Interface LesenSchreiben, sowie den Klassen TextIO, BinaerIO, JSON_IO, Leistung, Student, Speicher und Verwaltung zusätzlich die Klassen NetzwerkIO, NetzwerkIOServer und NetzwerkIODemoServer zur Verfügung, mit welchen sich die erzeugten Studentendaten nun auch über eine Netzwerkverbindung mit TCP/IP übertragen lassen.

Das entsprechende Ausgabeformat kann in der Klasse Verwaltung gewählt werden. Das verlinkte Archiv enthält bereits je eine erzeugte Text-, Binär- und JSON-Datei.

Am Ende der Seite finden Sie eine Vorschau der sich im Archiv befindlichen Java-Klassen.

Vorschau der Java-Klassen zu Kapitel 7.4


BeispielClient.java

import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.InetAddress;

import java.net.Socket;
import java.net.UnknownHostException;

public class BeispielClient {
	Socket linkZumServer;
	DataInputStream inFromServer;
	DataOutputStream outToServer; 

	public BeispielClient(InetAddress address, int port) throws IOException {
		linkZumServer = new Socket(address,port); // mit Server verbinden 
		System.out.println("Verbindung hergestellt");

		inFromServer = new DataInputStream(linkZumServer.getInputStream());
		outToServer = new DataOutputStream(linkZumServer.getOutputStream());
	}

	public void tuWas(int repeat) throws IOException {
		int summe;
		
		for(int i=0; i < repeat; i++) {
			outToServer.writeInt(i); 
			outToServer.writeInt(i+1); 
			System.out.print("Client gesendet: "+ i + ",  "+ (i+1));
			
			summe = inFromServer.readInt(); 
			System.out.println(" empfangen: "+summe);
		}
	}

	public void disconnect() throws IOException {
		inFromServer.close();
		outToServer.close();
		linkZumServer.close();
		System.out.println("Verbindung getrennt");
	}

	public static void main(String[] args) throws UnknownHostException, IOException {
		BeispielClient meinClient = new BeispielClient(InetAddress.getByName("127.0.0.1"),4711);

		meinClient.tuWas(100);

		meinClient.disconnect();
	}
}

BeispielClientGepuffert.java

import java.io.IOException;

import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.InetAddress;

import java.net.Socket;
import java.net.UnknownHostException;

public class BeispielClientGepuffert {
	Socket linkZumServer;
	DataInputStream inFromServer;
	DataOutputStream outToServer; 

	public BeispielClientGepuffert(InetAddress address, int port) throws IOException {
		linkZumServer = new Socket(address,port); // mit Server verbinden 
		System.out.println("Verbindung hergestellt");

		inFromServer = new DataInputStream(linkZumServer.getInputStream());
		outToServer = new DataOutputStream(new BufferedOutputStream(linkZumServer.getOutputStream()));
	}

	public void tuWas(int repeat) throws IOException {
		int summe;

		for(int i=0; i < repeat; i++) {
			outToServer.writeInt(i); 
			outToServer.writeInt(i+1); 
			System.out.print("Client gesendet: "+ i + ",  "+ (i+1));
			outToServer.flush();
			
			summe = inFromServer.readInt(); 
			System.out.println(" empfangen: "+summe);
		}
	}

	public void disconnect() throws IOException {
		inFromServer.close();
		outToServer.close();
		linkZumServer.close();
		System.out.println("Verbindung getrennt");
	}

	public static void main(String[] args) throws UnknownHostException, IOException {
		BeispielClientGepuffert meinClient = new BeispielClientGepuffert(InetAddress.getByName("127.0.0.1"),4711);

		meinClient.tuWas(100);

		meinClient.disconnect();
	}
}

BeispielClientGepuffertZweiSchleifen.java

import java.io.IOException;

import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.InetAddress;

import java.net.Socket;
import java.net.UnknownHostException;

public class BeispielClientGepuffertZweiSchleifen {
	Socket linkZumServer;
	DataInputStream inFromServer;
	DataOutputStream outToServer; 

	public BeispielClientGepuffertZweiSchleifen(InetAddress address, int port) throws IOException {
		linkZumServer = new Socket(address,port); // mit Server verbinden 
		System.out.println("Verbindung hergestellt");

		inFromServer = new DataInputStream(linkZumServer.getInputStream());
		outToServer = new DataOutputStream(new BufferedOutputStream(linkZumServer.getOutputStream()));
	}

	public void tuWas(int repeat) throws IOException {
		int summe;

		for(int i=0; i < repeat; i++) {
			outToServer.writeInt(i); 
			outToServer.writeInt(i+1); 
			System.out.println("Client gesendet: "+ i + ",  "+ (i+1));
		}
		outToServer.flush();
		
		for(int i=0; i < repeat; i++) {
			summe = inFromServer.readInt(); 
			System.out.println(" empfangen: "+summe);
		}
	}

	public void disconnect() throws IOException {
		inFromServer.close();
		outToServer.close();
		linkZumServer.close();
		System.out.println("Verbindung getrennt");
	}

	public static void main(String[] args) throws UnknownHostException, IOException {
		BeispielClientGepuffertZweiSchleifen meinClient = new BeispielClientGepuffertZweiSchleifen(InetAddress.getByName("127.0.0.1"),4711);

		meinClient.tuWas(100);

		meinClient.disconnect();
	}
}

BeispielServer.java

import java.io.IOException;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class BeispielServer {
	
	ServerSocket serverSocket;
	Socket linkZumClient;
	DataInputStream inFromClient;
	DataOutputStream outToClient; 
	
	public BeispielServer( int port) throws IOException {
		serverSocket = new ServerSocket(port); // Socket erzeugen
		System.out.println("Server gestartet.");
	
		linkZumClient = serverSocket.accept(); // warten bis sich Client verbindet 
		System.out.println("Verbindung hergestellt.");
		
		inFromClient = new DataInputStream(linkZumClient.getInputStream());
		outToClient = new DataOutputStream(linkZumClient.getOutputStream());
	}
	
	public void tuWas(int repeat) throws IOException {
		int zahl1;
		int zahl2;
		int summe;

		for(int i = 0;  i < repeat; i++) {
			zahl1 = inFromClient.readInt();
			zahl2 = inFromClient.readInt(); 
			System.out.print("Server Empfangen: "+ zahl1 + ", "+ zahl2);
			summe = zahl1 + zahl2; 
			outToClient.writeInt(summe); 
			System.out.println(" gesendet: "+summe);
		}
	}
	
	public void disconnect() throws IOException {
		inFromClient.close();
		outToClient.close();
		linkZumClient.close();
		serverSocket.close();
		System.out.println("Server beendet.");
	}
	
	public static void main(String[] args) throws IOException {
		BeispielServer meinServer = new BeispielServer(4711);
	
		meinServer.tuWas(100);
		
		meinServer.disconnect();
	}
}

BeispielServerGepuffert.java

import java.io.IOException;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class BeispielServerGepuffert {
	
	ServerSocket serverSocket;
	Socket linkZumClient;
	DataInputStream inFromClient;
	DataOutputStream outToClient; 
	
	public BeispielServerGepuffert( int port) throws IOException {
		serverSocket = new ServerSocket(port); // Socket erzeugen
		System.out.println("Server gestartet.");
	
		linkZumClient = serverSocket.accept(); // warten bis sich Client verbindet 
		System.out.println("Verbindung hergestellt.");
		
		inFromClient = new DataInputStream(linkZumClient.getInputStream());
		outToClient = new DataOutputStream(new BufferedOutputStream(linkZumClient.getOutputStream()));
	}
	
	public void tuWas(int repeat) throws IOException {
		int zahl1;
		int zahl2;
		int summe;

		for(int i = 0;  i < repeat; i++) {
			zahl1 = inFromClient.readInt();
			zahl2 = inFromClient.readInt(); 
			System.out.print("Server Empfangen: "+ zahl1 + ", " + zahl2);
			summe = zahl1 + zahl2; 
			outToClient.writeInt(summe); 
			outToClient.flush();
			System.out.println(" gesendet: "+summe);
		}
	}

	public void disconnect() throws IOException {
		inFromClient.close();
		outToClient.close();
		linkZumClient.close();
		serverSocket.close();
		System.out.println("Server beendet.");
	}
	
	public static void main(String[] args) throws IOException {
		BeispielServerGepuffert meinServer = new BeispielServerGepuffert(4711);
	
		meinServer.tuWas(100);
		
		meinServer.disconnect();
	}
}

BeispielServerGepuffertZweiSchleifen.java

import java.io.IOException;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class BeispielServerGepuffertZweiSchleifen {
	
	ServerSocket serverSocket;
	Socket linkZumClient;
	DataInputStream inFromClient;
	DataOutputStream outToClient; 
	
	public BeispielServerGepuffertZweiSchleifen( int port) throws IOException {
		serverSocket = new ServerSocket(port); // Socket erzeugen
		System.out.println("Server gestartet.");
	
		linkZumClient = serverSocket.accept(); // warten bis sich Client verbindet 
		System.out.println("Verbindung hergestellt.");
		
		inFromClient = new DataInputStream(linkZumClient.getInputStream());
		outToClient = new DataOutputStream(new BufferedOutputStream(linkZumClient.getOutputStream()));
	}
	
	public void tuWas(int repeat) throws IOException {
		int zahl1;
		int zahl2;
		int summe;

		for(int i = 0;  i < repeat; i++) {
			zahl1 = inFromClient.readInt();
			zahl2 = inFromClient.readInt(); 
			System.out.print("Server Empfangen: "+ zahl1 + ", " + zahl2);
			summe = zahl1 + zahl2; 
			outToClient.writeInt(summe); 
			System.out.println(" gesendet: "+summe);
		}
		outToClient.flush();
	}

	public void disconnect() throws IOException {
		inFromClient.close();
		outToClient.close();
		linkZumClient.close();
		serverSocket.close();
		System.out.println("Server beendet.");
	}
	
	public static void main(String[] args) throws IOException {
		BeispielServerGepuffertZweiSchleifen meinServer = new BeispielServerGepuffertZweiSchleifen(4711);
	
		meinServer.tuWas(100);
		
		meinServer.disconnect();
	}
}

Vorschau der Java-Klassen zu Kapitel 7.5


BinaerIO.java

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class BinaerIO implements LesenSchreiben {

	String dateiName;
	
	BinaerIO(String dateiName)
	{
		this.dateiName = dateiName;
	}
	
	@Override
	public void schreibeDatei(Student[] studenten) throws IOException {
		FileOutputStream fos = new FileOutputStream(dateiName);
		DataOutputStream dos = new DataOutputStream(fos);
		
		if(studenten != null) {
			dos.writeInt(studenten.length);
			for(int i=0; i < studenten.length; i++) {
				dos.writeInt(studenten[i].matrikelNummer);
				dos.writeUTF(studenten[i].name);
				if(studenten[i].leistungen != null) {
					dos.writeInt(studenten[i].leistungen.length);

					for(int j=0; j < studenten[i].leistungen.length; j++) {
						dos.writeUTF(studenten[i].leistungen[j].modul);
						dos.writeDouble(studenten[i].leistungen[j].note);
					}
				}
				else
					dos.writeInt(0);	
			}
		}
		else
			dos.writeInt(0);
		dos.close();
		fos.close();
	}

	@Override
	public Student[] leseDatei() throws IOException {
		Student[] geleseneStudenten;

		FileInputStream fis = new FileInputStream(dateiName);
		DataInputStream dis = new DataInputStream(fis);

		int studCnt = dis.readInt();
		if(studCnt != 0)
		{
			geleseneStudenten = new Student[studCnt];
			for(int i=0; i < studCnt; i++) {
				geleseneStudenten[i] = new Student();
				geleseneStudenten[i].matrikelNummer = dis.readInt();
				geleseneStudenten[i].name = dis.readUTF();
				int leistCnt = dis.readInt();

				if(leistCnt != 0) {
					geleseneStudenten[i].leistungen = new Leistung[leistCnt];
					for(int j=0; j < leistCnt; j++) {
						geleseneStudenten[i].leistungen[j] = new Leistung();
						geleseneStudenten[i].leistungen[j].modul = dis.readUTF();
						geleseneStudenten[i].leistungen[j].note = dis.readDouble();
					}
				}
				else
					geleseneStudenten[i].leistungen = null;	
			}

		}
		else
			geleseneStudenten = null;

		dis.close();
		fis.close();
		return geleseneStudenten;
	}
	

}

JSON_IO.java

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class JSON_IO implements LesenSchreiben {
	
	String dateiName;
	Gson gson;
	
	JSON_IO(String dateiName) {
		this.dateiName = dateiName;
		gson = new GsonBuilder().create();
	}
	
	@Override
	public void schreibeDatei(Student[] studenten) throws IOException {
		FileOutputStream fos = new FileOutputStream(dateiName);
		OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
		
		gson.toJson(studenten,osw);
		
		osw.close();
		fos.close();
	}

	@Override
	public Student[] leseDatei() throws IOException {
		Student[] geleseneStudenten;
		FileInputStream fis = new FileInputStream(dateiName);
		InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
		
		geleseneStudenten = gson.fromJson(isr,Student[].class);
		
		isr.close();
		fis.close();
		
		return geleseneStudenten;
	}
	
}

Leistung.java

public class Leistung {
	String modul;
	double note;
}

//
// 4711 - Hans Muster
// Leistungen - REN 1,0
// 		      - GdaT 5,0
// 4712 - Erika Muster
// Leistungen - keine also Wert == null

LesenSchreiben.java

import java.io.IOException;

// Interface, das das Lesen und Schreiben der Datensätze kapselt
// Dateinamen/Netzwerkadressen werden im Konstruktur der Klasse behandelt, 
// die instantiiert wird. 
public interface LesenSchreiben {
	void schreibeDatei(Student[] studenten) throws IOException;
    Student [] leseDatei() 	throws IOException;
}

NetzwerkIO.java

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class NetzwerkIO implements LesenSchreiben {
	String server;
	int port;
	Socket linkZumServer;
	DataInputStream datenEmpfang;
	DataOutputStream datenVersand;
	boolean verbindungSteht;
	
	NetzwerkIO(String serverURL, int serverPort) {
		server = serverURL;
		port = serverPort;
		verbindungSteht = false;
	}
		
	void VerbindungAufbauen() throws UnknownHostException, InterruptedException {
		while(!verbindungSteht) {
			try {

				linkZumServer = new Socket(server,port);
				System.out.println("Verbunden mit " + linkZumServer.getInetAddress() + ":" + linkZumServer.getPort());
				datenEmpfang = new DataInputStream(new BufferedInputStream(linkZumServer.getInputStream()));
				datenVersand = new DataOutputStream(new BufferedOutputStream(linkZumServer.getOutputStream()));
				verbindungSteht = true;
			}
			catch (IOException e) {
				System.out.println("Verbindungsaufbau gescheitert" + e);
				verbindungSteht = false;
				VerbindungAbbauen();
				Thread.sleep(10000);
			}
		}
	}


	void VerbindungAbbauen()  {
		try {
			verbindungSteht = false;
			datenVersand.close();
			datenEmpfang.close();
			linkZumServer.close();
		}
		catch (IOException e) {
			System.out.println("Abbau mit Exception "+e);
		}
	}

	@Override
	public void schreibeDatei(Student[] studenten) throws IOException {
		if(!verbindungSteht)
		{
			try {
				VerbindungAufbauen();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		DataOutputStream dos = new DataOutputStream(datenVersand);
		
		if(studenten != null) {
			dos.writeInt(studenten.length);
			for(int i=0; i < studenten.length; i++) {
				dos.writeInt(studenten[i].matrikelNummer);
				dos.writeUTF(studenten[i].name);
				if(studenten[i].leistungen != null) {
					dos.writeInt(studenten[i].leistungen.length);

					for(int j=0; j < studenten[i].leistungen.length; j++) {
						dos.writeUTF(studenten[i].leistungen[j].modul);
						dos.writeDouble(studenten[i].leistungen[j].note);
					}
				}
				else
					dos.writeInt(0);	
			}
		}
		else
			dos.writeInt(0);
		dos.flush();
		dos.close();
		VerbindungAbbauen();
	}

	@Override
	public Student[] leseDatei() throws IOException {
		Student[] geleseneStudenten;
		
		if(!verbindungSteht)
		{
			try {
				VerbindungAufbauen();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	
		DataInputStream dis = new DataInputStream(datenEmpfang);

		int studCnt = dis.readInt();
		if(studCnt != 0)
		{
			geleseneStudenten = new Student[studCnt];
			for(int i=0; i < studCnt; i++) {
				geleseneStudenten[i] = new Student();
				geleseneStudenten[i].matrikelNummer = dis.readInt();
				geleseneStudenten[i].name = dis.readUTF();
				int leistCnt = dis.readInt();

				if(leistCnt != 0) {
					geleseneStudenten[i].leistungen = new Leistung[leistCnt];
					for(int j=0; j < leistCnt; j++) {
						geleseneStudenten[i].leistungen[j] = new Leistung();
						geleseneStudenten[i].leistungen[j].modul = dis.readUTF();
						geleseneStudenten[i].leistungen[j].note = dis.readDouble();
					}
				}
				else
					geleseneStudenten[i].leistungen = null;	
			}

		}
		else
			geleseneStudenten = null;

		dis.close();
		VerbindungAbbauen();
		return geleseneStudenten;
	}
	

}

NetzwerkIODemoServer.java

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

public class NetzwerkIODemoServer {
	
	ServerSocket serverSocket;
	int port;
	Socket linkZumClient;
	DataInputStream vomClient;
	DataOutputStream zumClient;
	boolean verbindungSteht;

	NetzwerkIODemoServer(int portNr) {
		port = portNr;
		verbindungSteht = false;
	}
	
	void VerbindungAufbauen() throws UnknownHostException, InterruptedException {
		while(!verbindungSteht) {
			try {
				serverSocket = new ServerSocket(port);
				System.out.println("Warte auf Verbindung");
				linkZumClient = serverSocket.accept();
				System.out.println("Verbunden mit " + linkZumClient.getInetAddress() + ":" + linkZumClient.getPort());
				vomClient = new DataInputStream(linkZumClient.getInputStream());
				zumClient = new DataOutputStream(linkZumClient.getOutputStream());
				verbindungSteht = true;
			}
			catch (IOException e) {
				System.out.println("Verbindungsaufbau gescheitert" + e);
				verbindungSteht = false;
				VerbindungAbbauen();
			}
		}
	}

	void VerbindungAbbauen()  {
		try {
			verbindungSteht = false;
			zumClient.close();
			vomClient.close();
			linkZumClient.close();
			serverSocket.close();
		}
		catch (IOException e) {
			System.out.println("Abbau mit Exception "+e);
		}
	}
	
	public void schreibeDatei(String dateiName, Student[] studenten) throws IOException, InterruptedException {
		DataOutputStream dos = new DataOutputStream(zumClient);
		
		if(studenten != null) {
			dos.writeInt(studenten.length);
			for(int i=0; i < studenten.length; i++) {
				dos.writeInt(studenten[i].matrikelNummer);
				dos.writeUTF(studenten[i].name);
				System.out.print("geschrieben: "+studenten[i].name);
				if(studenten[i].leistungen != null) {
					dos.writeInt(studenten[i].leistungen.length);

					for(int j=0; j < studenten[i].leistungen.length; j++) {
						dos.writeUTF(studenten[i].leistungen[j].modul);
						dos.writeDouble(studenten[i].leistungen[j].note);
					}
				}
				else
					dos.writeInt(0);	
				System.out.println(" mit Noten.");
			}
		}
		else
			dos.writeInt(0);
		dos.flush();
		//Thread.sleep(10000);
		dos.close();
		VerbindungAbbauen();
	}

	public Student[] leseDatei(String dateiName) throws IOException, InterruptedException {
		Student[] geleseneStudenten;
		
		DataInputStream dis = new DataInputStream(vomClient);

		int studCnt = dis.readInt();
		if(studCnt != 0)
		{
			geleseneStudenten = new Student[studCnt];
			for(int i=0; i < studCnt; i++) {
				geleseneStudenten[i] = new Student();
				geleseneStudenten[i].matrikelNummer = dis.readInt();
				geleseneStudenten[i].name = dis.readUTF();
				System.out.print("gelesen: "+geleseneStudenten[i].name);
				int leistCnt = dis.readInt();
				if(leistCnt != 0) {
					geleseneStudenten[i].leistungen = new Leistung[leistCnt];
					for(int j=0; j < leistCnt; j++) {
						geleseneStudenten[i].leistungen[j] = new Leistung();
						geleseneStudenten[i].leistungen[j].modul = dis.readUTF();
						geleseneStudenten[i].leistungen[j].note = dis.readDouble();
					}
				}
				else
					geleseneStudenten[i].leistungen = null;	
				System.out.println(" mit  Noten.");
			}
		}
		else
			geleseneStudenten = null;

		dis.close();
		//Thread.sleep(10000);
		VerbindungAbbauen();
		return geleseneStudenten;
	}
	


	public static void main(String[] args) throws InterruptedException, IOException {
		NetzwerkIODemoServer server = new NetzwerkIODemoServer(4711);
		
		server.VerbindungAufbauen();
		
		// Datei lesen
		System.out.println("Lese Datei");
		Student[] gelesen = server.leseDatei("Datei");
		
		server.VerbindungAufbauen();
		
		// Datei zurücksenden
		System.out.println("Schreibe Datei");
		server.schreibeDatei("Datei", gelesen);
	
		server.VerbindungAbbauen();
	}

}

NetzwerkIOServer.java

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

public class NetzwerkIOServer extends NetzwerkIO {
	ServerSocket serverSocket;
	Socket linkZumClient;

	NetzwerkIOServer(int serverPort) {
		super("egal",serverPort);
	}
	
	@Override
	void VerbindungAufbauen() throws UnknownHostException, InterruptedException {
		while(!verbindungSteht) {
			try {
				serverSocket = new ServerSocket(port);
				System.out.println("Warte auf Verbindung");
				linkZumClient = serverSocket.accept();
				System.out.println("Verbunden mit " + linkZumClient.getInetAddress() + ":" + linkZumClient.getPort());
				datenEmpfang = new DataInputStream(new BufferedInputStream(linkZumClient.getInputStream()));
				datenVersand = new DataOutputStream(new BufferedOutputStream(linkZumClient.getOutputStream()));
				verbindungSteht = true;
			}
			catch (IOException e) {
				System.out.println("Verbindungsaufbau gescheitert" + e);
				verbindungSteht = false;
				VerbindungAbbauen();
			}
		}
	}

	@Override
	void VerbindungAbbauen()  {
		try {
			verbindungSteht = false;
			datenVersand.close();
			datenEmpfang.close();
			linkZumClient.close();
			serverSocket.close();
		}
		catch (IOException e) {
			System.out.println("Abbau mit Exception "+e);
		}
	}

	public static void main(String[] args) throws InterruptedException, IOException {
		NetzwerkIOServer server = new NetzwerkIOServer(4711);
		
		server.VerbindungAufbauen();
		
		// Datei vom Client lesen
		System.out.println("Lese Datei");
		Student[] gelesen = server.leseDatei();
		
		server.VerbindungAufbauen();
		
		// Datei an Client zuruecksenden
		System.out.println("Schreibe Datei");
		server.schreibeDatei(gelesen);
	
		server.VerbindungAbbauen();	}
}

Speicher.java

public class Speicher {
	// Array, das die Studenten speichert
	// Kniff: Der Inhalt des Speichers existiert nur einmal, da static
	private static final Student[] studenten;

	// Kniff: Der Inhalt des Speichers wird durch diese Methode beim ersten Zugriff erzeugt
	static
	{
		// Datensaetze erzeugen
		studenten = Speicher.fuelleMitUnsinn(100);
	}

	// Methoden fuer den Zugriff auf die gespeicherten Daten
	public static Student[] getStudenten()
	{
		return studenten;
	}

	public static Student getSucheMatrikelNummerZuName(String name)
	{
		for(Student s : studenten)
		{
			if(s.name.equals(name))
			{
				return s;
			}
		}
		return null;
	}

	public static Student getStudentenInfoZuMatrikelNummer(int matrikelNummer)
	{
		for(Student s : studenten)
		{
			if(s.matrikelNummer == matrikelNummer)
			{
				return s;
			}
		}	
		return null;
	}	

	// Utility-Methoden
	public static Student[] fuelleMitUnsinn(int Zahl)
	{
		// Hilfsvariablen zum Erzeugen von Datensaetzen
		  final String [] vornamen = { "Mia","Ben","Emma","Jonas","Hannah","Leon","Sofia","Finn","Anna","Elias"};
		  final String [] nachnamen = {"Bauer","Becker","Fischer","Fuchs","Hartmann","Lang", "Jung","Hofmann","Huber"};
		  final String [] module = {"Analysis A","Lineare Algebra A","Analysis B","Lineare Algebra B","Numerik A",
				"Stochastik A","Stochastik B","Numerik partieller Differentialgleichungen 1","Numerik partieller Differentialgleichungen 2",
				"Baumechanik I (Statik starrer Koerper)","Baumechanik II (Elastomechanik)","Baumechanik III (Kinematik und Kinetik)",
				"Kontinuumsmechanik I","Modellbildung im Ingenieurwesen","Numerische Mechanik","Festkoerpermechanik","Finite Elemente II",
				"Grundlagen der Elektrotechnik","Umweltbiologie und -chemie","Stroemungsmechanik","Thermodynamik im Ueberblick",
				"Datenstrukturen, Algorithmen und Programmierung","Datenbanksysteme im Ingenieurwesen","Graphen und Netze","Baustoffkunde I",
				"Baustoffkunde II","Ausgleichungsrechnung und Statistik I","Ausgleichungsrechnung und Statistik II",
		"Projekte des Ingenieurwesens" };

		Student[] unsinn = new Student[Zahl];

		for(int i=0; i < Zahl; i++) {
			unsinn[i]=new Student();
			int vn_indx = (int)(Math.random()*vornamen.length);
			int nn_indx = (int)(Math.random()*nachnamen.length);
			unsinn[i].name = vornamen[vn_indx] + " " + nachnamen[nn_indx];
			unsinn[i].matrikelNummer = vn_indx * 100 + nn_indx + i * 10000;
			int notenZahl = (int)(Math.random()*8);
			if(notenZahl >= 1) {
				unsinn[i].leistungen = new Leistung[notenZahl];
				for(int j=0; j < notenZahl; j++) {
					int mod_indx = (int)(Math.random()*module.length);
					unsinn[i].leistungen[j] = new Leistung();
					unsinn[i].leistungen[j].modul = module[mod_indx];
					unsinn[i].leistungen[j].note = (int)(Math.random()*5) + 1;
				}
			}
			else
				unsinn[i].leistungen = null;
		}
		return unsinn;
	}

	public static boolean sindArraysGleich(Student[] a, Student[] b) {
		boolean istUnGleich = false;
		if(a.length == b.length)
		{
			for(int i=0; i < a.length; i++) {
				istUnGleich |= a[i].matrikelNummer != b[i].matrikelNummer;
				istUnGleich |= !(a[i].name.equals(b[i].name));
				if(a[i].leistungen != null) {
					for(int j=0; j < a[i].leistungen.length; j++) {
						istUnGleich |= !(a[i].leistungen[j].modul.equals(b[i].leistungen[j].modul)) ;
						istUnGleich |= a[i].leistungen[j].note != b[i].leistungen[j].note ;
					}
				}
				if(istUnGleich)
					System.out.println("Ungleich a="+ a + "| b=" + b);
			}
		}
		else
			istUnGleich = true;

		return !istUnGleich;
	}
}

Student.java

public class Student {
	int matrikelNummer;
	String name;
	Leistung[] leistungen;
}

TextIO.java

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Scanner;

public class TextIO implements LesenSchreiben {

	String dateiName;
	
	TextIO(String dateiName)
	{
		this.dateiName = dateiName;
	}
	
	@Override
	public void schreibeDatei(Student[] studenten) throws IOException {
		FileOutputStream fos = new FileOutputStream(dateiName);
		OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF8");	
		
		// string.format()
		String toWrite;
		
		if(studenten != null) {
			// zu schreibenden Text aus einzelnen Elementen zusammensetzen
			toWrite = String.format("%d",studenten.length );
			// Elemente mit ; und Leerzeichen trennen
			toWrite += "; ";
			// Text als Zeile schreiben
			toWrite += "\n";
			osw.write(toWrite);
	
			for(int i=0; i < studenten.length; i++) {
				// neuen Text beginnen
				toWrite = String.format("%d; %s; ",
						studenten[i].matrikelNummer,
						studenten[i].name);
				if(studenten[i].leistungen != null) {
					// Text ergänzen
					toWrite += String.format("%d; ",studenten[i].leistungen.length);

					for(int j=0; j < studenten[i].leistungen.length; j++) {
						toWrite += String.format("%s; %3.1f; ",
								studenten[i].leistungen[j].modul,
								studenten[i].leistungen[j].note);
					}
				}
				else
					toWrite += "0; ";
				// Text / Datensatz eines Studenten als Zeile ausgeben
				toWrite += "\n";
				osw.write(toWrite);
			}
		}
		else
		{
			toWrite = "0; \n";
			osw.write(toWrite);
		}
		osw.close();
		fos.close();
	}

	@Override
	public Student[] leseDatei() throws IOException {
		Student[] geleseneStudenten;

		FileInputStream fis = new FileInputStream(dateiName);
		
		// Einen Scanner erzeugen, der den Stream von Trennzeichen zu Trennzeichen liest
			Scanner scan = new Scanner(fis,"UTF8");
			// ; mit oder ohne folgenden Whitespace (Leerzeichen, Tabulator, Zeilenvorschub)
			// als Trennzeichen festlegen
			scan.useDelimiter(";\\s*");
		
		int studCnt = scan.nextInt();
		if(studCnt != 0)
		{
			geleseneStudenten = new Student[studCnt];
			for(int i=0; i < studCnt; i++) {
				geleseneStudenten[i] = new Student();
				geleseneStudenten[i].matrikelNummer = scan.nextInt();
				geleseneStudenten[i].name = scan.next();
				int leistCnt = scan.nextInt();
				if(leistCnt != 0) {
					geleseneStudenten[i].leistungen = new Leistung[leistCnt];
					for(int j=0; j < leistCnt; j++) {
						geleseneStudenten[i].leistungen[j] = new Leistung();
						geleseneStudenten[i].leistungen[j].modul = scan.next(); 
						geleseneStudenten[i].leistungen[j].note = scan.nextDouble();
					}
				}
				else
					geleseneStudenten[i].leistungen = null;	
			}

		}
		else
			geleseneStudenten = null;

		scan.close();
		fis.close();
		return geleseneStudenten;
	}
	

}

Verwaltung.java

import java.io.IOException;

public class Verwaltung {
	public static void main(String[] args) throws IOException, InterruptedException {
		// Studenten aus dem Speicher abfragen
		Student[] studenten = Speicher.getStudenten();
					
		// Dateihandlerinstanz erzeugen
		LesenSchreiben leseSchreibe = new  
		//		BinaerIO("BinaerDatei");
		//		TextIO("Textdatei");
		//		JSON_IO("JSON-Datei");
				NetzwerkIO("127.0.0.1", 4711);
		
		// Datei schreiben
		leseSchreibe.schreibeDatei(studenten);
		System.out.println("Array geschrieben");
		
		// Kurze Wartezeit, simuliert Verarbeitung
		Thread.sleep(1000);
		
		// Datei lesen
		Student[] zurueckGelesen = leseSchreibe.leseDatei();
		System.out.println("Array gelesen");
		
		// Vergleichen
		if(Speicher.sindArraysGleich(studenten, zurueckGelesen))
			System.out.println("Arrays sind gleich");
		else
			System.out.println("Arrays sind ungleich");
	}
}