Socket Einfache Client/Server-Anwendung

Serbel

Mitglied
Hallo Leute,
Ich habe gerade erst begonnen mich mit der Client Server Programmierung zu beschäftigen und bin deshalb noch ein Anfänger in diesem Bereich. Ich wollte einfach mal eine ganz kleine Client-Server-Anwendung programmieren. Der Server soll lediglich einen Text zum Client schicken und der Client soll diesen Text einfach lesen uns ausgeben. Jedoch funktioniert das nicht so ganz. Hier ist mal der Quellcode für den Client und den Server

Server
Java:
import java.io.*;
import java.net.*;


public class Server {
	public static void main(String[] args) {
		try {
			int port = Integer.parseInt(args[0]); // Kann eine ArrayIndexOutOfBound Exception werfen, aber auch eine NumberForamtException--> Beide Exceptions müssen aber nicht gefangen werden--> Unchecked Exceptions
			ServerSocket socket = new ServerSocket(port); // Kann eine IO Exception werfen, die gefangen werden muss --> Ist eine checkedException
			Socket s = socket.accept();
			System.out.println("Server gestartet");

			BufferedWriter zumClient = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
			BufferedReader vomClient = new BufferedReader(new InputStreamReader(s.getInputStream()));

			zumClient.write("Hallo Client, ich bin der Server");
		} catch (ArrayIndexOutOfBoundsException a) {
			System.out.println("ArrayIndexOutOfBoundsException");
		} catch (NumberFormatException n) {
			System.out.println("NumberFormatException");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

Und der Client
Java:
import java.io.*;
import java.net.*;


public class Client {
	public static void main(String[] args) {
		try {
			int port = Integer.parseInt(args[0]);
			Socket clientSocket = new Socket("localhost", port); // Kann eine UnknownHostExceptionWerfen, die ABGEFANGEN werden muss --> CheckedException
																 // Kann aber auch eine IOException werden, die abgefangen werden muss

			BufferedWriter zumServer = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
			BufferedReader vomServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

			System.out.println(vomServer.readLine());
		}
		catch (ArrayIndexOutOfBoundsException a) {
			System.out.println("ArrayIndexOutOfBoundsException");
		} catch (UnknownHostException u) {
			System.out.println("Unbekannter Host");
		} catch (IOException e) {
			System.out.println("IOException");
		}
	}
}

Wenn ich das Programm mit dem Kommandozeilenparameter z.b. 2222 (für einen benutzbaren Port) aufrufe, dann bekommen ich beim Server, sobald der Client sich angemeldet hat, die Nachricht "Server gestartet" danach tut sich gar nichts mehr. Beim Client bekomme ich eine IOException.

Kann mir jemand erklären, was ich falsch mache?
 
nach dem write ein flush() auf den Stream aufrufen.
Grundsätzlich sollte man nicht nur ausgeben, dass eine Exception geworfen wurde.
Code:
e.printStackTrace();
wie beim Server, gibt deutlich mehr Aufschluss über den Fehler.
 
Vielleicht hilft flush, auf jeden Fall benötigst du aber sowohl bei deinen Streams, als auch deinen sockets ein close(). Du musst Streams immer schließen, sonst kannst du dir nie sicher sein, dass alle Daten auch wirklich geschrieben wurden.
 
pff, man kann doch wohl eine TCP-Verbindung länger als 1 sec offen halten und auch ohne close() erwarten und sich sicher sein, dass die Daten gesendet werden 😉
 
Das mit dem flush() ändert leider überhaupt nichts. Wenn ich den Server und den Client starte, so bekomme ich beim Client eine IOException
 
vielleicht hilft die angesprochene Ausgabe der IOException,
ansonsten dürfte nichts zu sehen sein, bei jedem anderen läuft das Programm (also testen kann ich nur bei mir 😉, geht)

dass der Server nur Nanosekunden nach dem Senden schon aufhört kann evtl. Probleme machen, rate ich jetzt mal,
hilft es wenn der Server bisschen wartet mit Thread.sleep()?

damit die Nachricht auch gut übertragen wird, verwende lieber
Java:
zumClient.write("Hallo Client, ich bin der Server\n"); // ohne Zeilenumbruch geht kein readLine()
zumClient.flush(); // sonst evtl. erst bei Socket-Ende oder gar nicht gesendet? bleibt im Buffer
 
Hi
Mit den Befehlen:
zumClient.write("Hallo Client, ich bin der Server\n");
zumClient.flush();
Funktioniert das Programm. Kann mir jemand erklären, warum ich:
- einen Zeilenumbruch verwenden muss
- flush() verwenden muss
 
- einen Zeilenumbruch verwenden muss
weil Du beim Client einen Zeilenumbruch erwartest
Code:
System.out.println(vomServer.readLine());
daher musst Du auch einen Zeilenumbruch senden

- flush() verwenden muss
Du verwendest Streams um es einfacher zu haben
Code:
BufferedWriter zumClient = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
aber Streams werden gepuffert (zumindest die Ausgabe) um effizienter zu arbeiten

hand, mogel
 
Schließe doch einfach deine Streams und Sockets wenn du fertig bist mit senden, dann funktionierts auch.
das funktioniert auch nur für diesen Fall ... sowie mehr als nur ein String von A nach B gesendet werden soll, wirds schwierig - weil ständig die Verbindung neu aufgebaut werden muss

hand, mogel
 
vielleicht brauchst du noch eine Schleife
Code:
while((line = bufferedReader.readLine())!= null)
?
 

Neue Themen


Zurück
Oben