2016-11-04 35 views
1

嘿我试图从最近2-3天调试这个程序。问题在于,我构建了一个客户端服务器体系结构,并且所有客户端在使用Socket连接的某个时间间隔后都会ping服务器(使用它们的信息)。因此,在服务器端,当我尝试构造ObjectOutputStream时,程序卡住了。这里是客户端的代码。
程序卡在ObjectInputStream的构造函数

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(); 
} 

这里是服务器的代码

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(); 
       } 
     } 
    } 

服务器程序打印,直到“建立输入流”,并会被卡住。我不知道为什么会发生这种情况,尽管我在客户端刷新了输出流。谢谢。

+2

您应该创建一次流。你的'pingThread'在每个循环中创建一个新的'ObjectOutputStream'。你可能也想通过一些网络教程,否则你会在几个星期内进行调试。 – Kayaman

+0

如果抛出异常,则不关闭套接字。 – EJP

+0

@Kayaman在循环的每次迭代中创建ObjectOutputStream会出现什么问题? – omjego

回答

1

我无法重现挂起的客户端。我认为它必须要做的是如何在不刷新流的情况下将对象写入流,因为只有在流完整或关闭之前才会刷新流。请使用finally块关闭套接字和流。

我已经重写了您的源代码并发送了一个字符串“Hallo,Server”而不是User对象(在您提供的代码中缺少该对象)。发送后,我添加了一些延迟,因为没有连接服务器。

我已经使用JDK 1.8 Update 102测试了Win 8.1上的代码,它现在可以工作。

客户:

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(); 
    } 
} 

服务器:

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(); 
    } 
} 

编辑:TCP协议需要一些时间做TCP握手和服务器上的System.out需要一些时间来输出线和关闭插座。

没有等待在客户端抛出一个java.net.BindException:地址已经在使用:连接 1-2秒后,因为服务器的可用端口。 对于低延迟ping通,UDP协议更好,请参阅example code for a UDP pinger或保持套接字处于打开状态并将其重复用于每个ping。

+0

在联网代码中添加睡眠并不能解决它们。它只会拖延它们。 – EJP