java-forum.org
JBoss Seam
Alter Preis: 39,95 €
Jetzt: 0,00 €

zzgl. Versandkosten

Zurück   java-forum.org > Java - Programmierung > Netzwerkprogrammierung

Netzwerkprogrammierung Fragen zu Client-/Server-Programmierung sowie zu verteilten Anwendungen (RMI, CORBA etc.)

Antwort    
Themen-Optionen Thema durchsuchen Ansicht
Alt 30.07.2010, 14:54   #1 (permalink)
Neuer Benutzer
Byte
 
Registriert seit: 30.01.2010
Beiträge: 9
Abgegebene Danke: 0
Erhielt 0 Danke für 0 Beiträge
Standard Server mit meheren Streams/Aufgaben?

Hallo Zusammen,
ich hab mich ein bisschen in Sockets eingelesen und auch einen kl. Chat gebaut.
Ist ja ne Basis-Aufgabe. So meine Frage ist, ich möchte nun z.b. das man sich Registrieren kann,
das heißt das der Server also einen Befehl bekommt und zum Nutzer erstmal nur ne Text-datei anlegt.

So meine Denkblockade:
Es gibt ja einen Socket.InputStream. Ist der für alles Zuständig? Also darüber läuft ja jetzt quasi der Chat. Wie bring ich da nun eine zweite Aufgabe unter?
Kommt alles an diesem InputStream an oder kann es zwei geben?
Also quasi.
1.)jeweils nur einen Data/Input/Object-Stream?
2.)oder nur einen Stream egal welcher und ich muss quasi da differenzieren was ich machen will?

Hoffe ihr versteht wo meine Blockade ist, muss eine zweite Kommunikationsaufgabe einbauen und hab das noch nirgends in einem Tutorial gelesen. Die Basis mein ich verstanden zu haben.

Gruß Behnke

edit: Ich bräuchte beim Clienten auch ne zweite Schiene der Kommunikation fällt mir grad auf?
Muss ich einfach noch einen Socket erstellen?
*verwirrt*

Geändert von Behnke (30.07.2010 um 15:01 Uhr)
Behnke ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 30.07.2010, 15:16   #2 (permalink)
Stammbenutzer
Kilobyte
 
Benutzerbild von mogel
 
Registriert seit: 04.12.2007
Beiträge: 629
Abgegebene Danke: 17
Erhielt 15 Danke für 15 Beiträge
Zitat: Behnke
Beitrag anzeigen
Ich bräuchte beim Clienten auch ne zweite Schiene der Kommunikation fällt mir grad auf?
Muss ich einfach noch einen Socket erstellen?
nein - einfach ein vernüftiges Protokoll für die Kommunikation definieren ... im Moment kann Dein Protokoll nur Nachrichten (also Chat) senden ... das Protokoll wird also komplexer
__________________
.http://www.fantasya-pbem.de. - Fantasy-Multiplayer-Strategie - Runden basiert
mogel ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 30.07.2010, 15:33   #3 (permalink)
Neuer Benutzer
Byte
Themenstarter
 
Registriert seit: 30.01.2010
Beiträge: 9
Abgegebene Danke: 0
Erhielt 0 Danke für 0 Beiträge
Das heißt z.b.: Ich definiere # als Befehlsanfang.
Beispiel: "#Register Nickname" vom Client

Der Server filtert also dann "#.." im InputStream und sieht dann aha Register und ich ruf meine Funktionen auf und Antworte je nachdem wieder zum Clienten.
Ist das korrekt?

Gruß

Edit: hab grad ein alten Thread gefunden!
Zitat:
Zitat von tuxedo

-> Nachricht beginn
1 byte -> Beschreibt welche Art von Nachricht es ist (0..255... Da kannst du genug Nachrichtentypen definieren)
4 byte -> Länge des Bodys der Nachricht
x byte -> der Body der Nachricht. Hier drin sind alle Daten und Infos der Nachricht gespeichert.
-> Nachricht ende
Klar macht ja auch mehr Sinn, weil sonst könnte jemand im Chat mit #Register rumspamen und ich leg dafür Benutzer an.
Weitere Tips immer her, ansonsten probier ich mich mal daran!

Geändert von Behnke (30.07.2010 um 15:50 Uhr)
Behnke ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 30.07.2010, 15:47   #4 (permalink)
Stammbenutzer
Viertel Gigabyte
 
Benutzerbild von ARadauer
 
Registriert seit: 16.09.2006
Beiträge: 3.748
Abgegebene Danke: 0
Erhielt 62 Danke für 62 Beiträge
Zitat:
Es gibt ja einen Socket.InputStream. Ist der für alles Zuständig? Also darüber läuft ja jetzt quasi der Chat. Wie bring ich da nun eine zweite Aufgabe unter?
threads...

ok, dan kram ich mal in alten beispielen... hier ein alter rechen server den man über browser ansprechen kann..

also für jeden eingehenden request wir ein eigener thread erzeugt...
Java Code: Quelltext in neuem Fenster öffnen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
import java.util.Random;
 
public class MyServer extends Thread {
 
   public static void main(String[] args) throws IOException {
      ServerSocket socket = new ServerSocket(1234);
      while(true){
         System.out.println("waiting...");
         new MyServer(socket.accept()).start();
         
      }
   }
   
   Socket client;
   
   public MyServer(Socket client){
      this.client = client;      
      
   }
   
   public void run(){
      try {
         String request = parseRequest();
                
         
         String msg = "<b>"+handleRequest(request)+"</b><br> proof of alive:"+System.currentTimeMillis();
         sendResponse(msg);
      } catch (IOException e) {
         System.out.println("FEHELER");
         e.printStackTrace();
      }finally{
         try {
            client.close();
         } catch (IOException e) {}
      }    
   }
   /**
    * Protokoll: "cmd?param1:param2"
    * @return
    */
   public String handleRequest(String request){
      
          try {
         System.out.println(request);
         int start = 1;
         int end = request.indexOf("?");
         
         String cmd = request.substring(start, end);
         start = end+1;
         end = request.indexOf(":");
         
         int param1 = Integer.parseInt(request.substring(start, end));
         start = end+1;
         end = request.length();
         int param2 = Integer.parseInt(request.substring(start, end));
         
         if(cmd.equals("add")){
            return ""+(param1+param2);
         }else if(cmd.equals("sub")){
            return ""+(param1-param2);
         }else{
            return "cmd nicht bekannt";
         }
      } catch (Exception e) {
         e.printStackTrace();
         return "ERROR";
      }      
      
      
      
   }
   
   public String parseRequest() throws IOException {
      BufferedReader reader =  new BufferedReader(new InputStreamReader(client.getInputStream()));
         String request = reader.readLine();
         if (request == null || !request.startsWith("GET ") || !(request.endsWith(" HTTP/1.0") || request.endsWith("HTTP/1.1"))) {
             return null;
         }            
       return request.substring(4, request.length() - 9);   
      
      
   }
   
   public void sendResponse(String data) throws IOException{
     
      BufferedOutputStream out = new BufferedOutputStream(client.getOutputStream());      
     
         out.write(("HTTP/1.0 " + 200 + " OK\r\n" + 
                    "Date: " + new Date().toString() + "\r\n" +
                    "Server: MyServer/1.0\r\n" +
                    "Content-Type: text/html\r\n" +
                    "Expires: Thu, 01 Dec 1994 16:00:00 GMT\r\n" +
                    "Content-Length: " + data.length() + "\r\n" +
                    "Last-modified: " + new Date().toString() + "\r\n" +
                    "\r\n").getBytes());
         out.write(data.getBytes());
         out.close();
     
   }
}
__________________
Meine Beiträge stehen unter der Beerware Lizenz!
ARadauer ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 30.07.2010, 15:55   #5 (permalink)
Neuer Benutzer
Byte
Themenstarter
 
Registriert seit: 30.01.2010
Beiträge: 9
Abgegebene Danke: 0
Erhielt 0 Danke für 0 Beiträge
@ARadauer: Threads hab ich ja schon drin.
Mir gings eher um die Stream Angelegenheiten bei dem ich mir nun versuch mit einem Protokoll zu helfen.
Ich mein 2 Threads mit jeweils 1 InputStream?
Obwohl klingt auch garnicht so doof, weil mein Protokoll dann ja abfängt ob es für Chat/Register bestimmt ist.
Aber: kommt das auch 2x an? Sobald sich das ein InputStream holt ist es doch kein zweites mal mehr da oder?
Behnke ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 30.07.2010, 16:08   #6 (permalink)
Stammbenutzer
Kilobyte
 
Registriert seit: 28.05.2007
Beiträge: 643
Abgegebene Danke: 6
Erhielt 19 Danke für 18 Beiträge
Zitat: Behnke
Beitrag anzeigen
Klar macht ja auch mehr Sinn, weil sonst könnte jemand im Chat mit #Register rumspamen und ich leg dafür Benutzer an.
Weitere Tips immer her, ansonsten probier ich mich mal daran!
ich glaube mein Beispiel eines binären Protokolls ist zu Anfang etwas schwerer

Du nutzt immer nur 1 InputStream, außerdem musst du jede übertragene Aktion mit dem Protokoll machen, nicht nur Sonderbefehle
also:
Code:
#REGISTER meinname
#CHAT hi wie gehts
würde nun jemand versuchen #REGISTER maxmustermann im Chat zu senden kommt da folgendes heraus:
Code:
#CHAT #REGISTER maxmustermann
es wird also also dadurch immer als Chat-Nachricht interpretiert.


Ein gutes Format für das Protokoll zu definieren ist dann die nächste schwere Aufgabe.
ice-breaker ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 30.07.2010, 16:40   #7 (permalink)
Projektleiter Plugin-System
Team Plugin-System
 
Benutzerbild von Tomate_Salat
 
Registriert seit: 29.01.2009
Beiträge: 1.105
Blog-Einträge: 6
Abgegebene Danke: 26
Erhielt 56 Danke für 56 Beiträge
Zitat: ice-breaker
Beitrag anzeigen
Ein gutes Format für das Protokoll zu definieren ist dann die nächste schwere Aufgabe.
Siehe hier. Derzeit bin ich auch gerade dabei ein relativ simples Protokoll zu entwickeln, welches aber schwierigkeiten bei Arrays und listen etc hat.

Derzeit überlege ich ob gson (also json) eine alternative für komplexere Objekte wäre. Was ich schnell gemerkt habe: bleib weg von: Objekte über ObjectOutputStream zu senden, die sind einfach zu Groß.

MFG

Tomate_Salat
Tomate_Salat ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 30.07.2010, 17:23   #8 (permalink)
Stammbenutzer
Viertel Gigabyte
 
Benutzerbild von tuxedo
 
Registriert seit: 18.11.2004
Beiträge: 4.658
Abgegebene Danke: 7
Erhielt 58 Danke für 58 Beiträge
Zitat: Tomate_Salat
Beitrag anzeigen
bleib weg von: Objekte über ObjectOutputStream zu senden, die sind einfach zu Groß.
Wo hast du das denn her? Klar, wenn du statt Chat-Nachricht und Benutzername (zwei Strings, evtl gewrappt in einem "Transportobjekt") den ganzen JFrame sendest, ja, dann hast du Overhead wie blöd.

Aber man man mit OOS/OIS durchaus byte-sparend Dinge übertragen: Einfache Transportobjekte die nach Möglichkeit nur aus primitiven bestehen.

Mach ich mit SIMON (und RMI machts nicht anders) auch so. Und die Bandbreite fliegt einem keineswegs um die Ohren...

- Alex
__________________
SIMON, das einfach bessere RMI ...
-> Projektseite
-> Warum SIMON besser ist als RMI
-> Support-Forum
tuxedo ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 30.07.2010, 17:37   #9 (permalink)
Projektleiter Plugin-System
Team Plugin-System
 
Benutzerbild von Tomate_Salat
 
Registriert seit: 29.01.2009
Beiträge: 1.105
Blog-Einträge: 6
Abgegebene Danke: 26
Erhielt 56 Danke für 56 Beiträge
...Getestet?!

Schau mal in meinen Block. Klar ist das Protokoll nicht ausgereift, aber mit einfachen Datentypen schlage ich den ObjectOutputStream schon jetzt um längen! Aber du kannst dir schon eine Menge bytes einsparen, wenn du z.B. auf JSON setzt.

Anmerkung: und mein Update für das Protokoll wird zwar mehr Bytes brauchen, aber trotzdem noch merklich weniger als der OOS und er kann bisher Objekte behandeln, welche variablen vom Typ Number(int, float,...), Character, String und referenzen auf Objekte sind.

Geändert von Tomate_Salat (30.07.2010 um 17:41 Uhr)
Tomate_Salat ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Alt 30.07.2010, 17:55   #10 (permalink)
Stammbenutzer
Viertel Gigabyte
 
Benutzerbild von tuxedo
 
Registriert seit: 18.11.2004
Beiträge: 4.658
Abgegebene Danke: 7
Erhielt 58 Danke für 58 Beiträge
Klar, wenn du einen Handoptimierten Serialisierungs-Algo benutzt, dann ist das immer sparsamer als wenn man einfach "unbedacht" den OOS benutzt.

Aber nimm ein flaches Transport-Objekt das nur primitive und Arrays aus solchen beinhaltet und jag das durch den OOS. SO VIEL overhead produziert das nicht.

Hab Anafangs auch gerätselt ob ich SIMON nicht noch weiter optimieren kann, hier ein zwei byte sparen, dort nochmal eins... Aber braucht man das?

Codesample:

Java Code: Quelltext in neuem Fenster öffnen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Test
{
    
    static class MyTransportClass implements Serializable {
        String s = "HelloWorld"; // 10 bytes + 4 bytes länge
        int i = Integer.MAX_VALUE; // 4 bytes
        int ii = Integer.MIN_VALUE; // 4 bytes
        long l = Long.MAX_VALUE; // 8 bytes
        long ll = Long.MIN_VALUE; // 8 bytes
        boolean b = false; // 1 byte
        
        // total: 14+4+4+8+8+1=39 bytes
    }
    
    public static void main (String[] args) throws IOException
    {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        
        MyTransportClass mtc = new MyTransportClass();
        oos.writeObject(mtc);
        System.out.println(baos.toByteArray().length); // --> 164 bytes
    }
 
}

39 bytes in einem Objekt zu serialisieren, kostet 164 bytes. Macht einen Overhead von 125 bytes.

Klar, das hört sich viel an. Aber hallo... 125 bytes ... Das flitzt selbst über die GPRS Leitung meines Handy nocht mit drüber ohne dass ich's merke ...

Früher, zu 14k4 Modem zeiten ja... Oder 1k2 modem zeiten. Aber im Zeitalter von DSL und Handy-Flats ist es mir wurscht ob ich ein paar bytes extra habe.

Auf der anderen Seite kann man argumentieren: Klar, wenn ich jetzt 1000 solcher Objekte übertragen muss, dann sind das schon 125.000 bytes. Aber selbst hier kommt der durchschnittliche Netzwerkanschluss ohne weiteres mit zurecht.

Auf der anderen Seite: Man muss ja keine Transportobjekte nutzen... Man kann auch ein eigenes Marshalling, wie es RMI z.B. macht nutzen... Ist das zu übertragende etwas etwas "primitives", so nutzt man DataOutputStream und schiebt es direkt durch. Da gibts dann gar keinen Overhead. Ist es allerdings ein Objekt, so nutzt man OOS. Fertig.

Aber letzten endes kommt es auf den Anwendungsbereich an. Und somit gibt's keine ultimative Lösung. Jeder wie er es für richtig hält ...

- Alex

P.S. JBOSS Remoting nutzt eine serialisierung die schneller und besser sein soll als die von Java direkt. Sollte man sich vermutlich mal anschauen: JBoss Serialization - JBoss Community
__________________
SIMON, das einfach bessere RMI ...
-> Projektseite
-> Warum SIMON besser ist als RMI
-> Support-Forum

Geändert von tuxedo (30.07.2010 um 18:00 Uhr)
tuxedo ist offline  
Bei Google nach dem markiertem Wort suchen Bei Wikipedia nach dem markiertem Wort suchen Im Forum nach dem markiertem Wort suchen
Mit Zitat antworten
Antwort    

Lesezeichen

Latex Maths & Physics Editor ...

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln
Es ist Ihnen erlaubt, neue Themen zu verfassen.
Es ist Ihnen erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are aus
Pingbacks are aus
Refbacks are aus


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Server sauber beenden musiKk Netzwerkprogrammierung 6 04.06.2008 20:55
finlalize Methode vom Server wird nicht aufgerufen TeacherMC Netzwerkprogrammierung 4 21.05.2007 11:01
Fehler beim starten von Glassfish siassei84 Allgemeines EE 0 26.02.2007 17:43
InputStream - seltsamer Output Rex Allgemeine Java-Themen 2 07.10.2006 16:09
FindServers - Server im LAN finden! Andy Codeschnipsel u. Projekte 2 22.09.2005 15:07


Alle Zeitangaben in WEZ +2. Es ist jetzt 07:18 Uhr.


Powered by vBulletin® Version 3.8.6 (Deutsch)
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.2
Thanks for Smilies by smilies.4-user.de