2014-01-17 62 views
0

我試圖創建一個簡單的Socket客戶端 - 服務器對其中一個會發送消息,但在我跑的方法之一,我這樣做:String servermessage = new String(dis.readUTF());,它返回一個java.io.EOFException我是什麼做錯了,是否有更好的方式發送消息在客戶端和服務器之間?爪哇 - DataInputStream類的readUTF返回一個EOFException類

編輯:我現在知道,當輸入流到達所有字節前的末尾時發生EOFException,但我不明白他們是什麼意思,有人可以澄清嗎?

服務器:

public class Server { 
    String host = "localhost"; 
    int port = 2484; 
    static boolean launched = false; 

    ServerSocket server; 
    static DataOutputStream dos; 

    public static void main(String args[]) throws IOException { 
     final Server serv = new Server(); 

     final Thread socketThread = new Thread(new Runnable() { 
      ServerSocket server; 

      @Override 
      public void run() { 
       try { 
        Server serv = new Server(); 
        ServerSocket server = new ServerSocket(serv.port); 
        System.out.println("Server: Launched!"); 

        Socket client = server.accept(); 
        OutputStream clientOut = client.getOutputStream(); 
        DataOutputStream dos = new DataOutputStream(clientOut); 

        dos.close(); 
        clientOut.close(); 
        server.close(); 
        client.close(); 

       } catch (IOException e) { 
        e.printStackTrace(); 

       } 
      } 
     }); 

     Thread input = new Thread(new Runnable() { //Thread that reads from an input from the console 
      Server serv = new Server(); 

      @Override 
      public void run() { 
       Scanner scanner = new Scanner(System.in); 
       System.out.println("Type Something!"); 

       while (true) { 
        String input = scanner.next(); 

        if (input.equalsIgnoreCase("Start")) { 
         if(!launched) { //Checks if the ServerSocket server is already launched, and if not, launches it 
          System.out.println("Launching the socket!"); 
          socketThread.start(); 
          input = scanner.next(); 

          launched = true; 
         } else if(launched){ 
          System.err.println("ServerSocket is already Launched!"); 

         } 
        } else if (input.equalsIgnoreCase("Send")) { 
         System.out.println("What would you like to send?"); 
         input = null; 
         input = scanner.next(); 
         System.out.println("Server: " + input); 

         try { 
          dos.writeUTF(input); //Sends the input to the client 

         } catch (IOException e) { 
          System.err.println("Unable to send the message"); 
          e.printStackTrace(); 

         } 
        } else { 
         System.err.println("Unknown Input!"); 
         input = null; 
        } 
       } 
      } 
     }); 

     input.start(); 
    } 
} 

SocketManager:

package Socket_Swing_Test_2; 

public class SocketManager implements Runnable { 
    ClientMain c = new ClientMain(); 
    ClientSwing cs = new ClientSwing(); 

    Socket client; 
    PrintWriter output; 
    BufferedReader input; 
    InputStream clientIn; 
    DataInputStream dis; 



    String host = "localhost"; 
    int port = 2484; 

    JTextArea textArea = cs.textArea; 

    public SocketManager(ClientMain c) { 
     this.c = c; 

     try { 
      client = new Socket(host, port); 
      System.out.println("SocketManager: Connected to the server!"); 

      clientIn = client.getInputStream(); 
      dis = new DataInputStream(clientIn); 

     } catch (Exception e) { 
      System.err.println("Client: Socket failed to Connect"); 
      e.printStackTrace(); 

     } 
    } 

    public synchronized void send(String message) { 
     try { 
      output.println(message); 
      output.flush(); 

     } catch (Exception e) { 
      e.printStackTrace(); 

     } 
    } 

    public synchronized void connect() { 
     try { 
      client = new Socket(host, port); 
     } catch (Exception e) { 
      System.err.println("Client: Socket failed to Connect"); 
      e.printStackTrace(); 
     } 
    } 

    public synchronized void close() { 
     try { 
      client.close(); 

     } catch (Exception e) { 
      System.err.println("Unable to close the socket!"); 
      e.printStackTrace(); 
     } 

     clientIn = null; 
     dis = null; 
     System.gc(); // Garbage Collector, recycles unused objects that are taking up RAM 

    } 

    public synchronized boolean checkConnection() { 
     return client.isConnected(); 

    } 

    public synchronized void listenStream() { //Unused, keeping for reference 
     try { 
      while (input.ready()) { 
       System.out.println(input.readLine()); 

      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    } 

    public synchronized Socket getSocket() { 
     return client; 

    } 

    public void receive() { 

    } 

    @Override 
    public void run() { 
     System.out.println("SocketManager.run: Is running!"); 

     try { 
      //Read for a message from the server 

      System.out.println("SocketManager.run: Checking for messages from the server"); 
      String servermessage = new String(dis.readUTF()); 
      textArea.append(servermessage); 

     } catch (Exception e) { 
      e.printStackTrace(); 

     } finally { 

      try { 
       client.close(); 
       close(); 

      } catch (Exception e) { 
       e.printStackTrace(); 

      } 
     } 
    } 
} 

可能不需要爲你們,但萬一

ClientSwing只是提供:

public class ClientSwing extends JFrame { 
    JPanel panel; 
    JTextArea textArea; 
    JTextField textField; 

    int WIDTH = 640; 
    int HEIGHT = 480; 

    public ClientSwing() { 
     super("Client"); 

     panel = new JPanel(); 
     panel.setLayout(null); 

     textArea = new JTextArea(); 
     textArea.setEditable(false); 
     textArea.setBounds(0, 0, WIDTH, HEIGHT - 15); 
     textArea.setFont(new Font("Impact", Font.PLAIN, 13 + 1/2)); 

     textField = new JTextField(); 
     textField.setLocation(0, HEIGHT - 47); 
     textField.setSize(WIDTH, 20); 
     textField.addActionListener(new ActionListener() { //I AM RIGHT HERE 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       String input = textField.getText(); 

       if(input.equalsIgnoreCase("Launch")) { 
        SwingWorker socketLaunch = new SwingWorker() { 

         @Override 
         protected Object doInBackground() throws Exception { 
          ClientMain main = new ClientMain(); 
          main.run(); 
          return null; 
         } 
        }; 

        socketLaunch.execute(); 
       } 
      } 
     }); 

     panel.add(textArea); 
     panel.add(textField); 

     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     setSize(WIDTH, HEIGHT); 
     setLocationRelativeTo(null); 
     setResizable(false); 

     add(textField); 
     add(textArea); 
    } 
} 

ClientMain:

public class ClientMain extends JFrame { 
    private SocketManager network; 
    int a = 1; 

    public static void main(String args[]) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       ClientSwing window = new ClientSwing(); 
       window.setVisible(true); 
      } 
     }); 
    } 

    public void run() { 
     network = new SocketManager(new ClientMain()); 

     Thread thread = new Thread(network); 
     thread.run(); 
    } 

    public SocketManager getSocketM() { 
     return network; 
    } 
} 

跟蹤:

java.io.EOFException 
    at java.io.DataInputStream.readUnsignedShort(Unknown Source) 
    at java.io.DataInputStream.readUTF(Unknown Source) 
    at java.io.DataInputStream.readUTF(Unknown Source) 
    at Socket_Swing_Test_2.SocketManager.run(SocketManager.java:114) 
    at java.lang.Thread.run(Unknown Source) 
    at Socket_Swing_Test_2.ClientMain.run(ClientMain.java:26) 
    at Socket_Swing_Test_2.ClientSwing$1$1.doInBackground(ClientSwing.java:46) 
    at javax.swing.SwingWorker$1.call(Unknown Source) 
    at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) 
    at java.util.concurrent.FutureTask.run(Unknown Source) 
    at javax.swing.SwingWorker.run(Unknown Source) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
    at java.lang.Thread.run(Unknown Source) 
+0

你正在閱讀一個字符串,但你不寫一個字符串。你沒有寫任何東西。你只要接受它就關閉套接字。你還可能期望發生什麼? – EJP

+0

在我的服務器類中,它檢查輸入以向客戶端發送UTF消息,我想知道如何做一個while循環來檢查UTF消息(在SocketManager中,我在哪裏執行'dis.readUTF()' ,但我想不出一個返回布爾值的方法,如(假設):while(dis.isOpen())'或類似的東西。我想,因爲我把'socket.close() '方法在最後,它只在關閉JFrame時運行,我對使用'finally'很新,我沒有用太多,所以我不確定它是如何工作的。 – N1ghtk1n9

+0

@EJP對不起,我忘了標記你的名字,所以你沒有得到我認爲的通知 – N1ghtk1n9

回答

1

從教程Data Streams

注意DataStreams通過捕捉EOFException檢測結束文件的條件,無效的回報,而不是測試值。

數據流爲基本數據值提供二進制I/O;沒有辦法讀取已被選擇來代表結束的價值。