2015-02-12 40 views
1

好的,所以我编写了一个简单的使用服务器的通信程序,真的比其他任何东西都更像一个测试,所以我知道它很少,但与下面的客户端类:从套接字声明输入/输出流阻止程序继续

public class Client { 
    private ObjectInputStream in; 
    private ObjectOutputStream out; 

    private Socket socket; 

    private String server; 
    private int port; 

    public Client(String ip, int p){ 
     port = p; 
     server = ip; 
    } 

    public boolean start(){ 
     try{ 
      socket = new Socket(server, port); 
     }catch(Exception e){ 
      System.out.println("Exception"); 
      e.printStackTrace(); 
      return false; 
     } 
     try{ 
      in = new ObjectInputStream(socket.getInputStream()); 
      out = new ObjectOutputStream(socket.getOutputStream()); 
      System.out.println("All declared"); 
     }catch(Exception e){ 
      System.out.println("Exception"); 
      e.printStackTrace(); 
      return false;} 
     new LThread().start(); 
     return true; 
    } 

    private void sendMessage(Message msg){ 
     try{ 
     out.writeObject(msg); 
     }catch(Exception e){} 
    } 

    public static void main(String[] args){ 
     int portNum = 1500; 
     String servers = "localhost"; 

     Client client = new Client(servers, portNum); 

     System.out.println("Client started"); 

     if(!client.start()){ 
      System.out.println("Didn't work"); 
      return; 
     } 

     System.out.println("Client started again"); 


     Scanner scan = new Scanner(System.in); 

     while(true){ 
      String i = scan.nextLine(); 
      client.sendMessage(new Message(2, i)); 
     } 
    } 

    class LThread extends Thread{ 

     public void run(){ 
      System.out.println("Lthread running"); 
      while(true){ 
       try{ 
        String message = (String)in.readObject(); 
        System.out.println(message); 
       }catch(Exception e){ 
        e.printStackTrace();} 
      } 
     } 

    } 
} 

程序时,它达到它宣称其ObjectInputOutputStream了问题的实质只是停止。该程序没有退出,它似乎没有进入catch区块,我根本无法弄清楚究竟是什么导致了它。 “所有声明”行。从不打印,但是打印之前的任何东西。任何人都可以告诉我为什么我的程序在这个时候停止运行而没有显示任何错误?

编辑:我的身影,有可能在我的服务器文件的地方是一个错误,所以这里的类:

public class Server { 

    private static int uid; 

    private ArrayList<ClientThread> clients; 
    private int port; 
    private boolean cont; 

    public Server(int p){ 
     port = p; 
     clients = new ArrayList<ClientThread>(); 
    } 

    public void start(){ 
     System.out.println("Started"); 
     cont = true; 
     try{ 
      ServerSocket srvr = new ServerSocket(port); 
      System.out.println("Declared socket"); 
      while(cont){ 
       Socket sk = srvr.accept(); 
       System.out.println("Socket accepted"); 

       if(!cont)break; 

       ClientThread t = new ClientThread(sk); 
       clients.add(t); 
       t.start(); 
      } 
      try{ 
       srvr.close(); 
       for(ClientThread t : clients){ 
        t.in.close(); 
        t.out.close(); 
        t.socket.close(); 
       } 
      }catch(Exception e){ 
       e.printStackTrace(); 
      } 
     }catch(Exception e){ 

      e.printStackTrace(); 
     } 
    } 

    private synchronized void broadcast(String msg){ 
     for(int i=clients.size(); --i >= 0;){ 
      ClientThread t= clients.get(i); 
       if(!t.writeMsg(msg)){ 
        clients.remove(i); 
       } 
     } 
    } 

    public static void main(String[] args){ 
     int portNum = 1500; 

     Server server = new Server(portNum); 
     server.start(); 
    } 

    class ClientThread extends Thread{ 
     Socket socket; 
     ObjectInputStream in; 
     ObjectOutputStream out; 
     String name; 
     int id; 
     Message m; 

     ClientThread(Socket s){ 
      id = ++uid; 
      socket = s; 
      try{ 
       System.out.println("Before"); 
       in = new ObjectInputStream(socket.getInputStream()); 
       out = new ObjectOutputStream(socket.getOutputStream()); 
       System.out.println("After"); 
      }catch(Exception e){ 
       e.printStackTrace();} 
     } 

     public void run(){ 
      boolean c = true; 
      while(c){ 
       try{ 
        m = (Message)in.readObject(); 
        switch(m.getType()){ 
        case 2: 
         broadcast(m.getMessage()); 
        } 
       }catch (Exception e){ 
        e.printStackTrace();} 
      } 
     } 

     public boolean writeMsg(String msg){ 
      if(!socket.isConnected()){ 
       return false; 
      } 
      try{ 
       out.writeObject(msg); 
      }catch(Exception e){ 
       e.printStackTrace();} 
      return true; 
     } 
    } 

} 

好吧,另一个编辑。所以我在ClientThread的构造函数中将这两个println s添加到try声明中,就像客户端一样,它会运行,直到我尝试初始化流,然后它停止。再次,没有错误,没有任何东西;它完全停止在它的轨道上。我无法弄清楚为什么发生这种情况,但如果它意味着什么,我使用Eclipse IDE来运行它。

+0

只是一个提示:打印“所有声明”之上的两行不声明任何东西。 – immibis 2015-02-12 02:36:30

+0

你怎么知道它没有卡在'新的套接字(服务器,端口)'? – immibis 2015-02-12 02:37:50

+0

@immibis正确,但将输出更改为“All assigned。”。不会真的让代码运行得更好。 – user2649681 2015-02-12 02:38:06

回答

1

我在第一次使用时就挂了这个ObjectInputStreamObjectOutputStream。在你的问题的根本原因是在constructor ObjectInputStream。构造函数将从底层流中读取数据,以尝试获取标头信息,例如有线格式版本。

为了防止您的客户端和服务器无限等待其他人先发送信息,您应该颠倒输入和输出流的顺序,然后明确刷新输出流。以下在客户端和服务器中的流构造将解决您的问题:

out = new ObjectOutputStream(socket.getOutputStream()); 
out.flush(); 
in = new ObjectInputStream(socket.getInputStream()); 
out = new ObjectOutputStream(socket.getOutputStream()); 
out.flush(); 
in = new ObjectInputStream(socket.getInputStream());