ObjectInputStream 停止循环
Posted
技术标签:
【中文标题】ObjectInputStream 停止循环【英文标题】:ObjectInputStream stops loop 【发布时间】:2017-04-18 01:27:08 【问题描述】:所以我正在创建一个服务器和客户端程序,
服务器类:
package Networking;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Scanner;
public class Server
private static ArrayList<Socket> sockets = new ArrayList<Socket>();
private static ArrayList<ObjectOutputStream>os = new ArrayList<ObjectOutputStream>();
private static ArrayList<ObjectInputStream> is = new ArrayList<ObjectInputStream>();
private static ArrayList<Player> players = new ArrayList<Player>();
public static void main(String args[]) throws IOException, ClassNotFoundException
ServerSocket listener = new ServerSocket(7321);
System.out.println("Server Started");
int fps = 60;
double timePerTick = 1000000000 / fps;
double delta = 0.0D;
long lastTime = System.nanoTime();
long timer = 0L;
int ticks = 0;
while (true)
long now = System.nanoTime();
delta += (now - lastTime) / timePerTick;
timer += now - lastTime;
lastTime = now;
if (delta >= 1.0D)
Socket socket = listener.accept();
if(socket != null)
sockets.add(socket);
os.add(new ObjectOutputStream(sockets.get(sockets.size()-1).getOutputStream()));
is.add(new ObjectInputStream(sockets.get(sockets.size()-1).getInputStream()));
players.add((Player)is.get(sockets.size()-1).readObject());
ticks++;
delta -= 1.0D;
for(int i = 0 ;i < sockets.size();i++)
os.get(i).writeObject(players);
os.get(i).flush();
if (timer >= 1000000000L)
ticks = 0;
timer = 0L;
for(int i =0; i < sockets.size();i++)
客户端类
package Networking;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import com.sun.prism.paint.Stop;
import Dynamics.Display;
public class Client implements Runnable
private final String serverAddress = "localhost";
private static int PORT = 7321;
private Socket socket;
private ObjectInputStream in;
private ObjectOutputStream out;
private boolean connected = false;
private static Player player = null;
private boolean isrunning = false;
private ArrayList<Player> enemy;
private Thread thread;
private Display display;
public static void main(String args[]) throws ClassNotFoundException
Client c = new Client();
c.connect();
c.start();
public Client()
player = new Player();
display = new Display("Game: " + player.getName());
public void connect() throws ClassNotFoundException
try
socket = new Socket(serverAddress, PORT);
connected = true;
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
out.writeObject(player);
catch(UnknownHostException e)e.printStackTrace();
catch (IOException e)e.printStackTrace();
private synchronized void start()
if(isrunning)
return;
isrunning = true;
this.thread = new Thread(this);
this.thread.start();
this.display.getFrame().setVisible(true);
public void run()
int fps = 60;
double timePerTick = 1000000000 / fps;
double delta = 0.0D;
long lastTime = System.nanoTime();
long timer = 0L;
int ticks = 0;
while (isrunning)
long now = System.nanoTime();
delta += (now - lastTime) / timePerTick;
timer += now - lastTime;
lastTime = now;
if (delta >= 1.0D)
tick();
render();
ticks++;
delta -= 1.0D;
if (timer >= 1000000000L)
ticks = 0;
timer = 0L;
public void tick()
public void render()
CheckEnemys();
@SuppressWarnings("unchecked")
public void CheckEnemys()
try
enemy = (ArrayList<Player>)in.readObject();
catch (ClassNotFoundException | IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println(enemy.size());
当我运行循环以不断检查新玩家并且循环在一次迭代后停止时,我的问题就出现了。播放器类可使用默认构造函数和名称进行序列化。 Idk y 循环停止了
【问题讨论】:
【参考方案1】:当您打开ObjectInputStream
时,它将阻塞,直到另一方刷新其ObjectOutputStream
并写入标题。确保首先打开输出流并立即刷新它。
out = new ObjectOutputStream(socket.getOutputStream());
out.flush();
in = new ObjectInputStream(socket.getInputStream());
您的CheckEnemys
方法也将阻塞,直到它从服务器接收到对象,这仅在客户端加入时发生。您应该在单独的线程中运行该方法,并通过同步队列将事件从它提供给您的主线程。
顺便说一句,您应该在滴答声之间Thread.sleep()
,而不是不断循环检查时钟。
你也应该在你写完消息后reset()
你的ObjectOutputStream
,否则它会保存对所有已写内容的引用,从而防止垃圾收集。
【讨论】:
【参考方案2】:您不应在接受循环中执行任何 I/O,包括创建 ObjectinputStreams
或 ObjectOutputStreams
。所有这些都应该在单独线程的run()
方法中。
【讨论】:
以上是关于ObjectInputStream 停止循环的主要内容,如果未能解决你的问题,请参考以下文章
如何根据循环内的特定条件使用 Array.map 迭代停止索引计数增量?
如何在 Java 中检查 ObjectInputStream 是不是为空?