2016-11-04 8 views
1

Hey Ich versuche dieses Programm aus den letzten 2-3 Tagen zu debuggen. Hier ist das Problem, ich baue eine Client-Server-Architektur und alle Clients Ping-Server (mit ihren Informationen) nach bestimmten Zeitintervallen mit Socket-Verbindung.So auf der Serverseite, wenn ich versuche, einen ObjectOutputStream zu konstruieren das Programm stecken bleiben. Hier ist der Code des Kunden.
Programm bei ObjectInputStream-Konstruktor stecken

public void pingUpdate(){ 
    Thread pingThread = new Thread() { 
    public void run() { 
     while(true) { 
      try { 
       ping_socket = new Socket("localhost", 11111); 
       ObjectOutputStream ping_objectOutputStream = new ObjectOutputStream(ping_socket.getOutputStream()); 
       ping_objectOutputStream.flush(); 

       ping_objectOutputStream.writeObject(user); 

       ping_objectOutputStream.close(); 

       ping_socket.close(); 

      }catch (Exception exception) { 
       exception.printStackTrace(); 
      } 
      } 
    }; 
    pingThread.start(); 
} 

Und hier ist der Code des Servers

public void run() { 
while (true) { 
     try { 

      System.out.println("Server Listening"); 

      Socket client = null; 

      client = serverSock.accept(); 
      System.out.println("Accepted"); 

      InputStream inputStream = client.getInputStream(); 

      System.out.println("Input stream established"); 

      ObjectInputStream ois = new ObjectInputStream(inputStream); 

       System.out.println("Object streams established"); 

       User user = (User) ois.readObject(); 

       System.out.println("Object read"); 

       ois.close(); 
       client.close(); 
      } 
       catch (Exception e){ 
        e.printStackTrace(); 
       } 
     } 
    } 

Die Server-Programm druckt bis "Input-Streams etabliert" und steckt. Ich weiß nicht, warum das passiert, obwohl ich den Ausgabestrom auf Client-Seite flushed.Thanks.

+2

Sie sollten Ihren Stream einmal erstellen. Ihr 'pingThread' erzeugt einen neuen' ObjectOutputStream' in jeder Schleife. Vielleicht möchten Sie auch einige Netzwerktutorials durchgehen, sonst werden Sie wochenlang debuggen. – Kayaman

+0

Wenn eine Ausnahme ausgelöst wird, schließen Sie den Socket nicht. – EJP

+0

@Kayaman Was ist das Problem beim Erstellen von ObjectOutputStream bei jeder Iteration der Schleife? – omjego

Antwort

1

Ich kann den hängenden Client nicht reproduzieren. Ich denke, es muss tun, wie Sie das Objekt in den Stream schreiben, ohne den Stream danach zu leeren, weil Streams nur dann ausgeleert werden, wenn sie voll sind oder bevor sie schließen. Bitte benutze finally Blöcke, um die Sockets und Streams zu schließen.

Ich habe Ihren Quellcode umgeschrieben und eine Zeichenfolge "Hallo, Server" anstelle des Benutzerobjekts (das in dem von Ihnen angegebenen Code fehlt) gesendet. Ich habe nach dem Senden eine kleine Verzögerung hinzugefügt, um den Server nicht mit Verbindungen zu überfluten.

Ich habe den Code auf Win 8.1 mit JDK 1.8 Update 102 getestet und es funktioniert jetzt.

Auftraggeber:

import java.io.IOException; 
import java.io.ObjectOutputStream; 
import java.net.Socket; 

public class Client{ 

    public static void main(String[] args){ 

     new Client().pingUpdate(); 
    } 

    public void pingUpdate(){ 

     Thread pingThread = new Thread(){ 

     @Override 
     public void run(){ 

      while(true){ 
       Socket ping_socket = null; 
       ObjectOutputStream ping_objectOutputStream = null; 
       try{ 
        ping_socket = new Socket("localhost", 
              11111); 
        ping_objectOutputStream = new ObjectOutputStream(ping_socket.getOutputStream()); 

        ping_objectOutputStream.writeObject("Hallo, Server"); 
        ping_objectOutputStream.flush(); 
       } 
       catch(Exception exception){ 
        exception.printStackTrace(); 
       } 
       finally{ 
        try{ 
        if (ping_objectOutputStream != null){ 
         ping_objectOutputStream.close(); 
        } 
        } 
        catch(IOException e){ 
        e.printStackTrace(); 
        } 
        try{ 
        if (ping_socket != null){ 
         ping_socket.close(); 
        } 
        } 
        catch(IOException e){ 
        e.printStackTrace(); 
        } 
       } 

       // wait some time for the next ping 
       try{ 
        Thread.sleep(1000); 
       } 
       catch(InterruptedException e){ 
        e.printStackTrace(); 
       } 
      } 
     } 
     }; 
     pingThread.start(); 
    } 
} 

Server:

import java.io.IOException; 
import java.io.InputStream; 
import java.io.ObjectInputStream; 
import java.net.ServerSocket; 
import java.net.Socket; 

public class Server{ 

    public void servePingUpdate(){ 

     Thread pingThread = new Thread(){ 

     @Override 
     public void run(){ 

      ServerSocket serverSock = null; 
      try{ 
       serverSock = new ServerSocket(11111); 

       while(true){ 
        Socket client = null; 
        ObjectInputStream ois = null; 

        try{ 
        System.out.println("Server Listening"); 

        client = serverSock.accept(); 
        System.out.println("Accepted"); 

        InputStream inputStream = client.getInputStream(); 

        System.out.println("Input stream established"); 

        ois = new ObjectInputStream(inputStream); 

        System.out.println("Object streams established"); 

        String message = (String) ois.readObject(); 

        System.out.println("Object read: " + message); 
        } 
        catch(Exception e){ 
        e.printStackTrace(); 
        } 
        finally{ 
        try{ 
         if (ois != null){ 
          ois.close(); 
         } 
        } 
        catch(IOException e){ 
         e.printStackTrace(); 
        } 
        try{ 
         if (client != null){ 
          client.close(); 
         } 
        } 
        catch(IOException e){ 
         e.printStackTrace(); 
        } 
        } 
       } 
      } 
      catch(IOException e1){ 
       e1.printStackTrace(); 
      } 
      finally{ 
       try{ 
        if (serverSock != null){ 
        serverSock.close(); 
        } 
       } 
       catch(IOException e){ 
        e.printStackTrace(); 
       } 
      } 
     } 
     }; 
     pingThread.start(); 
    } 

    public static void main(String[] args){ 

     new Server().servePingUpdate(); 
    } 
} 

EDIT: Das TCP-Protokoll einige Zeit braucht die TCP-Handshake zu tun, und der Server dauert einige Zeit zur Ausgabe der Linien über System.out und um den Sockel zu schließen.

Ohne die Wartezeit im Client löst eine java.net.BindException: Adresse bereits verwendet: Verbinden Sie nach 1-2 Sekunden, da der Server nicht mehr verwendbare Ports ist. Für Ping mit niedriger Latenz ist das UDP-Protokoll besser, siehe example code for a UDP pinger oder halten Sie den Socket offen und verwenden Sie ihn für jeden Ping erneut.

+0

Durch das Hinzufügen von Betten in den Netzwerkcode werden diese nicht gelöst. Es verzögert sie nur. – EJP