从Java中的ObjectInputStream连续读取对象

我在使用ObjectInputStream时遇到了问题,现在我已经苦苦挣扎了2天。 我试图寻找解决方案,但遗憾的是找不到合适的答案。

我正在尝试编写客户端/服务器应用程序,其中客户端将对象(在本例中为配置类)发送到服务器。 这个想法是在发送对象之后连接保持活动,因此可以在必要时发送新对象。

以下是我的客户端代码的重要部分:

mSocket = new Socket("192.168.43.56", 1234); mObjectIn = new ObjectInputStream(mSocket.getInputStream()); mObjectOut = new ObjectOutputStream(mSocket.getOutputStream()); mObjectOut.writeObject(stubConfig); mObjectOut.flush(); 

在上面的代码中,我省略了一些try / catch块以保证代码对您可读。

服务器端看起来如下:

 mHostServer = new ServerSocket(port); mSocket = mHostServer.accept(); // create streams in reverse oreder mObjectOut = new ObjectOutputStream(mConnection.getOutputStream()); mObjectOut.flush(); mObjectIn = new ObjectInputStream(mConnection.getInputStream()); while (mIsSocketConnected) { StubConfig = (StubConfiguration)mObjectIn.readObject(); } 

我想要实现的是,只要socketconnection处于活动状态,服务器就会监听传入的配置对象。

然而,当我运行我的程序时,我在服务器端的while循环中得到了一个EOFException。 我在while循环的第一次迭代中没有任何问题地收到第一个配置对象,但之后每次调用readObject()时都会得到一个EOFException。

我正在寻找解决这个问题的方法。 谁能让我朝着好的方向前进?

编辑:我读到的有关EOFException的内容是,当您希望在到达目标结尾时从流中读取时,它会被抛出。 这意味着由于某种原因,流在对象发送后结束。 有没有办法重新初始化流?

尝试使用这个

服务器端
1.Server在单独的线程上运行

 public class ServeurPresence implements Runnable { public final static int PORT = 20000 ; public final static String HOSTNAME = "localhost" ; public static enum Action {CONNEXION, MSG, DECONNEXION,USER, FINCLASSEMENT}; ServerSocket serveur ; static List names ; */ public ServeurPresence() { System.out.println("Start Server..."); try { serveur = new ServerSocket(PORT) ; new Thread(this).start(); //javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI();} } ); } catch (IOException e) { e.printStackTrace(); } } /** * @param args */ public static void main(String[] args) { new ServeurPresence(); } @Override public void run() { System.out.println("server runs"); while(true) { try { Socket sock = serveur.accept(); ServiceClientsThread thread= new ServiceClientsThread(sock); thread.start(); } catch (IOException e) { System.out.println("Error with socket"); e.printStackTrace(); } } } } 

2.处理每个客户端的线程:ServiceClientThread

  import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import java.util.ArrayList; import java.util.List; public class ServiceClientsThread extends Thread{ private Socket sock ; ServiceClientsThread(Socket sock) { //super(); this.sock=sock; } @Override public void run() { DataInputStream is ; DataOutputStream os ; String name =null ; try { is = new DataInputStream(sock.getInputStream()) ; os = new DataOutputStream(sock.getOutputStream()) ; ServeurPresence.Action act ; do { // read Action act = ServeurPresence.Action.valueOf(is.readUTF()) ; // read string -> enum System.out.println("action :"+act); switch (act) { case CONNEXION : name = is.readUTF(); //read client name System.out.println("Name :"+name); os.writeUTF("Hi");//send welcome msg break ; case MSG : String msg = is.readUTF(); os.writeUTF("OK");//response break ; case DECONNEXION : System.out.println(name+" is logged out"); break ; } } while (act!=ServeurPresence.Action.DECONNEXION) ; // the end is.close(); os.close(); sock.close(); } catch (IOException e) { System.out.println("Error with "+name+" socket"); e.printStackTrace(); } } } 

3.客户方

  import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; public class Client { /** * */ Client(String name) { System.out.println("Start Client..."); try { Socket sock = new Socket(ServeurPresence.HOSTNAME,ServeurPresence.PORT) ; DataOutputStream os = new DataOutputStream(sock.getOutputStream()) ; DataInputStream is = new DataInputStream(sock.getInputStream()) ; System.out.println("Send "+name+" to server"); // CONNECTION : Action then value os.writeUTF(ServeurPresence.Action.CONNEXION.name()) ; // send action : write enum -> String os.writeUTF(name) ; // send the name //read server welcome msg String msg = is.readUTF(); System.out.println("Welcome msg: "+msg); /* Your actions here : see example below */ try { Thread.currentThread().sleep(4000); os.writeUTF(ServeurPresence.Action.MSG.name()) ; // send action : write enum -> String os.writeUTF("My message here") ; // send msg Thread.currentThread().sleep(4000); msg = is.readUTF();//server response message } catch (InterruptedException e) { e.printStackTrace(); } /************************************************/ //CLOSE os.writeUTF(ServeurPresence.Action.DECONNEXION.name()) ; // send action System.out.println("Log out"); os.close(); sock.close(); } catch (UnknownHostException e) { System.out.println(ServeurPresence.HOSTNAME+ " unknown"); e.printStackTrace(); } catch (IOException e) { System.out.println("Impossible to connect to "+ServeurPresence.HOSTNAME+ ":"+ServeurPresence.PORT); e.printStackTrace(); } } } 

4.在你的情况下使用readObject()/ writeObject()而不是readUTF()/ writeUTF()来编写你的配置对象

试试这个,让我知道它是怎么回事:

 while (1==1) { StubConfig = (StubConfiguration)mObjectIn.readObject(); Thread.sleep(100); //Saves CPU usage } 

当对等方关闭连接时, readObject()抛出EOFException 。 之后永远不会有更多数据。 因此,您根本无法编写多个对象:您关闭了连接。

答案很晚,但仅供将来参考。 我一直在通过套接字发送对象时遇到问题,因为方法flush()无法正常工作。

我只是通过将flush()切换到reset()来解决这个问题。