2014-12-06 24 views
0

這是我在Stack Overflow的第一篇文章,所以我希望我以最低限度的正派來做。Java客戶端服務器套接字,重用客戶端套接字拋出「java.io.StreamCorruptedException:無效的類型代碼:AC」

我試圖用Java套接字實現一個簡單的解決方案,但我有一個例外。我肯定濫用API,但我無法弄清楚爲什麼和在哪裏。

客戶端需要發送幾個二進制消息到服務器,它(客戶端)必須重用相同的套接字。 (1)接受客戶端請求,(2)實例化新線程(運行ClientWorker實例)以處理客戶端請求。

如果我只是從客戶端發送一條消息,一切工作正常。然而,當我嘗試第二個消息中發送多條消息,我有以下異常:

java.io.StreamCorruptedException:無效類型代碼:AC在 java.io.ObjectInputStream.readObject0(來源不明)在 java.io.ObjectInputStream.readObject(未知來源)在 simple.socketexample.ClientWorker.run(ClientWorker.java:26)在 java.lang.Thread.run(未知來源)

的異常發生在我的ClienWorker類中,在「Message message =(Message)in.readObject();」請注意,第一條消息總是被服務器成功接收。

以下類是我創建的一個簡單示例的一部分,只是爲了顯示此錯誤。

第一類是消息:

package simple.socketexample; 

import java.io.Serializable; 

public class Message implements Serializable { 
    private static final long serialVersionUID = 4473470814745876900L; 
    private String text; 
    private int number; 

    public Message(String text, int number) { 
     super(); 
     this.text = text; 
     this.number = number; 
    } 

    public String getText() { 
     return text; 
    } 

    public void setText(String text) { 
     this.text = text; 
    } 

    public int getNumber() { 
     return number; 
    } 

    public void setNumber(int number) { 
     this.number = number; 
    } 

    @Override 
    public String toString() { 
     return "Message [text=" + text + ", number=" + number + "]"; 
    } 
} 

這是我的客戶:

public class Client { 
    private final int SERVER_PORT = 3456; 
    private final String SERVER_HOST = "localhost"; 
    private Socket serverSocket; 

    public void connect() throws IOException, UnknownHostException { 
     serverSocket = new Socket(SERVER_HOST, SERVER_PORT); 
    } 

    public void disconnect() throws IOException { 
     serverSocket.close(); 
    } 

    public void sendMessage(Message message) throws IOException { 
     ObjectOutputStream out = new ObjectOutputStream(serverSocket.getOutputStream()); 
     out.writeObject(message); 
     out.flush(); 
     out.reset(); 
    } 
} 

服務器:

public class Server { 
    private final int SERVER_PORT = 3456; 

    public void start() throws IOException { 
     Thread acceptConnectionsThread = new Thread(new Runnable() { 
      public void run() { 
       // Instantiates the socket 
       ServerSocket serverSocket = null; 
       try { 
        serverSocket = new ServerSocket(SERVER_PORT); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 

       // Starts accepting client connections 
       while(true) { 
        Socket socketFromClient = null; 
        try { 
         socketFromClient = serverSocket.accept(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 

        // Create a new "client dedicated thread" 
        ClientWorker clientWorker = new ClientWorker(socketFromClient); 
        Thread clientDedicatedThread = new Thread(clientWorker); 
        clientDedicatedThread.start(); 
       } 
      } 
     }); 

     acceptConnectionsThread.start(); 

    } 
} 

我ClientWorker:

public class ClientWorker implements Runnable { 
    private Socket socketFromClient; 

    public ClientWorker(Socket socketFromClient) { 
     super(); 
     this.socketFromClient = socketFromClient; 
    } 

    public void run() { 
     ObjectInputStream in = null; 
     try { 
      in = new ObjectInputStream(socketFromClient.getInputStream()); 
     } catch (IOException e) { 
      e.printStackTrace(); 
      return; 
     } 

     while(true) { 
      try { 
       Message message = (Message)in.readObject(); 
       System.out.println(message); 
      } catch (ClassNotFoundException e) { 
       e.printStackTrace(); 
       break; 
      } catch (IOException e) { 
       e.printStackTrace(); 
       break; 
      } 
     } 
    } 
} 

和我用來測試這個的類: package simple.socketexample;

import java.io.IOException; 

/** 
* Hello world! 
* 
*/ 
public class App { 
    public static void main(String[] args) throws Exception { 
     // Start the server in a new (background) thread 
     Thread serverInBackground = new Thread(new Runnable() { 
      public void run() { 
       Server server = new Server(); 
       try { 
        server.start(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
     serverInBackground.start(); 

     // Client and connect a client 
     Client client = new Client(); 
     client.connect(); 

     // Sending one message to the server 
     client.sendMessage(new Message("MessageOne", 1)); 

     // Sending another message to the server 
     client.sendMessage(new Message("MessageTwo", 2)); 

     // Closing the client 
     client.disconnect(); 
    } 
} 

的問題可能會在一個小細節和解決方案可能是也可能是正確的鼻子前面,但不知何故,我無法看到它。有沒有人遇到類似的問題?你是如何解決它的?

非常感謝和親切的問候。

回答

2

試試這個ClientWorker

public class ClientWorker implements Runnable { 
    private Socket socketFromClient; 

    public ClientWorker(Socket socketFromClient) { 
     super(); 
     this.socketFromClient = socketFromClient; 
    } 

    public void run() { 

     while(true) { 
      ObjectInputStream in = null; 
      try { 
       in = new ObjectInputStream(socketFromClient.getInputStream()); 
      } catch (IOException e) { 
       e.printStackTrace(); 
       return; 
      } 
      try { 
        Message message = (Message)in.readObject(); 
        System.out.println(message); 

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

和客戶

public void sendMessage(Message message) throws IOException { 
     ObjectOutputStream out = new ObjectOutputStream(serverSocket.getOutputStream()); 
     out.writeObject(message); 
     out.flush(); 
//  out.reset(); 
    } 
+0

哇評論復位(),這是它!我嘗試過一個類似版本的ClientWorker,但我從來沒有評論過「out.reset()」。非常感謝你! – FireWalkWithMe 2014-12-06 15:23:58

相關問題