从 Java 中的 ObjectInputStream 连续读取对象 [英] Continuously read objects from an ObjectInputStream in Java
问题描述
我在使用 ObjectInputStream 时遇到问题,我已经为此苦苦挣扎了 2 天.我试图寻找解决方案,但不幸的是没有找到合适的答案.
I have a problem using an ObjectInputStream and I have been struggling with it for 2 days now. I tried to search for a solution but unfortunately found no fitting answer.
我正在尝试编写一个客户端/服务器应用程序,其中客户端将对象(在本例中为配置类)发送到服务器.这个想法是连接在发送对象后保持活动状态,因此可以在必要时发送新对象.
I am trying to write a client/server application in which the client sends objects (in this case a configuration class) to the server. The idea is that connection keeps alive after sending the object so it is possible to send a new object if necessary.
以下是我的客户端代码的重要部分:
Here are the important parts of my client code:
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 块以保持代码对您可读.
In the above code, I left out some try/catch blocks to keep the code readable for you.
服务端如下:
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 处于活动状态,服务器就会监听传入的配置对象.
What I want to achieve is that as long at the socketconnection is alive, the server is listening for incoming config objects.
然而,当我运行我的程序时,我在服务器端的 while 循环中得到了一个 EOFException.我在 while 循环的第一次迭代中没有任何问题地收到第一个配置对象,但之后每次调用 readObject() 时我都会收到 EOFException.
When I run my program however, I got an EOFException in the while loop at server side. I receive the first config object without any problems in the first iteration of the while loop but after that I get an EOFException every time readObject() is called.
我正在寻找解决此问题的方法.任何人都可以让我朝着好的方向发展吗?
I am looking for a way to solve this. Can anyone put me in the good direction?
我读到的关于 EOFException 的内容是,当您想在到达流末尾时从流中读取它时会抛出它.这意味着由于某种原因,流在对象发送后结束.有没有办法重新初始化流?
What I read about the EOFException is that it is thrown when you want to read from a stream when the end of it is reached. That means that for some reason the stream ended after the object has been send. Is there a way to reinitialize the streams or so??
推荐答案
尝试使用这个
try using this
服务端
1.服务器运行在一个单独的线程上
Server side
1.Server running on a separate thread
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<String> 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.一个线程来处理每个Client:ServiceClientThread
2. A Thread to handle each Client: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. 客户端
3. Client side
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() 来编写您的配置对象
4. In your case use readObject()/writeObject() instead of readUTF()/writeUTF() to write your config objects
这篇关于从 Java 中的 ObjectInputStream 连续读取对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!