Vergleichs Problem

bladich

Mitglied
Guten Tag zusammen


Problem: Ich lese eine Datei ein und speichere deren Inhalt (IP:Port) in 2 Strings, einer für die IP und den anderen für den Port.

Ich vergleiche dann noch jedem Durchlauf wo ein Server einen Time out hatte das dieser nicht mehr genommen wird.

Das komische ist, er nimmt den lieben Server dann aber immer. :suspekt:
Trage ich aber nur einen Server in die Datei ein, bleibt er beim vergleich haengen und merkt das die IP und der Port gleich sind. :eek:


Hier mal der Code (Ich hab das Essenziele rot gefärbt):


Code:
//******************************************************//
// usage: java -cp . UDPClient type(guid, dicom) amount timout (ms)
//******************************************************//

import java.net.*;
import java.io.*;
import java.util.Random;
	 
 class UDPClient {
		public static void main (String args []) {

			//Create object for UDP communication
			NetworkStuff connection1 = new NetworkStuff();
			connection1.getServerList();
                        connection1.setOptionsAndSendPacket(args[0], args[1]);
			//Starting endless loop
			do{
					//Set options, send packet to the server and wait for answer
					try{
						connection1.receivePacket(Integer.parseInt(args[2]));
					}
					
					//For missing args[] we set here the arguments automaticly
		 			catch(ArrayIndexOutOfBoundsException e){
						connection1.setOptionsAndSendPacket(args[0], args[1]);
						connection1.receivePacket(500);
		 			}
			}while(1==1);
		}
 }
 
 
 class NetworkStuff{
	 
	 //Some variables ;-)
	 byte [] buffer;
	 private InetAddress server;
	 private DatagramSocket socket;
	 private DatagramPacket packet;
	 private String host;
	 private String typeOfID;
	 private String amountOfID;
	 private String [] tmpHost;
	 private String [] tmpPort;
	 
	 private int port;
	 private int anzZeilen;
	 
	 //Used for the compare
	 private String host_old = "0.0.0.0";
	 private int port_old = 0;
	 
	 void getServerList(){
		 
		 // Get line number and input the server ip's
		 String thisLine;
		 
		 // Get number of line in the server.txt
		 try {
			 BufferedReader in = new BufferedReader (new FileReader ("server.txt") );
		     try {
		    	 while( (thisLine = in.readLine()) != null ) {
		    		 anzZeilen++;
		         }
		         in.close();
		     } catch (IOException e) {
		     System.out.println("Read error " + e);
		     }
		 } 
		 catch (IOException e) {
			 System.out.println("Open error " + e);
		 }
		 
		 
		 //Create for each entry in the server.txt two strings (1. server, 2. port)
		 tmpHost = new String [anzZeilen];
		 tmpPort = new String [anzZeilen];
		 
		 // Input the server ip and port, line for line, split it in 2 strings (server and port)
		 try {
			BufferedReader sTmp = new BufferedReader ( new FileReader ("server.txt") );
			for(int y = 0; y < anzZeilen;y++){
				String elements [] = sTmp.readLine().split(":");
				tmpHost[y] = elements[0];
				tmpPort[y] = elements[1];
			}
			sTmp.close();
		 } 
		 catch (FileNotFoundException e) {}
		 catch(IOException e){ System.out.println(e); }
	 }
	 
	 void choiceServer(){
		 
		 // Random choice of a server and check to take a other server for this try
		 int genNumFinal = 0;
		 Random genNumTmp = new Random();
		 
		 do{
			 genNumFinal = Math.abs(genNumTmp.nextInt() % anzZeilen)+ 0;
			 host = tmpHost[genNumFinal];
			 port = Integer.parseInt(tmpPort[genNumFinal]);
		 }while(host_old.equals(tmpHost[genNumFinal]) == true && port_old == Integer.parseInt(tmpPort[genNumFinal]));
		 
		 //Set host_old to compare that a server is not used two times in a row
		 host_old = host;
		 port_old = port;
	 }
	 
	 void setOptionsAndSendPacket(String typeOfID, String amountOfID){
		 	
		 	// Get host for transmitting
		 	choiceServer();
		 
		    buffer = new byte[1024];
			try{
				// Create a Datagram Socket
				socket = new DatagramSocket();
			
				// Create a packet with server information
				String myMessage = typeOfID + ":" + amountOfID;
				buffer = myMessage.getBytes("US-ASCII");
				
				// Set host and port
				server = InetAddress.getByName(host);
				packet = new DatagramPacket(buffer, buffer.length, server, port);
					
				// Send the packet and reset the buffer
				socket.send(packet);
				buffer = new byte[1024];
			}
			
			catch(UnknownHostException e){ System.out.println(e); }
			catch(IOException e){ System.out.println(e); }
	 }
	 
	 
	 void receivePacket(int timeout){
		 
		 	// receive request from client and get client info
			try {
				
				System.out.println("Waiting for answer from: " +host + ":" + port);
				System.out.println("Old Host " + host_old + "" +"Old Port: " + port_old);
				packet = new DatagramPacket(buffer, buffer.length);
				
				socket.setSoTimeout(timeout);
				socket.receive(packet);
				
				// output the data from the server
				System.out.println(new String(buffer).trim());
			} 
			catch (IOException e) {
				System.out.println("time out");
				setOptionsAndSendPacket(typeOfID, amountOfID);}
	 }
 }

Ausgabe:

Waiting for answer from: 62.2.3.3:123
Old Host 62.2.3.3 Old Port: 123
time out
Waiting for answer from: 62.2.3.3:123
Old Host 62.2.3.3 Old Port: 123
time out
Waiting for answer from: 62.2.3.3:123
Old Host 62.2.3.3 Old Port: 123
time out
Waiting for answer from: 62.2.3.3:123
Old Host 62.2.3.3 Old Port: 123

Für Hilfe bin ich sehr dankbar, in meinen Augen stimmt der Code oder hab ich irgendwo nen Logikfehler oder sonst was Grobes vermasselt?
 
Zuletzt bearbeitet:
Hi,

ich kann es hier auch nur noch mal sagen. BITTE BENUTZT DAS this für die Variablen aus der Klasse. Dann kann man sofort sehen, welche dazu gehören, und welche nur für die Methode oder den Block zählen.

Also ich würde an deiner Stelle mal die Whileschleife überprüfen. Da könnte dein Logikfehler sein. Setzt mal ein paar mehr Klammern. Ich bin mir nämlich nicht sicher, wie genau die Prioritäten da liegen. Klammer ist auf jeden Fall Nummero Uno. Versuchs mal ;-)

Gruß
 
Hi,

ich kann es hier auch nur noch mal sagen. BITTE BENUTZT DAS this für die Variablen aus der Klasse. Dann kann man sofort sehen, welche dazu gehören, und welche nur für die Methode oder den Block zählen.

Also ich würde an deiner Stelle mal die Whileschleife überprüfen. Da könnte dein Logikfehler sein. Setzt mal ein paar mehr Klammern. Ich bin mir nämlich nicht sicher, wie genau die Prioritäten da liegen. Klammer ist auf jeden Fall Nummero Uno. Versuchs mal ;-)

Gruß

Ok, werde this verwenden in Zukunft. Bin nicht wirklich so der Javaprogrammierer, merkt man glaub ich auch gut. :rolleyes:

Die Schleife stimmt, hab jetzt noch zwar ne Klammer mehr aber das gleiche Ergebniss, hab jetzt mit ein paar System.out's herausgefunden dass der sehr merkwürdige Sprünge macht. :suspekt:

Der ruft die Methode choiceServer ohne Grund auf, bzw. es gibt in diesem Codeabschnitt gar keine Möglichkeit der er sie aufruft. :suspekt:


Ich ging mal mit dem Debuger dahinter (ich liebe eclipse =)):

Code:
		 	choiceServer();
		    System.out.println("#########################");
		    
		    buffer = new byte[1024];

Bei buffer springt er wieder auf choicheServer(). Wenn mir das jemand erklären kann?:suspekt:


*Am Kopf kratz* Eclipse neugestartet und es geht. -.-
 
Zuletzt bearbeitet:
Also ein Fehler kann ich erkennen. Und ich glaube das wirds auch sein.

Lass dir mal die Zufallswerte ausgeben. Da sollten jede Runde die gleichen sein.

Und dann noch was.

Du merkst dir immer nur den letzten Port und die IP. Das heißt, wenn du 3 Server in deiner Liste hast, dann könnte folgendes passieren.

Server1 ist unbrauchbar... Also neuen nehmen und Server1 merken.
nächste Runde. Server3 ist jetzt unbrauchbar also neuen nehmen. Durch Zufall kommt wieder server 1 dran. Aber dein gemerkter Server 3 das heißt, Server1 kann wieder genommen werden. Weißt was ich meine? Du musst dir alle unbrauchbaren merken, nicht nur den letzten.

Gruß
 
Also ein Fehler kann ich erkennen. Und ich glaube das wirds auch sein.

Lass dir mal die Zufallswerte ausgeben. Da sollten jede Runde die gleichen sein.

Und dann noch was.

Du merkst dir immer nur den letzten Port und die IP. Das heißt, wenn du 3 Server in deiner Liste hast, dann könnte folgendes passieren.

Server1 ist unbrauchbar... Also neuen nehmen und Server1 merken.
nächste Runde. Server3 ist jetzt unbrauchbar also neuen nehmen. Durch Zufall kommt wieder server 1 dran. Aber dein gemerkter Server 3 das heißt, Server1 kann wieder genommen werden. Weißt was ich meine? Du musst dir alle unbrauchbaren merken, nicht nur den letzten.

Gruß

Zufallswerte sind immer anderst. Das hab ich gecheckt. Warum kommst du darauf das dort ein Fehler ist?

Hab den Fehler wo ich erst dachte Eclipse spielt mir nen Streich ganz aus gemerzt, das Problem war das in der Main-Klasse eine Zeile zu viel in der do-Schleife war.

Jups das ist mir klar, aber die Aufgabenstellung war das nur der letzte Server nicht wieder genommen wird. Aber ich werd es mal umbauen, kann nur lernreich sein. :)


Vielen Dank für deine Hilfe.
 
Sorry,

habe mich da mit der Programmiersprache verhauen. Bei vielen Programmiersprachen ist es so, wenn eine Random ohne Zeitinitalisierung gemacht wird, immer der gleiche Rythmus genommen wird. Ergo immer die gleiche Zahl beim neustart kommt.

Läuft jetzt alles?

Ach und noch was. Sag mal nur eine Frage so. Hast du eine Prozessorauslastung von 100 Prozent, wenn das Programm läuft?
 
Ok.


Mehr oder weniger, das Problem ist gelöst nun gilt es noch die anderen Sachen rein zu bringen.


Nein, der Prozess braucht max. 6%. Auch wenn ich timeout auf ne sehr grosse Zahl setze, warum meinst du?
 
Guten Tag


Ich stelle hier meine Frage rein, ein neues Thema ist fast zu schade dafür. :rolleyes:


Mein Problem ist ganz einfach, ich habe eine private Variable die ich nach dem Methoden durchlauf wieder auf "0" setzen möchte. Bzw. Es handelt sich um ein byte[].

Hier die Methode:

Code:
private byte [] receiveBuffer = new byte[1024];
...
...
boolean receivePacket(){
		 	
		 	// receive request from client and get client info
			try {
				
				System.out.println("***Waiting for answer from: " + this.host + ":" + this.port);
					
				this.packet = new DatagramPacket(receiveBuffer, receiveBuffer.length);
				this.socket.setSoTimeout(timeout);
				this.socket.receive(packet);					

				// output the data from the server
				System.out.println("The received ID is: " + new String(receiveBuffer).trim());
				
			}
			
			catch (IOException e) {
				System.out.println("time out of the host: " + host + ":" + port);
				return true;
			}
			
			receiveBuffer = new byte [1024];
			
			return false;
	 }

Sobald die Methode 1 mal durchlief ist receiveBuffer gefüllt mit den Infos vom Server. Nun hab ich um dies zu löschen "receiveBuffer = new byte [1024];" am Ende der Methode eingefügt. Nur wurde mir gesagt das dies nicht sauber ist und unnötig RAM verschwendet. Nun suche ich eine andere Lösung für das Problem. Wenn ich sage dass es null ist bricht er mir beim nächsten durchlauf ab, was logisch ist.

Wie kann ich sagen das der Inhalt der Variable nach Ende der Methode wieder auf den Startwert gesetzt wird? Konnte über Google nichts genaues finden das mir weiter half.


Danke im Vorraus =)
 
Zurück