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,包括创建 ObjectinputStreamsObjectOutputStreams。所有这些都应该在单独线程的run() 方法中。

【讨论】:

以上是关于ObjectInputStream 停止循环的主要内容,如果未能解决你的问题,请参考以下文章

如何根据循环内的特定条件使用 Array.map 迭代停止索引计数增量?

如何在 Java 中检查 ObjectInputStream 是不是为空?

如果满足条件,则 Obj-C 停止程序

计时器在想要时不停止,在不想时停止 Obj-C

make: *** 没有规则来制作目标 'obj/logging.o','liso_server' 需要。停止

myeclipse如何停止当前的tomcat服务?