[Gelöst - Java] Netzwerkprogrammierung für die Schule
Verfasst: 30.06.2011, 20:32
Hallo, alle zusammen ;)
ich komme heute mit einer Frage in Java zu euch. Es geht, wie der Betreff des Themas bereits mitteilt, um Netzwerkprogrammierung mit Multithreading. Es ist eine Aufgabe für die Schule.
Für die Aufgabe liegt ein Archiv mit einigen Tests vor. Prinzipiell gelingen meinem Partner und mir die meisten Tests, mit Ausnahme der letzten drei (Genau genommen sind es test3, test4 und test6 im Test BasicTestRemote.java). Dieser Test beschäftigt sich mit der eigentlichen Netzwerkprogrammierung.
Nun, um zu meiner eigentlichen Frage zu kommen:
In welcher Situation würde es zu einer SocketException (Address already in use) kommen?
Ich erstelle mir ein Server-Objekt und beim Binden des Sockets an den Port wird die Exception ausgelöst. Davor wurden alle vorherigen Server-Objekt schlafen gelegt.
Hier habe ich die Serverimplementierung:
ich komme heute mit einer Frage in Java zu euch. Es geht, wie der Betreff des Themas bereits mitteilt, um Netzwerkprogrammierung mit Multithreading. Es ist eine Aufgabe für die Schule.
Für die Aufgabe liegt ein Archiv mit einigen Tests vor. Prinzipiell gelingen meinem Partner und mir die meisten Tests, mit Ausnahme der letzten drei (Genau genommen sind es test3, test4 und test6 im Test BasicTestRemote.java). Dieser Test beschäftigt sich mit der eigentlichen Netzwerkprogrammierung.
Nun, um zu meiner eigentlichen Frage zu kommen:
In welcher Situation würde es zu einer SocketException (Address already in use) kommen?
Ich erstelle mir ein Server-Objekt und beim Binden des Sockets an den Port wird die Exception ausgelöst. Davor wurden alle vorherigen Server-Objekt schlafen gelegt.
Hier habe ich die Serverimplementierung:
Code: Alles auswählen
import java.util.List;
import java.net.Socket;
import java.net.ServerSocket;
import java.net.BindException;
import java.net.SocketException;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import network.Logger;
import network.LoggerImpl;
/**
* Ein Server der per TCP-Verbindung die Berechnung von Primzahlen ermoeglicht.
*/
public class PrimeServerImpl implements PrimeServer
{
private int clientNumber;
/** Prozess zum Verwalten der Clients. */
private PrimeServerProcess process;
/** Verwaltungssocket. */
private ServerSocket serverSocket;
/** Logger für den Server. */
private Logger serverLog;
/**
* Startet den Server. Diese Methode muss sofort zurueckkehren.
*
* Fuer jede Clientverbindung wird ein eigener Thread gestartet.
*
* @param port
* tcp port
* @throws IOException
* Netzwerkfehler
*/
public void startServer(int port) throws IOException
{
clientNumber=1;
serverLog = new LoggerImpl();
try {
serverSocket = new ServerSocket(port);
process = new PrimeServerProcess();
process.enable();
final Thread workerThread = new Thread(process);
workerThread.start();
} catch (BindException ex) {
ex.printStackTrace();
}
/*
* out.flush();
*/
}
/**
* Stoppt den Server. Das bedeutet es werden keine neuen Verbindungen mehr
* angenommen. Bereits bestehende Verbindungen laufen normal weiter. Die
* Methode kehrt jedoch erst zurueck, wenn alle Clients die Verbindung beendet
* haben.
*
* @throws IOException
* Netzwerkfehler
* @throws InterruptedException
* falls beim Beenden ein Netzwerkfehler auftritt
*/
public void stopServer() throws IOException, InterruptedException
{
if (serverSocket != null) {
process.disable();
try {
// serverSocket.setReuseAddress(true);
serverSocket.close();
} catch (BindException ex) {
ex.printStackTrace();
}
}
addEntry("client disconnected,1");
}
/**
*
* @param e
* wird ans Ende des Logs hinzugefuegt.
*/
public void addEntry(String e)
{
if (serverLog != null) {
serverLog.addEntry(e);
}
}
/**
*
* @return Liefert eine Kopie des aktuellen Logs zurueck.
*/
public List < String > getLog()
{
return serverLog.getLog();
}
/**
* Verwaltet den Umgang mit den Clients.
*/
private class PrimeServerProcess implements Runnable
{
/** Flag zur Überprüfung der Verbindung. */
private boolean connected;
/** Aktiviert die Überprüfung für neue Clients. */
public void enable()
{
connected = true;
}
/** Deaktiviert die Überprüfung für neue Clients. */
public void disable()
{
connected = false;
}
/**
* Threading Funktion.
*/
@Override
public void run()
{
try {
while (connected) {
final PrimeServerSession session = new PrimeServerSession();
try{
session.connectWith(servSocket.accept());
} catch (SocketException e) {
return;
}
addEntry("client connected,1");
final Thread t = new Thread(session);
t.start();
}
}catch (IOException e) {
return;
}
}
}
/** Session pro Client. */
private class PrimeServerSession implements Runnable
{
/** Socket zur Client-Kommunikation. */
private Socket socket;
/** Outputstream für den Socket. */
private ObjectOutputStream out;
/** InputStream vom Socket. */
private ObjectInputStream in;
/**
* Verbindet den Server mit einem Client.
*
* @param socket
* Socket zur Kommunikation zu einem Client.
*/
public void connectWith(Socket socket)
{
this.socket = socket;
try {
out = new ObjectOutputStream(socket.getOutputStream());
out.flush();
in = new ObjectInputStream(socket.getInputStream());
} catch (IOException io) {
io.printStackTrace();
}
}
/**
* Diese Funktion wird in einem Thread ausgeführt.
*/
@Override
public void run()
{
if (socket == null) {
return;
}
String message;
while (true) {
try {
out.writeObject("1");
} catch (IOException ioException) {
return;
}
try {
message = (String) in.readObject();
addEntry(message);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
return;
}
}
}
/**
*
*/
private void waitNow()
{
try {
wait();
} catch (InterruptedException e) {
assert(false);
}
}
}
}