Hallo Leute,
Ich hab die Aufgabe bekommen einen bereits vorhandenen Workspace weiterzuprogrammieren.
Es soll ein Echo-Server und ein passender Echo-Client auf Basis von TCP-Sockets
entwickelt werden, der alle Echo-Requests in einem einzigen Thread bearbeitet.
Für jeden Echo-Request baut ein Client eine TCP-Verbindung zum Server auf, sendet eine Echo-
PDU, wartet auf das Ergebnis und baut anschließend die Verbindung wieder ab.
Soweit bin ich bis jetzt:
Mir wird folgender Fehler angezeigt:
Kann mir jemand sagen, was ich falsch gemacht habe?
Ich hab die Aufgabe bekommen einen bereits vorhandenen Workspace weiterzuprogrammieren.
Es soll ein Echo-Server und ein passender Echo-Client auf Basis von TCP-Sockets
entwickelt werden, der alle Echo-Requests in einem einzigen Thread bearbeitet.
Für jeden Echo-Request baut ein Client eine TCP-Verbindung zum Server auf, sendet eine Echo-
PDU, wartet auf das Ergebnis und baut anschließend die Verbindung wieder ab.
Soweit bin ich bis jetzt:
Java:
public class TCPSingleThreadedEchoClientThread extends AbstractClientThread
{
private static Log log = LogFactory.getLog(TCPSingleThreadedEchoClientThread.class);
// Lokaler Port zur Kommunikation mit dem Echo-Server
private int localPort;
// Name des Threads
private String threadName;
// Nummer des Echo-Clients
private int numberOfClient;
// Laenge einer Nachricht
private int messageLength;
// Anzahl zu sendender Nachrichten je Thread
private int numberOfMessages;
// Serverport
private int serverPort;
// Adresse des Servers
private String remoteServerAddress;
// Denkzeit des Clients zwischen zwei Requests in ms
private int clientThinkTime;
// Gemeinsame Daten der Threads
private SharedClientStatistics sharedData;
// Socket-Verbindung
private Socket con;
private ObjectInputStream in;
private ObjectOutputStream out;
// Zeitstempel für RTT-Berechnung und Kalender
private long rttStartTime;
private long rtt;
@Override
public void initialize(
int serverPort,
String remoteServerAddress,
int numberOfClient,
int messageLength,
int numberOfMessages,
int clientThinkTime,
SharedClientStatistics sharedData)
{
this.serverPort = serverPort;
this.remoteServerAddress = remoteServerAddress;
this.numberOfClient = numberOfClient;
this.messageLength = messageLength;
this.numberOfMessages = numberOfMessages;
this.clientThinkTime = clientThinkTime;
this.sharedData = sharedData;
this.setName("EchoClient-".concat(String.valueOf(numberOfClient+1)));
threadName = getName();
}
/**
* Run-Methode fuer den Test-Thread:
* Client-Thread sendet hier alle Requests und wartet auf Antworten
*/
public void run()
{
sharedData.incrNumberOfLoggedInClients();
/**
* Synchronisation mit allen anderen Client-Threads:
* Warten, bis alle Clients angemeldet sind und dann
* erst mit der Lasterzeugung beginnen
*/
while (!sharedData.allClientsLoggedIn())
{
try {
Thread.sleep(100);
}
catch (InterruptedException e) {
log.error("Sleep unterbrochen");
}
}
/**
* Senden von Echo-Nachrichten
*/
for (int i = 0; i < numberOfMessages; i++)
{
try {
EchoPDU echo = new EchoPDU();
con = new Socket(remoteServerAddress, serverPort);
out = new ObjectOutputStream(con.getOutputStream());
in = new ObjectInputStream(con.getInputStream());
out.writeObject(echo);
out.close();
in.readObject();
in.close();
con.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Java:
public class TCPSingleThreadedEchoServer
{
private static Log log = LogFactory.getLog(TCPSingleThreadedEchoServer.class);
private static int serverPort = 50000;
// Verbindungstabelle: Hier werden alle aktiven Verbindungen zu Clients verwaltet
private static Map<String, Socket> connections = new ConcurrentHashMap<String, Socket>();
// TCP-Socket des Servers (Listen-Socket)
private static ServerSocket serverSocket;
// Laenge der Queue des Server-Sockets fuer ankommende Verbindungsaufbauwuensche
private static final int backlog = 20;
// Verbindungszaehler
private static long nrConnections = 0;
// Streams fuer TCP-Verbindung
private static ObjectOutputStream out;
private static ObjectInputStream in;
/**
* Konstruktor
*/
public TCPSingleThreadedEchoServer()
{
}
/**
* main
* @param args
*/
public static void main (String args[])
{
PropertyConfigurator.configureAndWatch("log4j.server.properties", 60 * 1000);
// TODO: TCP-Serversocket registrieren
try {
serverSocket = new ServerSocket(serverPort);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while (true) {
try {
// Auf ankommende Verbindungsaufbauwuensche warten
Socket incomingConnectionFromClient = serverSocket.accept();
//TODO
// Ein- und Ausgabe-Objektstrom erzeugen
out = new ObjectOutputStream(incomingConnectionFromClient.getOutputStream());
in = new ObjectInputStream(incomingConnectionFromClient.getInputStream());
//TODO: Neue Verbindung in Verbindungstabelle eintragen
Object e = in.readObject();
EchoPDU echo = (EchoPDU) e;
in.close();
//TODO: Echo-Response senden
out.writeObject(echo);
out.close();
serverSocket.close();
}
catch (Exception e) {
//TODO
}
}
}
}
Java:
public class EchoPDU implements Serializable
{
private static final long serialVersionUID = -6172619032079227583L;
String clientName; // Name des Client-Threads, der den Request absendet
String serverThreadName; // Name des Threads, der den Request im Server bearbeitet
boolean lastRequest; // Kennzeichen, ob Client letzte Nachricht sendet. Dieses Kennzeichen
// dient dem Server dazu, um festzustellen, ob sich der Client nach der Nachricht beendet
private long serverTime; // Zeit in Nanosekunden, die der Server benoetigt. Diese
// Zeit wird vom Server vor dem Absenden der Response eingetragen
String message; // Echo-Nachricht (eigentliche Nachricht in Textform)
public EchoPDU()
{
clientName = null;
serverThreadName = null;
message = null;
serverTime = 0;
lastRequest = false;
}
public void setClientName(String name)
{
this.clientName = name;
}
public void setServerThreadName(String name)
{
this.serverThreadName = name;
}
public void setMessage(String msg)
{
this.message= msg;
}
public void setServerTime(long time)
{
this.serverTime = time;
}
public void setLastRequest (boolean last)
{
this.lastRequest = last;
}
public String getClientName()
{
return(clientName);
}
public String getServerThreadName()
{
return(serverThreadName);
}
public String getMessage()
{
return(message);
}
public long getServerTime()
{
return(serverTime);
}
public boolean getLastRequest()
{
return(lastRequest);
}
}
Java:
public class BenchmarkingGuiSimulation implements BenchmarkingClientGuiInterface {
private int timeCounter = 0;
@Override
public void showStartData(GuiStartData data) {
System.out.println("Testbeginn: " + data.getStartTime());
System.out.println("Geplante Requests: " + data.getNumberOfRequests());
}
@Override
public void showResultData(GuiResultData data) {
System.out.println("Testende: " + data.getEndTime());
System.out.println("Testdauer in s: " + data.getElapsedTime());
System.out.println("Gesendete Requests: " + data.getNumberOfSentRequests());
System.out.println("Anzahl Responses: " + data.getNumberOfResponses());
System.out.println("Anzahl verlorener Responses: " + data.getNumberOfLostResponses());
System.out.println("Mittlere RTT in ms: " + data.getAvgRTT());
System.out.println("Maximale RTT in ms: " + data.getMaxRTT());
System.out.println("Minimale RTT in ms: " + data.getMinRTT());
System.out.println("Mittlere Serverbearbeitungszeit in ms: " + data.getAvgServerTime());
System.out.println("Maximale Heap-Belegung in MByte: " + data.getMaxHeapSize());
System.out.println("Maximale CPU-Auslastung in %: " + data.getMaxCpuUsage());
}
@Override
public void setMessageLine(String message) {
System.out.println("*** Meldung: " + message+ " ***");
}
@Override
public void addCurrentRunTime (long sec) {
timeCounter += sec;
System.out.println("Laufzeitzaehler: " + timeCounter);
}
@Override
public void resetCurrentRunTime () {
timeCounter = 0;
}
/**
* main
* @param args
*/
public static void main(String args[])
{
PropertyConfigurator.configureAndWatch("log4j.client.properties", 60 * 1000);
new BenchmarkingGuiSimulation().doWork();
}
public void doWork()
{
// Input-parameter aus GUI
GuiInputParameters parm = new GuiInputParameters();
// GUI sammmelt Eingabedaten ...
// Benchmarking-Client instanzieren und Benchmark starten
BenchmarkingClient benchClient = new BenchmarkingClient();
benchClient.executeTest(parm, this);
}
}
Mir wird folgender Fehler angezeigt:
Code:
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.ObjectInputStream$PeekInputStream.peek(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.peek(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at edu.hm.dako.EchoApplication.TCPSingleThreaded.TCPSingleThreadedEchoClientThread.run(TCPSingleThreadedEchoClientThread.java:126)
java.net.SocketException: socket closed
Kann mir jemand sagen, was ich falsch gemacht habe?