2009-04-07 14 views
0

Gibt es Beispiele für einen Server und einen Client, die Sockets verwenden, aber über Sende- und Abrufmethoden verfügen? Ich mache dieses vernetzte Schlachtschiffprogramm fast fertig, kann aber den Server und die Clients nicht zum Arbeiten bringen. Ich habe ein Chat-Programm erstellt, das nur Strings sendet, aber dieses Mal muss ich Objekte senden. Ich bin schon frustriert, also gibt es irgendeinen Quellcode, der das schon hat.Server und Client mit Sockets

Hier ist der Code für den Client ... wie würden Sie es ändern, um Objekte senden zu können? Außerdem muss ich eingehende Objekte abhören und sie sofort verarbeiten.

import java.net.*; 
import java.io.*; 
import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class SimpleChat extends JFrame { 
    private Socket   communicationSocket = null; 
    private PrintWriter outStream    = null; 
    private BufferedReader inStream    = null; 
    private Boolean  communicationContinue = true; 
    private String   disconnectString  = "disconnect764*#$1"; 
    private JMenuItem  disconnectItem; 
    private JTextField  displayLabel; 
    private final Color colorValues[]   = { Color.black, Color.blue, Color.red, Color.green }; 

    // set up GUI 
    public SimpleChat() { 
    super("Simple Chat"); 

    // set up File menu and its menu items 
    JMenu fileMenu = new JMenu("File"); 
    fileMenu.setMnemonic('F'); 

    // set up Activate Server menu item 
    JMenuItem serverItem = new JMenuItem("Activate Server"); 
    serverItem.setMnemonic('S'); 
    fileMenu.add(serverItem); 
    serverItem.addActionListener(new ActionListener() { // anonymous inner class 
       // display message dialog when user selects About... 
       public void actionPerformed(ActionEvent event) { 
        setUpServer(); 
       } 
       } // end anonymous inner class 
      ); // end call to addActionListener 

    // set up Activate Client menu item 
    JMenuItem clientItem = new JMenuItem("Activate Client"); 
    clientItem.setMnemonic('C'); 
    fileMenu.add(clientItem); 
    clientItem.addActionListener(new ActionListener() { // anonymous inner class 
       // display message dialog when user selects About... 
       public void actionPerformed(ActionEvent event) { 
        setUpClient(); 
       } 
       } // end anonymous inner class 
      ); // end call to addActionListener 

    // set up Activate Client menu item 
    disconnectItem = new JMenuItem("Disconnect Client/Server"); 
    disconnectItem.setMnemonic('D'); 
    disconnectItem.setEnabled(false); 
    fileMenu.add(disconnectItem); 
    disconnectItem.addActionListener(new ActionListener() { // anonymous inner 
        // class 
        // display message dialog when user selects About... 
        public void actionPerformed(ActionEvent event) { 
         disconnectClientServer(true); 
        } 
        } // end anonymous inner class 
       ); // end call to addActionListener 

    // set up About... menu item 
    JMenuItem aboutItem = new JMenuItem("About..."); 
    aboutItem.setMnemonic('A'); 
    fileMenu.add(aboutItem); 
    aboutItem.addActionListener(new ActionListener() { // anonymous inner class 
       // display message dialog when user selects About... 
       public void actionPerformed(ActionEvent event) { 
       JOptionPane.showMessageDialog(SimpleChat.this, "This is an example\nof using menus", "About", 
               JOptionPane.PLAIN_MESSAGE); 
       } 
      } // end anonymous inner class 
      ); // end call to addActionListener 

    // set up Exit menu item 
    JMenuItem exitItem = new JMenuItem("Exit"); 
    exitItem.setMnemonic('x'); 
    fileMenu.add(exitItem); 
    exitItem.addActionListener(new ActionListener() { // anonymous inner class 
       // terminate application when user clicks exitItem 
       public void actionPerformed(ActionEvent event) { 
       disconnectClientServer(true); 
       System.exit(0); 
       } 
      } // end anonymous inner class 
      ); // end call to addActionListener 

    // create menu bar and attach it to MenuTest window 
    JMenuBar bar = new JMenuBar(); 
    setJMenuBar(bar); 
    bar.add(fileMenu); 

    // set up label to display text 
    displayLabel = new JTextField("Sample Text", SwingConstants.CENTER); 
    displayLabel.setForeground(colorValues[0]); 
    displayLabel.setFont(new Font("Serif", Font.PLAIN, 72)); 
    displayLabel.addActionListener(new ActionListener() { // anonymous inner 
        // class 
        // display message dialog when user selects About... 
        public void actionPerformed(ActionEvent event) { 
        sendData(); 
        } 
       } // end anonymous inner class 
       ); // end call to addActionListener 

    getContentPane().setBackground(Color.CYAN); 
    getContentPane().add(displayLabel, BorderLayout.CENTER); 

    setSize(500, 200); 
    setVisible(true); 

    } // end constructor 

    public static void main(String args[]) { 
    final SimpleChat application = new SimpleChat(); 
    application.addWindowListener(new WindowAdapter() { 
     public void windowClosing(WindowEvent e) { 
     application.disconnectClientServer(true); 
     System.exit(0); 
     } 
    }); 

    // application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

    public void setCommunicationSocket(Socket sock) { 
    communicationSocket = sock; 
    communicationContinue = true; 
    disconnectItem.setEnabled(true); 
    } 

    public void setOutStream(PrintWriter out) { 
    outStream = out; 
    } 

    public void setInStream(BufferedReader in) { 
    inStream = in; 
    } 

    public void setUpServer() { 
    ServerThread st = new ServerThread(this); 
    st.start(); 
    } 

    public void setUpClient() { 
    ClientThread st = new ClientThread(this); 
    st.start(); 
    } 

    public void disconnectClientServer(Boolean sendMessage) { 
    if (communicationSocket == null) 
     return; 

    try { 
     // shut down socket read loop 
     communicationContinue = false; 
     disconnectItem.setEnabled(false); 

     // send notification to other end of socket 
     if (sendMessage == true) 
     outStream.println(disconnectString); 

     // sleep to let read loop shut down 
     Thread t = Thread.currentThread(); 
     try { 
     t.sleep(500); 
     } catch (InterruptedException ie) { 
     return; 
     } 

     outStream.close(); 
     inStream.close(); 
     communicationSocket.close(); 
    } catch (IOException e) { 
     System.err.println("Stream Read Failed."); 
     JOptionPane.showMessageDialog(SimpleChat.this, "Disconnection Failed", "SimpleChat", JOptionPane.PLAIN_MESSAGE); 
     return; 
    } finally { 
     communicationSocket = null; 
    } 
    } 

    public void sendData() { 
    if (communicationSocket != null) { 
     String data = displayLabel.getText(); 
     outStream.println(data); 
    } 
    } 

    public void getData() { 
    String inputLine; 
    try { 
     while (communicationContinue == true) { 
     communicationSocket.setSoTimeout(100); 
     // System.out.println ("Waiting for Connection"); 
     try { 
      while (((inputLine = inStream.readLine()) != null)) { 
      System.out.println("From socket: " + inputLine); 
      if (inputLine.equals(disconnectString)) { 
       disconnectClientServer(false); 
       return; 
      } 
      displayLabel.setText(inputLine); 
      } 
     } catch (SocketTimeoutException ste) { 
      // System.out.println ("Timeout Occurred"); 
     } 
     } // end of while loop 
     System.out.println("communication is false"); 
    } catch (IOException e) { 
     System.err.println("Stream Read Failed."); 
     JOptionPane.showMessageDialog(SimpleChat.this, "Input Stream read failed", "SimpleChat", 
            JOptionPane.PLAIN_MESSAGE); 
     return; 
    } 
    } 
} 

class ServerThread extends Thread { 
    private SimpleChat sc; 
    private JTextField display; 

    public ServerThread(SimpleChat scParam) { 
    sc = scParam; 
    } 

    public void run() { 
    ServerSocket connectionSocket = null; 

    try { 
     connectionSocket = new ServerSocket(10007); 
    } catch (IOException e) { 
     System.err.println("Could not listen on port: 10007."); 
     JOptionPane.showMessageDialog(sc, "Could not listen on port: 10007", "Server", JOptionPane.PLAIN_MESSAGE); 
     return; 
    } 

    JOptionPane.showMessageDialog(sc, "Server Socket is now activated", "Server", JOptionPane.PLAIN_MESSAGE); 

    Socket communicationSocket = null; 

    try { 
     communicationSocket = connectionSocket.accept(); 
    } catch (IOException e) { 
     System.err.println("Accept failed."); 
     JOptionPane.showMessageDialog(sc, "Accept failed", "Server", JOptionPane.PLAIN_MESSAGE); 
     return; 
    } 

    JOptionPane.showMessageDialog(sc, "Comminucation is now activated", "Server", JOptionPane.PLAIN_MESSAGE); 

    try { 
     PrintWriter out = new PrintWriter(communicationSocket.getOutputStream(), true); 
     BufferedReader in = new BufferedReader(new InputStreamReader(communicationSocket.getInputStream())); 

     sc.setCommunicationSocket(communicationSocket); 
     sc.setOutStream(out); 
     sc.setInStream(in); 

     connectionSocket.close(); 

     sc.getData(); 

    } catch (IOException e) { 
     System.err.println("Accept failed."); 
     JOptionPane.showMessageDialog(sc, "Creation of Input//Output Streams failed", "Server", JOptionPane.PLAIN_MESSAGE); 
     return; 
    } 
    } 
} 

class ClientThread extends Thread { 
    private SimpleChat sc; 

    public ClientThread(SimpleChat scParam) { 
    sc = scParam; 
    } 

    public void run() { 
    Socket echoSocket = null; 
    PrintWriter out = null; 
    BufferedReader in = null; 
    String ipAddress = "127.0.0.1"; 

    try { 
     echoSocket = new Socket(ipAddress, 10007); 
     out = new PrintWriter(echoSocket.getOutputStream(), true); 
     in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream())); 
    } catch (UnknownHostException e) { 
     System.err.println("Don't know about host: " + ipAddress); 
     JOptionPane.showMessageDialog(sc, "Don't know about host: " + ipAddress, "Client", JOptionPane.PLAIN_MESSAGE); 
     return; 
    } catch (IOException e) { 
     System.err.println("Couldn't get I/O for " + "the connection to: " + ipAddress); 
     JOptionPane.showMessageDialog(sc, "Couldn't get I/O for the connection to: " + ipAddress, "Client", 
            JOptionPane.PLAIN_MESSAGE); 
     return; 
    } 
    JOptionPane.showMessageDialog(sc, "Comminucation is now activated", "Client", JOptionPane.PLAIN_MESSAGE); 

    sc.setCommunicationSocket(echoSocket); 
    sc.setOutStream(out); 
    sc.setInStream(in); 

    sc.getData(); 
    } 
} 
+0

dies wäre viel klarer, wenn ohne den zusätzlichen Code –

+0

Siehe [diese Stackoverflow-Antwort] (http://stackoverflow.com/questions/707987/java-serialization-over-network/708717#708717) für eine Verweis auf ein Lernprogramm, das die Objektserialisierung und das anschließende Senden/Abrufen über Sockets ohne Verwendung von RMI miteinander verknüpft. –

Antwort

0

ich irgendwo eine Implementierung da draußen hat sich nicht die Mühe gemacht, Ihre Stapel und Stapel von Code zu lesen, aber im Allgemeinen können Sie Objekte nicht direkt über das Netzwerk senden. Die Netzwerkkommunikation besteht nur aus Bits und Bytes. Wenn Sie Objekte senden möchten, müssen Sie diese auf der Sendeseite serialisieren und sie auf der Empfangsseite deserialisieren. Es gibt Unmengen von Methoden der Serialisierung, zB JSON, XML oder sogar die eingebaute Serialisierung von Java (nur empfohlen, wenn sowohl der Client als auch der Server immer Java sind).

5

Ich schlage vor, Sie lesen auf Java-Serialisierung. Es gibt ein Beispiel here. Im Grunde wird Serialisierungsunterstützung eingebaut. Ihre Klasse muss Serializable implementieren. Dann verwenden Sie ObjectOutputStream und ObjectInputStream, um Objekt zu schreiben.

1

Ihr auf dem richtigen Weg. Ein Chat-Programm ist ein guter Ort, um über Sockets zu lernen.

Was Sie wollen, ist die ObjectOutputStream und ObjectInputStream Klassen zu verwenden. Sie müssen Ihren Eingabestream/Ausgabestream einfach mit diesen Filtern umschließen. ObjectOutputStream hat eine Methode writeObject(), und ObjectInputStream hat eine entsprechende readObject() -Methode.

Die meisten Serialisierungsbeispiele zeigen das Lesen und Schreiben von Objekten in eine Datei, aber das Gleiche kann mit einem Socket-Stream geschehen. Siehe http://www.acm.org/crossroads/xrds4-2/serial.html

0

Sie können diesen Code zu einem guten Ausgangspunkt für Ihre eigene Klasse finden. Dies sind zwei Klassen habe ich zu wenig abstrakt die Arbeit, die für TCP und UDP-Socket-Protokolle:

http://code.google.com/p/hivewars/source/browse/trunk/SocketData.java http://code.google.com/p/hivewars/source/browse/trunk/UDPSocket.java

Schnell Dislaimer: Dies sind die Art von Versionen einer Funktion voller Klasse, ich habe gerade zusätzliche Funktionalität, wie ich brauchte es. Es könnte Ihnen jedoch helfen, zu starten.