2014-12-06 38 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

相关问题