Frage

Ich bin der Aufbau eine einfache Client / Server-Anwendung Java-Sockets und das Experimentieren mit dem Object etc.

Ich verfolge das Tutorial an dieser URL http: //java.sun .com / Entwickler / technicalArticles / ALT / Steckdosen halben Weg nach unten beginnen, wenn es um den Transport von Objekten über Sockets spricht.

Sehen Sie meinen Code für den Client http: // Pastebin. com / m37e4c577 Allerdings scheint dies nicht zu arbeiten, und ich kann nicht herausfinden, was nicht funktioniert. Der Code unten auf Kommentar wird direkt aus dem Tutorial kopiert - und das funktioniert, wenn ich verwende nur, dass stattdessen das Client-Objekt zu erstellen.

Kann jemand sehen, was ich tue falsch?

War es hilfreich?

Lösung

Das Problem ist die Reihenfolge Sie die Streams erstellen:

In dem Server aus dem Artikel (was ich davon ausgehen, ist das, was Sie verwenden), wenn eine neue Verbindung geöffnet wird, öffnet der Server zunächst einen Eingangsstrom, und dann einem Ausgangsstrom:

public Connect(Socket clientSocket) {
 client = clientSocket;
 try {
  ois = new ObjectInputStream(client.getInputStream());
  oos = new ObjectOutputStream(client.getOutputStream());
 } catch(Exception e1) {
     // ...
 }
 this.start();
}

Die kommentierten Beispiel Code verwendet die umgekehrte Reihenfolge, zuerst den Ausgangsstrom zur Festlegung, dann wird der Eingangsstrom:

// open a socket connection
socket = new Socket("localhost", 2000);
// open I/O streams for objects
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());

Aber Ihr Code macht es umgekehrt:

server = new Socket(host, port);
in = new ObjectInputStream(server.getInputStream());
out = new ObjectOutputStream(server.getOutputStream());

Aufbau einen Ausgangsstrom / Eingangsstrom Paar wird abgewürgt, bis sie ihre Handshake-Informationen ausgetauscht haben, so dass Sie die Ordnung der Schöpfung müssen übereinstimmen. Sie können dies nur tun, durch die Linien 34 und 35 in dem Beispielcode austauschen.

Andere Tipps

Sie schreiben das Objekt nicht überall.

Wir sehen uns wieder auf diesen Link, irgendwo muss man schreiben:

 oos.writeObject( new Date() );

In Ihrem Code Sie haben

ois.readObject();

Deshalb

Nur zur Erinnerung.

Wenn Sie Object verwenden bedenken Sie, dass es einen Verweis-Cache hält. Wenn Sie ein Objekt schreiben, ändern Sie die Objektinhalte und dann wieder das gleiche Objekt senden, erhalten Sie doppelte Daten bekommen. Zum Beispiel:

List list = new ArrayList();
list.add("value1");
out.writeObject(list);
list.clear();
list.add("value2");
out.writeObject(list);

Wird in der Client-Seite zwei Listen mit der Zeichenfolge „Wert1“ erzeugen.

Um dies zu vermeiden, muss der Reset-Methode aufgerufen werden, um den Strom-Cache zurückzusetzen, wenn die gleichen Objektverweis mehrmals zu schreiben:

List list = new ArrayList();
list.add("value1");
out.writeObject(list);
out.reset();
list.clear();
list.add("value2");
out.writeObject(list);

Wahrscheinlich werden Sie mögen die grundlegendsten zuerst lernen.

Hier ist eine Probe Ich habe gerade codiert.

Es starten Server , das kümmert sich nur ein Client, und es sendet ein Objekt und sterben.

Wenn der Benutzer (Sie) drücken Sie die Eingabetaste, ein neues Client erstellt wird, verbindet es mit dem zuvor erstellten Server und lesen Sie das Objekt, das Server senden.

Es wird keine Ausnahme hier behandelt. Nur um die Dinge einfacher, aber dies ist nicht die Art und Weise Ausnahme behandelt werden soll.

Wenn Sie alle Konzepte hier zu verstehen, wird es leichter sein, die in der Anleitung zu verstehen.

import java.io.*;
import java.net.*;
import java.util.*;

public class SimpleServer implements Runnable { 

     // Creates the server, send a "date" and die.
    public void run() { 
        try {
            ServerSocket server = new ServerSocket( 8090 );
            Date creationDate = new Date();
            System.out.println("(Server) Server is ready " 
                                 + "and running at " + creationDate );

            Socket uniqueClient = server.accept();

            // We will write using this "chained" object.
            ObjectOutputStream out = new ObjectOutputStream( 
                                                 uniqueClient.getOutputStream());

            out.writeObject( creationDate );


            // close all, at this point forget about the exceptions.
            // this is lesson #1      
            out.close();

            uniqueClient.close();

            server.close();        

            System.out.println("(Server) The server is down");
        }catch( IOException ioe ) {}

     }

    public static void main ( String [] args ) throws IOException ,
                                                 ClassNotFoundException { 

         Thread serverThread = new Thread( new SimpleServer() );

         serverThread.start(); // start the server thread ... doh..

         System.out.println("(Client) Press enter when you want "+ 
                               " to connect to the server...");

         Scanner scanner = new Scanner( System.in );

         scanner.nextLine();

         Socket client = new Socket("localhost", 8090 );

         // Read from this object.
         ObjectInputStream in = new ObjectInputStream( client.getInputStream() );

         Date date = ( Date ) in.readObject();

         System.out.println("(Client) Current time is:          " + new Date() );
         System.out.println("(Client) Object read from server : " + date );

         in.close();
         client.close();

    }
}

Ich hoffe, das hilft.

Wenn Sie einen Debugger versucht, es habe Ihnen gesagt, wo das Problem war. (Vielleicht nicht warum)

Das Problem, das Sie haben, ist, dass Object einen Header schreibt und liest Object diesen Header. Sie haben die Object zuerst erstellt, was bedeutet, es versucht, einen Header zu lesen, die nie geschrieben werden.

. Lösung: Erstellen Sie immer die Object erste und flush (), bevor das Object Erstellen

Es ist besser, ein outputStream zu öffnen, weil ein Ausgangsstrom nicht blockiert. Dann haben Sie den Eingangsstrom, der für eine Stream wartet. Nachdem alle Bäche, schreiben Sie in den Stream und spülen Sie es - outputStream.flush() die Bytes von Daten zu senden. Sie brauchen auch eine Methode auf dem anderen Ende der Eingabe zu lesen, ob es einfach inputStream.read() die jedes Byte als eine ganze Zahl für eine char liest, oder durch einen BufferedReader oder Scanner verwenden. Ich habe fast alle Methoden möglich, aber die effektivste Methode für das Senden ist outputStream.write(String) verwendet, die eine Folge von chars als bytes in den Strom schreibt und liest inputStream.read() liest ein einzelnes char. Ich hoffe, das hilft.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top