Was für ein Stream soll ich verwenden?

Status
Nicht offen für weitere Antworten.

Wagner

Mitglied
Hallo zusammen,

Ich bin grad dabei ein Spiel netzwerkfähig zu machen, aber ich weiß nicht genau (auf Grund von Erfahrungdefizit) wie ich das Problem angehen soll. Das Netzwerk soll ja schließlich schnell sein, aber dennoch recht simpel.

Ich hab vor kurzem ein Server-Client-Programm geschrieben, das Objekte hin und her schicken kann, weil sich das für mich am logischsten angehört hat. Jetzt hab ich aber mal per Localhost geschaut, wie lang das braucht.

Bin dabei auf rund 250ms gekommen und das scheint mir doch sehr lang.

Jetzt meine Frage: Ist es sinnvoller ein ByteStream oder ähnliches zu verwenden? Wenn ja, wie wandle ich dann z.B. Floats in ein Byte um?

Vielen Dank für eure Antworten im Vorraus

mit freundlichen Grüßen
Patrick
 
G

Guest

Gast
Du kannst DataInputStream/DataOutputStream verwenden. Es hat Methoden zu Lesen und Schreiben von Float und anderer Typen.
 
T

tuxedo

Gast
Die verbleibenden 250ms liegen am Nagle-Algorithmus (siehe auch hier im letzten Post). Den kannst du aber abschalten:

Code:
socket.setTcpNoDelay(true);

Am Stream-Typ selbst liegt das nicht wirklich.

- Alex
 
W

Wagner.

Gast
Ich erreich keine Verbesserung dadurch : /
Was mach ich falsch?

Der Client schickt ein Objekt an den Server.
Der Server hat mehrere Objekte, und sobald der Server das Objekt vom Client bekommt, schickt er alle Objekte an den Client (dieser speichert dann alle Objekte in einem Objekt[])

Ist dieser Algorithmus angepasst für ein Spiel? Oder muss ich mehr auf meine Ressourcen (bzw. Übertragungsgeschwindigkeit) achten?
 
T

tuxedo

Gast
wenn du nicht gerade Kilobyte-weise Daten verschickst, solltest du, wenns dir auf die Geschwindigkeit ankommt, direkt nach dem Senden des Objektes ein .flush() auf deinen Ausgabestrom machen.

AFAIK ist der Standardpuffer 8kbyte groß. D.h. wenn du nur 1 oder 2 kbyte sendest, gehen die nicht "sofort" auf die Reise, sondern erst wenn der Puffer von 8kbyte voll ist. Das könnte deine noch übrigen "verzögerung" sein.

Wenn nicht:

Lass mal sehen "wie" du versendest und empfängst und versuch mal ein Minimalbeispiel zu basteln.

- Alex
 

Wagner

Mitglied
Okay,

ich versuch mal kurz zu erklären.

Also, folgendes Prinzip erstmal:

- Server legt ein Array von Objekt an.
- Client schickt ein Objekt mit einer bestimmten ID.
- Server speichert anhand der ID das Objekt an einer bestimmten Stelle.
- Danach "durchläuft" der Server das Array und zählt die vorhandenen Objekte.
- Diese Anzahl gibt der Server als erstes wieder an den Client zurück, damit der Client weiß, wie oft er auf ein Input warten muss.
- Danach durchläuft der Server das Array und sucht nach Stellen, die ungleich "null" sind und tut diese in den Output.
- Nachdem er alle im Output hat, kommt der Befehl "out.flush()".
- Dann beginnt der Client diese Objekte zu verarbeiten (dieser hat vorher ebenfalls ein Array angelegt), er bekommt auch die Objekte mit den entsprechenden ID's und speichert diese dann wiederrum in ein Array (damit er bei unserem Spiel alle Gegner bei sich anzeigen kann).

Hier der Code:

Das ist das Objekt (ist bis jetzt nur ein Dummie)
Code:
import java.io.Serializable;
import javax.vecmath.Point3d;

public class Objekt implements Serializable{
    
    public int ID;
    public int Anzahl_Objekte;    //Damit wird nachher die Anzahl an den Client gegeben
    public Point3d p0 = new Point3d();

    public Objekt() {

    }
    
}

So, nun zum Client:
Code:
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.Socket;

public class Client {
    
    Objekt[] alleObjekte = new Objekt[10]; //die hat nichts bestimmtes zu bedeuten!
    
    public Client()  throws IOException, ClassNotFoundException {

        long x = System.currentTimeMillis();
        
        Socket server = new Socket("localhost", 4242 );
        server.setTcpNoDelay(true);
        ObjectOutputStream out = new ObjectOutputStream(server.getOutputStream());
        ObjectInputStream in = new ObjectInputStream(server.getInputStream());


 
       
        Objekt bla = new Objekt();
        bla.ID = 2; //variiert...kommt auf den Client an!
        out.writeObject(bla);
        out.flush();

//Bis hier her sollte eiglt alles klar sein
        
    
/*************************
* - Der erste Input ist die Anzahl der Objekt
* - So wurde es mit beigebracht zu casten : / (ich weiß nicht, ob das elegant ist)
**************************/
    
        Object test1 = in.readObject();
        Objekt test2 = null;
        
        if (test1 instanceof Objekt) {
            test2 = (Objekt)test1;            
        }

//Nun hat test2 die Anzahl der Objekte unter der Variablen "anzahl_Objekte" gespeichert

  
/************************************
* - Nun wiederholt der Client anhand der Anzahl das Empfangen, und speichert dies dann
* in der entsprechenden Stelle!
************************************/
      
        for(int i = 0; i < test2.anzahl_Objekte; i++){
            Object o = in.readObject();
            Objekt mo = null;
            
            if (o instanceof Objekt) {
                mo = (Objekt)o;
                alleObjekte[mo.ID] = mo;
                
            }
        }

// P.S. ich weiß, meine Variablennamen sind nicht sehr hilfreich : /
        

 // Hier mach ich einfach einen Test, indem ich überprüf, welche ID's alles gespeichert wurden!
       
        System.out.println("ID's im Array:");
        for(int i = 1; i < alleObjekte.length; i++){
            if(alleObjekte[i] != null){
                System.out.println(alleObjekte[i].ID);
            }
        }
        System.out.println("---Ende---");

        in.close();
        out.close();
        server.close();
        
        long y = System.currentTimeMillis();
        System.out.println("Benoetigte Zeit: "+(y-x));
        
    }
    
    
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        
        try {
            Client newClient = new Client();
        }catch (IOException ex) {
            ex.printStackTrace();
        }catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
    }
}


Server:


Code:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    
    public Objekt[] alleObjekte = new Objekt[25];
    
    public Server() throws IOException, ClassNotFoundException{
        ServerSocket server = new ServerSocket(4242);


        while (true) {
            
            Socket client = server.accept();
            ObjectInputStream in = new ObjectInputStream(client.getInputStream());
            ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
  
 //Wenn der Server etwas von einem Client bekommt, dann speichert er den neuen Wert in der entsprechenden //Stelle!
         
            Object o = in.readObject();
            Objekt mo = null;
            
            if (o instanceof Objekt) {
                mo = (Objekt)o;
                alleObjekte[mo.ID] = mo;
                System.out.println("Folgende ID wurde gespeichert: "+mo.ID);                
            }
            
/******************Anzahl der Objekte**********/
            int anzahl = 0;
            for(int j = 0; j < alleObjekte.length; j++){
                if(alleObjekte[j] != null){
                    anzahl++;
                }
            }
            Objekt test = new Objekt();
            test.anzahl_Objekte = anzahl;
            out.writeObject(test);

//ich weiß, ist nict gerade schön : /
/********************Ende********************/


//Nun durchläuft der Server das Array und wenn an der Stelle ein Objekt ist, schreibt er es in den Output
            
            System.out.println("Folgende ID's wurden geschickt:");
            for(int i = 0; i < alleObjekte.length; i ++){                
                if(alleObjekte[i] != null){
                    out.writeObject(alleObjekte[i]);
                    System.out.println(alleObjekte[i].ID);
                    
                }
            }

//Nachdem er durch ist, kommt der Befel "out.flush();"

            out.flush();
            System.out.println("---Ende---");
            
            out.close();
            in.close();
            client.close();
        }
    }
    
    
    
    public static void main(String[] args) {
        
        try {
            Server newServer = new Server();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        
        
    }
    
    
}

Anmerkung zu alex0801: Das Objekt zeigt mir im Windows eine Größe von "1KB" an.

Und was mein Problem ist, von dem Zeitpunkt, wo ich den Input und Output im Client erstell bis zum Zeitpunkt, bei dem der Client fertig mit speichern ist, vergeht (mit localhost) zu viel Zeit um damit ein Netzwerkspiel zu machen (250-600ms pro Durchlauf)

Und wenn ich vorher schon in dem Array vom Server irgendwelche Objekte angelegt hab (z.b. 6 weitere Objekte) und die dann durch geb, vergeht fast genau so viel Zeit.

Wie muss ich das verstehen? Wie kann ich dem aus dem Weg gehen? Was sollte ich verbessern (mal abgesehen von der Darstellung und Eleganz)

Schon mal vielen Dank im Vorraus ;)

mit freundlichen Grüßen
Wagner
 

Wagner

Mitglied
Hat keiner eine Idee, wie ich das Problem best möglich lösen kann? :(
Oder zumindest einen besseren Ansatz?

mfg
Wagner
 

SebiB90

Top Contributor
ich hab eher wenig ahnung von netzwerkprogrammierung
aber wäre es nicht logischer setTypNoDelay auf dem Server auszuführen? Weil der verschickt die Daten ja, also muss da doch dieser Algorithmus deaktiviert werden. oder nicht?
 
T

tuxedo

Gast
Das mit dem TcpNoDelay solltest du in der Tat auf beiden Seiten machen.

Bei der Sache mit dem Casten ... Da du ja exakt weißt, was für ein Typ kommt, musst du keine instanceOf Abfrage machen. Das kostet nur unnötig zeit. Caste direkt in den Typ den du bekommen willst.

Weiterhin ist es nicht ganz so performant wenn du immer objekte schickst. Wenn du eine Zahl/Anzahl von irgendwas übermitteln willst, benutze eine DataInput/OutoutStream. Der kennt writeInt() und readInt(). Das ist etwas schneller.

>> Das Objekt zeigt mir im Windows eine Größe von "1KB" an.

Wie um Himmels willen hast du das denn ermittelt?

Nebenbei würde ich dir auch fast raten mal RMI oder was ähnliches (SIMON??) anzuschauen... Da sparst du dir die Arbeit mit dem Protokoll und kannst Nachrichten gleichj nen Zacken schneller verschicken ohne viel Aufand zu betreiben.

Schau dir mal diese Grafik an:



Vielleicht reicht dir diese Geschwindigkeit ja aus....

- Alex
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
dayaftereh Bester Stream für ein Spiel? Netzwerkprogrammierung 15
FrankenDerStein HTTP Https Server Bibliothek für Linux und Android gesucht. Netzwerkprogrammierung 7
FrankenDerStein Socket UDP Multithreading für ein Port Netzwerkprogrammierung 2
M Server-Client-System für Browsergame Netzwerkprogrammierung 5
Tobero Java serversocket nicht nur zuganglich für localhost Netzwerkprogrammierung 6
T Brauche Hilfe beim GET-String für HttpURLConnection Netzwerkprogrammierung 4
F Server für Java Applikationen Netzwerkprogrammierung 16
B Webview für Anwendung Netzwerkprogrammierung 7
M Sicheres Login-System für App implementieren Netzwerkprogrammierung 6
J Netty umsetzung für ein Protokoll Netzwerkprogrammierung 1
J ERM für kleine Verwaltungsdatenbank Netzwerkprogrammierung 2
H Machbarkeitsfrage: TCP/IP Client (z.B. Netty) für Java Web Applcation Netzwerkprogrammierung 1
Messoras Launcher für mein Spiel Netzwerkprogrammierung 7
F Einfaches Gateway für Log-Files Netzwerkprogrammierung 1
P RMI - Neue eigene Instanz für jeden Aufruf auf nicht serialisierbares Objekt - wie? Netzwerkprogrammierung 0
P PPTP Protokoll für JAVA Netzwerkprogrammierung 14
T FTP Wie Notwendigkeit für "rekey" klientenseitig detektieren? Netzwerkprogrammierung 3
S Webserver für Jar File Netzwerkprogrammierung 4
G Socket Socket verbindung für Chat System Netzwerkprogrammierung 3
V Templates für Java Client rabbitmq Netzwerkprogrammierung 4
M Erreichbar für alle zu sein Netzwerkprogrammierung 9
M Server nur für eine Aufgabe Netzwerkprogrammierung 2
N Selbes URL Objekt für alle Requests nutzen Netzwerkprogrammierung 7
T uberspace.de als (v)root-Ersatz für kleinere Java-Anwendungen? Netzwerkprogrammierung 12
L Proxy für Dateidownload? Netzwerkprogrammierung 3
K HTTP Eigener Http Response für Datei-Download Netzwerkprogrammierung 4
D Socket Leitstelle für Funkspiel Netzwerkprogrammierung 8
F Java-Beispielcode für Zeroconf (ähnlich Apple Bonjour) Netzwerkprogrammierung 7
I HTTP S - Zertifikate+Cockies für Form-basierten Login Netzwerkprogrammierung 2
Ollek Socket Sucher passende Server/Client Lösung für meine Anwendung Netzwerkprogrammierung 2
M Gleicher Port für Senden und Empfangen ? Netzwerkprogrammierung 17
N RMI Einstellungen für "übers Internet" Netzwerkprogrammierung 8
F SSL-Zertifikate für viele Nutzer? Netzwerkprogrammierung 8
K Byte für Byte aus InputStream lesen Netzwerkprogrammierung 5
S wie stell man die classpath für JARs? Netzwerkprogrammierung 3
M Bestimmte Klassen für Netzwerkchecks gesucht Netzwerkprogrammierung 11
M ClassLoader für Axis2 setzen Netzwerkprogrammierung 15
M Welches Speicherformat für News-Database?? Netzwerkprogrammierung 2
Shoox VPN-Verbindung für Datenbankzugriff Netzwerkprogrammierung 2
P Proxy für Anwendung setzten Netzwerkprogrammierung 3
T Bezeichner "end of line" für die Funktion readline Netzwerkprogrammierung 5
A DataGramsocket Übertragungsproblem im Internet (IPs für Voip) Netzwerkprogrammierung 5
E Userliste für Chat Applet Netzwerkprogrammierung 4
S HTTP Kleines Programm für den Routerneustart Netzwerkprogrammierung 3
L Zeitspanne für erneutes senden Netzwerkprogrammierung 16
L Socket Chat Server für mehrere Clients Netzwerkprogrammierung 7
F Netzwerkprogrammierung für Anfänger Netzwerkprogrammierung 2
J Framework/ Muster für Chat-ähnliches Programm gesucht Netzwerkprogrammierung 2
B Variablen ausrichten für Übertragung Netzwerkprogrammierung 2
D FTP Pfadangabe für ftp-upload funktioniert nicht Netzwerkprogrammierung 5
K Getrennte Rechner für RMI-Server/RMI-Registry, bzw. Alternativen? Netzwerkprogrammierung 5
dayaftereh HTTPCleint und HTMLparser für hTTpBot Netzwerkprogrammierung 2
E Socket Client-Applikation mit GUI für Internet IO-Platine Netzwerkprogrammierung 2
0din Grundlage für Bluetooth Netzwerkprogrammierung 5
N "Jungfernflug" der Socketprogrammierung für ein Mühlespiel Netzwerkprogrammierung 8
F Empfehlung für embedded Webserver Netzwerkprogrammierung 10
W Bibliothek für Certificate Management Protocol (CMP) Netzwerkprogrammierung 3
O Client/Server für Ticker Netzwerkprogrammierung 2
J Stubs für SOAP-Webservice generieren. Ich bekomme es einfach nicht hin... Netzwerkprogrammierung 3
data89 Sockets: ein alter Hut - für Euch - für mich nicht! Netzwerkprogrammierung 10
G FileDialog für FTP Client Netzwerkprogrammierung 2
P Welches Protokoll für RMI verwenden? Netzwerkprogrammierung 10
H RCON Tool für Gameserver Netzwerkprogrammierung 11
A Wichtig für einen Chat? Netzwerkprogrammierung 4
D Was für Verbindungen mit Socket möglich? Netzwerkprogrammierung 2
S Realisierung eines Netzwerkcodes für ein Strategiespiel Netzwerkprogrammierung 7
G Datagram-Sockets für UDP-Kommunikation Netzwerkprogrammierung 2
A Rezept für Webservices Netzwerkprogrammierung 5
I unc pfad für die klasse file? Netzwerkprogrammierung 4
P eine BufferedReader für alles ankommende Netzwerkprogrammierung 2
T Filter für Input UND OutputStream Netzwerkprogrammierung 4
T Welches Netzwerk ist am bestern für. Netzwerkprogrammierung 2
G server für mein spiel. Netzwerkprogrammierung 5
M Log In Programm für Seiten Netzwerkprogrammierung 2
G Netzwerkprogrammierung für spiele Netzwerkprogrammierung 2
A IRC-Server für das lokale Netzwerk? Netzwerkprogrammierung 12
C Einfacher Filedownload mit Sockets geht nicht für pdffiles Netzwerkprogrammierung 16
S Server für Internetspiel Netzwerkprogrammierung 2
G Objecte für Kommunikation nutzen Netzwerkprogrammierung 2
J Java Programm für Upload von Dateien per HTTP Netzwerkprogrammierung 7
S Voreinstellungen für JavaMail Netzwerkprogrammierung 2
S Idee für Projekt auf Agentenbasis Netzwerkprogrammierung 8
S Suche API für einfachen HTTP-Zugriff. Netzwerkprogrammierung 17
G benötige Beispiel für parallel ablaufende Threads Netzwerkprogrammierung 3
M RMI - Ein Objekt für Alle? Netzwerkprogrammierung 5
Z Protokoll für Schiffeversenken Netzwerkprogrammierung 5
T Kann man jeden Port für Programm verwenden? Netzwerkprogrammierung 2
R proxy für java anwendung angeben [resolved] Netzwerkprogrammierung 15
B Wie Router einstellen für CLient-Server-Programm? Netzwerkprogrammierung 4
R PPTP Protokoll für JAVA Netzwerkprogrammierung 3
Icewind Klasse für DNS Anfragen Netzwerkprogrammierung 14
P Welche Art von Sockets für ein Spiel? Netzwerkprogrammierung 3
M Socket Verbindungen für einen Chat Netzwerkprogrammierung 10
M Ausgangsport für FTp-Connection festlegen??? Netzwerkprogrammierung 3
D beste Methode für Datenübertragung ? Netzwerkprogrammierung 1
L Server-Socket liest Input-Stream nicht Netzwerkprogrammierung 5
E Socket Werte mit DataInput- und Output- Stream übergeben Netzwerkprogrammierung 1
T MP3 Dateien Stream Netzwerkprogrammierung 3
C Byte Stream dekodieren Netzwerkprogrammierung 7
G Video aus RTSP Stream speichern Netzwerkprogrammierung 8

Ähnliche Java Themen

Neue Themen


Oben