2017-04-13 78 views
0

有人可以解決這個問題。 使用JDK 1.8,我試圖使用套接字在Java中構建一個非常簡單的聊天應用程序。在我的客戶類中,一旦執行以下行, 消息returnMessage =(Message)objectInputStream.readObject(); 它拋出異常。 異常線程「main」 java.io.OptionalDataExceptionobjectInputStream.readObject()拋出異常java.io.OptionalDataException

我只寫類型的消息對象到流和閱讀類型的消息對象,因爲我寫了一次,我不認爲我所做的任何事情錯在依次閱讀。

問:還請讓我知道什麼是調試這種類型的應用程序的最佳方式,如何在運行客戶端時打到服務器中的斷點?

客戶

package com.company; 

import sun.misc.SharedSecrets; 

import java.io.*; 
import java.net.Socket; 
import java.net.UnknownHostException; 

public class Client { 
    public static void main(String[] args) throws UnknownHostException, IOException, ClassNotFoundException{ 

      Socket socket = new Socket("localhost", Server.PORT); 

      ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream()); 
      ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream()); 

      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); 
      String readerInput = bufferedReader.readLine(); 
      String[] readerInputTokens = readerInput.split("\u0020"); 

      if(readerInputTokens.length != 2) { 
       System.out.println("Usage: Client <integer> <integer>"); 
      } else { 
       Integer firstNumber = Integer.decode(readerInputTokens[0]); 
       Integer secondNumber = Integer.decode(readerInputTokens[1]); 

       Message message = new Message(firstNumber, secondNumber); 

       objectOutputStream.writeObject(message); 


       System.out.println("Reading Object .... "); 
       Message returnMessage = (Message) objectInputStream.readObject(); 

       System.out.println(returnMessage.getResult()); 

       socket.close(); 
      } 
    } 

    public static boolean isInteger(String value) { 
     boolean returnValue = true; 
     try{Integer.parseInt(value);} 
     catch (Exception ex){ returnValue = false; } 
     return returnValue; 
    } 
} 

服務器

package com.company; 

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


public class Server { 
    public final static int PORT = 4446; 
    public static void main(String[] args) throws IOException, ClassNotFoundException { 
     new Server().runServer(); 
    } 

    public void runServer() throws IOException, ClassNotFoundException { 

     ServerSocket serverSocket = new ServerSocket(PORT); 
     System.out.println("Server up & ready for connections ..."); 

     // This while loop is necessary to make this server able to continuously in listning mode 
     // So that whenever a client tries to connect, it let it connect. 
     while (true){ 
      Socket socket = serverSocket.accept(); // Server is ready to accept connectiosn;. 

      // Initialize Server Thread. 
      new ServerThread(socket).start(); 
     } 
    } 
} 

Sever的主題

package com.company; 

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

public class ServerThread extends Thread { 
    private Socket socket = null; 
    ServerThread(Socket socket){ 
     this.socket = socket; 
    } 

    public void run() { 

     try { 

      ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream()); 
      objectOutputStream.writeChars("\n"); 
      objectOutputStream.flush(); 

      ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream()); 

      Message message = (Message) objectInputStream.readObject(); 
      multiplyNumbers(message); 
      System.out.println("Writing: "+message.toString()); 
      objectOutputStream.writeObject(message); 
      System.out.println("Message Written"); 
      socket.close(); 

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

     } catch (ClassNotFoundException ex) { 
      ex.printStackTrace(); 
     } 
    } 

    private void multiplyNumbers(Message message) { 
     message.setResult(message.getFirstNumber().intValue() * message.getSecondNumber().intValue()); 
    } 
} 

消息類

package com.company; 

import java.io.Serializable; 

public class Message implements Serializable { 
    private static final long serialVersionUID = -72233630512719664L; 

    Integer firstNumber = null; 
    Integer secondNumber = null; 
    Integer result = null; 

    public Message(Integer firstNumber, Integer secondNumber) { 
     this.firstNumber = firstNumber; 
     this.secondNumber = secondNumber; 
    } 

    public Integer getFirstNumber() { 
     return this.firstNumber; 
    } 

    public Integer getSecondNumber() { 
     return this.secondNumber; 
    } 

    public Integer getResult() { 
     return this.result; 
    } 

    public void setResult(Integer result) { 
     this.result = result; 
    } 

    @Override 
    public String toString() { 
     return "Message{" + 
       "firstNumber=" + firstNumber + 
       ", secondNumber=" + secondNumber + 
       ", result=" + result + 
       '}'; 
    } 
} 
+0

請幫助一些[補充性調試技巧](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)。如果您之後仍然遇到問題,請隨時返回一個[最小,完整且可驗證的示例](http://stackoverflow.com/help/mcve),以說明您的問題。 –

+0

我知道如何在java中進行調試,我可以調試客戶端,但我的服務器斷點沒有打,我認爲有一種不同的技術來調試這些類型的客戶端服務器應用程序。 – ATHER

+0

在這種情況下,我的建議是仔細檢查您是否在調試模式下運行,然後將斷點移動到更有可能被擊中的地方。 –

回答

2
objectOutputStream.writeChars("\n"); 

你爲什麼寫一個換行符到ObjectOutputStream?你永遠不會讀它。不要這樣做。無論遇到什麼情況,都要將其移除

+0

我不得不這樣做,因爲我的輸入流在客戶端被阻塞。我會嘗試刪除它,並會更新你。讓我們看看是否有效。 – ATHER

+0

不,你沒必要這麼做,因爲輸入流在客戶端被阻塞了。 'flush()'是你所需要的。 – EJP

+0

是的,這工作。爲你+1。 – ATHER