Sockets - Interaktion mit Server

wSam

Erfahrenes Mitglied
Hallo zusammen

Ich möchte mit einem Client mit einem Server über Sockets kommunizieren und Daten austauschen. Zusätzlich möchte ich von einem Client über den Server mit einem anderen, verbundenen Client direkt eine Verbindung haben.

Ich habe jetzt alles mit dem BufferedReader gemacht. Nur ist jetzt das ganze sehr statisch, daher wenn ich vom Client etwas sende, muss der Server genau wissen für was das gut ist, damit der Server es einlesen kann.

Client-Code:
Zuerst loggt sich der Client beim Server ein, bekommt danach eine Liste mit allen verfügbaren Usern, kann dort einen User wählen, mit wem er sich gerne verbinden möchte.

Java:
  private void connect() throws IOException
  {
    try
    {
      kkSocket = new Socket("localhost", 4444);
      out = new PrintWriter(kkSocket.getOutputStream(), true);
      
      in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream()));
      out.println(nameField.getText());
      out.println(numberField.getText());
      // First line is null
      in.readLine();
      String loginSuccessful = in.readLine();
      if ("true".equals(loginSuccessful)) {
        infoLabel.setText("Login successful");
        
        // Receiving the userlist
        String socketList = in.readLine();
        showSocketList(socketList);
        
        System.out.println("LOGGER - " + socketList);
        
        
        Thread clientThread = null;
        if (clientThread == null) {
          clientThread = new Thread(this, "Client");
          clientThread.start();   // start() method in Thread
        }
      }
      else if ("false".equals(loginSuccessful)) {
        infoLabel.setText("Login not successful");
      }
      
      
      
    } catch (UnknownHostException e)
    {
      System.err.println("Don't know about host: localhost.");
      System.exit(1);
    } catch (IOException e)
    {
      System.err.println("Couldn't get I/O for the connection to: localhost.");
      System.exit(1);
    }
  }

Gebe es keine Möglichkeit, direkt ein Objekt vom Server an den Client zu schicken? (Mal abgesehen von RMI, oder sollte ich doch lieber RMI verwenden?)

Und wie könnte ich jetzt eine Verbindung von einem Client über den Server zu einem anderen Client aufbauen?

Vielen Dank im Voraus und Gruss
 
Hi,

also du kannst Objekte, die das Interface Serializable implementieren
mittels ObjectInput/OutputStream schreiben bzw. lesen. Das schöne dabei ist, dass beide von Input bzw. OutputStream abgeleitet sind. Allerdings weißt du dann nicht um was für ein Objekt es sich dabei handelt

Für die Kommunikation von einem Client zum anderen könntest du eine Klasse schreiben die auf dem Server die Infos von einem Client zum anderen weiterleitet.

Vorteil: Relativ easy zu machen.
Nachteil: Serverlast


Alternativ könntest du aber auch dem Server deine IP / Port übergeben. Der andere Client kann sich dann die IP / Port abholen und dann dorthin connecten.

Vorteil: Direkte Verbindung zwischen den Clients
Nachteil: Einer der Clients spielt dann doch den Server. Aufwand für die IP (muss halt passen für lokales Netz bzw. Inet)


Denkbar wären auch noch UDP Pakete da mit diesen auch eine Peer to Peer Verbindung realisierbar wäre.

Vorteil: Peer to Peer Verbindung möglich auch mit mehreren Clientes
Nachteil: Paketmanagement muss implementiert werden (nicht so easy)

Gruß 4men
 
Zuletzt bearbeitet:
Moin!
4men hat gesagt.:

also du kannst Objekte, die das Interface Serializable implementieren
mittels ObjectInput/OutputStream schreiben bzw. lesen. Das schöne dabei ist, dass beide von Input bzw. OutputStream abgeleitet sind. Allerdings weißt du dann nicht um was für ein Objekt es sich dabei handelt
Doch, darum geht es ja beim Serialisieren, dass alle benötigen Informationen eingepackt werden. Mit beispielweise "instanceof" kann man den Klassentyp des wieder deserialisierten Objekts überprüfen, bevor man es in das entsprechende Objekt zurückcastet.


Eine Möglichkeit wäre auch das JXTAFramework http://jxta.org.
Da musst du dir über IPs, NAT, Firewalls etc keine Gedanken mehr machen, da es ein von IPAdressen abstrahiertes Overlaynetzwerk nutzt. Sehr nützlich wenn deine Clients bzw der Server sich nicht im selben Subnetz befinden, kein Portforwarding oder globale IPs möglich ist.

*grüssle*
MeinerEiner
 
Danke für die Tipps.

Da musst du dir über IPs, NAT, Firewalls etc keine Gedanken mehr machen, da es ein von IPAdressen abstrahiertes Overlaynetzwerk nutzt.

Bekomme ich da mit normalen Sockets Probleme, wenn ich von einem NAT-Netzwerk in ein anderes NAT-Netzwerk oder ins Internet verbinden will?


Für die Kommunikation von einem Client zum anderen könntest du eine Klasse schreiben die auf dem Server die Infos von einem Client zum anderen weiterleitet.

Ich habe für jeden Clienten einen eigenen Thread erstellt, wie kann ich dann zwischen zwei Threads kommunizieren?

Gruss
 
wSam hat gesagt.:
Bekomme ich da mit normalen Sockets Probleme, wenn ich von einem NAT-Netzwerk in ein anderes NAT-Netzwerk oder ins Internet verbinden will?

Nehmen wir mal an, ich sitze in einem Netzwerk, in dem der Router "NATtet"( was auch der Fall ist). D.h. ich habe eine Lokale IP-Adresse wie zum Beispiel "192.168.10.99".
Wie schaffst du es jetzt, mit den normalen java Sockets bzw. irgendwie sonst dich direkt mit mir zu verbinden?
Ausser mit irgendwelche Tricks a la portforwaring erstmal garnicht.


Ich würde dir eins empfehlen. Höre erstmal auf wild drauflos zu proggen.
Mach dir erstmal eine gescheites Konzept, lese dich in die Grundlagen von Netzwerken ein.
Also zum Beispiel:
Was für Knoten sind in deinem Netzwerk vorhanden: lokale Clients, global zugängliche, "NAT" Clients.. etc...
Was willst du nutzen : Peer-to-Peer (eigen oder JXTA),, klassisches Client Server..
etc.etc.

Sobald du genau weist, was du willst, wie du es willst und auch die Grundlagen verstanden hast, solltest du erst anfangen das auch zu programmieren. Glaube mir, sonst kommen da nur halb gelegte Eier raus.

*grüssle*
MeinerEiner
 
@MeinerEiner_80

Danke für den Hinweis und die Hilfe. Ich werde deinen Rat befolgen und mir nochmals gründlich überlegen wie ich das ganze am besten aufbaue. :)

Gruss
 
wSam hat gesagt.:
Ich habe für jeden Clienten einen eigenen Thread erstellt, wie kann ich dann zwischen zwei Threads kommunizieren?
Gruss
Möglichkeiten gibts genug am einfachsten sollte jedoch eine synchronisierte Liste bzw. Queue sein die du beiden beim erzeugen übergibst. Dann können beide lesend / schreibend drauf zugreifen. Kannst dir dazu mal das Paket java.util.concurrent anschauen.

Gruß 4men
 
Zurück