# Netzwerkspiel Client ruckelt



## Andi1804 (25. Mrz 2008)

Hallo Leute,
also ich hab in Java ein kleines Netzwerkspiel programmiert. Dabei hab ich beim Testen immer Server und Client auf den gleichen Rechner laufen lassen und immer über localhost verbunden. Bei diesen Tests funktionierte das Spiel einwandfrei. Werden Server und Client aber auf verschiedenen PCs ausgeführt, ruckelt der Client stark.

Hier mal eine kurze Übersicht wie alles Abläuft:

Der Server startet für jeden client (Anzahl vorher eingeben) einen Thread sobald dieser connected.
Sind alle Clients verbunden, startet auf dem Server im Hauptthread das Spiel.
Die nötigen Daten werden über DataInputStreams und DataOutputstreams übertragen vom jeweiligen Thread aus übertragen.

Der client hat keine extra Threads, er sendet regelmäßig bestimmte Tastertureingaben zum Server und ließt die ankommenden Daten, dazwischen aktualisiert er seine Spielwelt. 

Ich würd gerne rausfinden, woher dieses ruckeln kommt. 
Da es über localhost ohne Probleme läuft müsste doch irgendwas bei der Datenübertragung schief laufen. (vermut ich mal)
Kann mir wer erklären wie sich eine richtige Netzwerkverbindung im Gegensatz zur localhost Verbindung auf das Programm auswirkt?
Kann es sein, dass ich die Streams vieleicht puffern muss?

Ich hoffe mir kann geholfen werden.

mfg Andi


----------



## Pappenheimer++ (25. Mrz 2008)

Was hast du denn für ne Verbindung? TCP? Wenn das der fall sein sollte und du jedes Byte einzeln schickst (was sein kann, oder auch nicht: ich habe ja keinen Code gesehen), dann wird nach jedem Paket (also jedem Byte) erst ein ACK zurückgesendet, bevor es weitergehen kann. Das würde das ganze natürlich extremst ausbremsen. Aber poste doch mal Code. Wenn du das nicht willst, kannst du ja mal selbst Nachforschungen anstellen. Dazu kannst du dir Progs wie z.b. Wireshark besorgen, die dne Netzwerkverkehr für dich analysieren.


----------



## Andi1804 (25. Mrz 2008)

Ich muss gestehen, ich bin noch Anfänger in Sachen Netzwerk in Java. Aber laut meinem Java Buch wird bei den Socket Klassen TCP verwendet. Wird das ACK bei localhost connection denn nicht zurück gesendet?

Danke übrigens für deine Hilfe und hier noch etwas Code:

Also hier ist mal der Code der den Server eröffnet und die Clients annimmt:


```
import java.net.*;
import java.util.LinkedList;

public class server {

	private static int spielerzahl;
	private static ServerSocket serverS;
	private static LinkedList <Thread> threads;
	
	public static void öffneServer(int port,int spielerz){
		spielerzahl = spielerz;
		try{
			serverS = new ServerSocket(port);
			serverS.setSoTimeout(60000);
		}catch(Exception e){
			System.out.println(e);
		}
		
		
		if (spielerzahl <0){spielerzahl = 0;}
		if (spielerzahl >4){spielerzahl = 4;}
		threads=new LinkedList();
		for (int a = 1; a<=spielerzahl;a++){
			Thread b = new Thread(new client(a));
			threads.add(b);
		}
		System.out.println("starte Spiel");

		game spiel = new game();
		

	}
	
	public static void starteClientThreads(){
		for(int a = 0; a<spielerzahl; a++){
			System.out.println("starte Thread Nr. "+a);
			threads.get(a).start();
		}
	}
	
	public static ServerSocket getServerSocket(){
		return serverS;
	}
	
	public static int getSpielerzahl(){
		return spielerzahl;
	}
}
```


Und hier der Code der Clientklasse im Server (also die Klasse die die Daten zum Client sendet)


```
import java.net.*;
import java.io.*;

public class client implements Runnable {


	private DataInputStream in;
	private DataOutputStream out;
	
	private int clientnummer;
	
	private static Socket socket;
	
	public client(int nummer){
		clientnummer = nummer;
		try{
			socket = server.getServerSocket().accept();
		}catch(Exception e){
			System.out.println(e);
		}
		System.out.println("clientclasse im server akzeptiert verbindung");
		
		try{
			in = new DataInputStream(socket.getInputStream());
			out = new DataOutputStream( socket.getOutputStream());
		}catch(Exception e){
			System.out.println("in Clientklasse Streamproblem:");
			System.out.println(e);
		}
		
		Daten.spieler[clientnummer-1]= true;

	}
	
	public void run(){
		System.out.println("starte run");
		
		sendeBoolean(true);
		sendeInt(clientnummer);
		
		while(true){
			sendeDaten();
			
			Daten.setVorwärts(leseBoolean(), clientnummer);
			Daten.setRückwärts(leseBoolean(), clientnummer);
			Daten.setLinks(leseBoolean(), clientnummer);
			Daten.setRechts(leseBoolean(), clientnummer);
			Daten.setSchuss(leseBoolean(), clientnummer);
			
			
	         try {
		            Thread.sleep(15);
		         } catch (InterruptedException e) {
		            System.out.println(e);
		         }
		         
		}
	}
	
	

	private void sendeBoolean(boolean f){
		try{
			out.writeBoolean(f);
		}catch(Exception e){
			System.out.println("in Clientklasse writeproblem:");
			System.out.println("e");
		}
	}
	
	private  boolean leseBoolean(){
		try{
			return in.readBoolean();
		}catch(Exception e){
			System.out.println("in Clientklasse readproblem:");
			System.out.println("e");
			return false;
		}
	}
	
	private void sendeInt(int f){
		try{
			out.writeInt(f);
		}catch(Exception e){
			System.out.println("in Clientklasse writeproblem:");
			System.out.println("e");
		}
	}
	
	private void sendeFloat(float f){
		try{
			out.writeFloat(f);
		}catch(Exception e){
			System.out.println("int Clientklasse writeproblem:");
			System.out.println("e");
		}
	}
	
	
	private void sendeDaten(){
		sendeInt(Daten.lebensenergieSpieler[clientnummer-1]); //sende lebensenergie
		GameObject Objekt;
		int zähler = 0;
		
		while((Objekt = copyData(zähler))!= null){
			zähler ++;
			sendeBoolean(true);
			
			MyObject3D c = Objekt.getMyObject3D();
			float [] rotationMatrix = c.getRotationMatrix().getDump();
			sendeInt(c.getNetID());
			sendeInt(c.getObjektArt());
			sendeFloat(c.getTransformedCenter().x);
			sendeFloat(c.getTransformedCenter().y);
			sendeFloat(c.getTransformedCenter().z);
			
			for (int d = 0; d<rotationMatrix.length; d++){
				sendeFloat(rotationMatrix[d]);
			}
		}
		sendeBoolean(false);
	}
	
	private GameObject copyData(int nummer){
		try{
			return Daten.Objekte.get(nummer).copyObject();
		}catch(Exception e){
			return null;
		}
	}
	

	
}
```


----------

