【问题标题】:ObjectInputStream stops loopObjectInputStream 停止循环
【发布时间】: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 循环停止了

【问题讨论】:

    标签: java udp serializable objectinputstream


    【解决方案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() 方法中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-11
        • 1970-01-01
        • 2019-07-29
        相关资源
        最近更新 更多