当服务器尝试接收客户端数据时程序停止

问题描述 投票:0回答:1

我正在尝试在 Greenfoot 中为学校项目制作一个简单的多人游戏。

如果我删除“updatePosition();”在播放器脚本中,服务器可以移动,客户端获取数据。但是,当我尝试从客户端获取数据并调用 updatePosition(); 时在播放器脚本中,当服务器尝试调用 receiveInt() 时,它会停止。终端显示“Works Server”,但在脚本后面的几行中不显示“1”或“2”。

“游戏管理器”:

import greenfoot.*;
import java.io.*;
import java.net.*;

import javax.swing.JOptionPane;
import java.util.ArrayList;

public class MyWorld extends World
{
    public Server server;
    public Client client;
    public boolean Server = false;

    /**
     * Constructor for objects of class MyWorld.
     * 
     */
    public MyWorld()
    {    
        super(600, 400, 1);
        Player player = new Player(this);
        addObject(player, getWidth()/2, getHeight()/2);
    }

    public void act()
    {
        if(Greenfoot.isKeyDown("q"))
        {
            if(Server)
            {
                server.close();
            }else
            {
                client.close();
            }
        }
    }

    public void init()
    {
        Object[] options = {"Server","Client"};
        int i = JOptionPane.showOptionDialog(null, "Host as server or join as client?", "Selection", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options, options[0]);
        if(i == 0)
        {
            server = new Server(this);
            Server = true;

            Player2 player2 = new Player2();
            addObject(player2, 0, 0);
        }else if(i == 1)
        {
            client = new Client(this);
            
            Player2 player2 = new Player2();
            addObject(player2, 0, 0);
        }
    }

    public class Server
    {
        MyWorld myWorld;
        public ServerSocket serverSocket;
        public Socket skt;
        private ObjectInputStream inServer;
        private ObjectOutputStream outServer;
        public Server(MyWorld myWorl)
        {
            this.myWorld = myWorl;
            try
            {
                serverSocket = new ServerSocket(8888);
                skt = serverSocket.accept();
                inServer = new ObjectInputStream(skt.getInputStream());
                outServer = new ObjectOutputStream(skt.getOutputStream());
            }catch(IOException e)
            {
                close();
            }
        }

        public void sendInts(int ...arr) {
            try {
                outServer.writeObject(arr);
                Greenfoot.delay(1);
                outServer.flush();
            }
            catch(NullPointerException ex) {
            }
            catch(IOException ex) {
            }
        }

        public int[] receiveInts() {
            int[] datServer = null;
            try {
                datServer = (int[])inServer.readObject();
            }
            catch(ClassNotFoundException ex) {
                ex.printStackTrace();
                close();
            }
            catch(NullPointerException ex) {
                close();
            }
            catch(IOException ex) {
                close();
            }
            return datServer;
        }

        public void close()
        {
            try {
                outServer.close();
                inServer.close();
                skt.close();
                serverSocket.close();
            }
            catch(IOException ex) {
                throw new RuntimeException("Error closing streams...");
            }
        }
    }

    public class Client
    {
        MyWorld myWorld;
        private ObjectOutputStream outClient;
        private ObjectInputStream inClient;
        public Socket clientSocket;
        public Client(MyWorld myWorl)
        {
            this.myWorld = myWorl;
            try
            {
                clientSocket = new Socket("localhost",8888);
                outClient = new ObjectOutputStream(clientSocket.getOutputStream());
                inClient = new ObjectInputStream(clientSocket.getInputStream());
            }catch(IOException e)
            {
                close();
            }   
        }

        public void sendInts(int ...arr) {
            try {
                outClient.writeObject(arr);
                Greenfoot.delay(1);
                outClient.flush();
            }
            catch(NullPointerException ex) {
            }
            catch(IOException ex) {
            }
        }

        public int[] receiveInts() {
            int[] datClient = null;
            try {
                datClient = (int[])inClient.readObject();
            }
            catch(ClassNotFoundException ex) {
                ex.printStackTrace();
            }
            catch(NullPointerException ex) {
            }
            catch(IOException ex) {
                close();
            }
            return datClient;
        }

        public void close()
        {
            try {
                outClient.close();
                inClient.close();
                clientSocket.close();
            }
            catch(IOException ex) {
                throw new RuntimeException("Error closing streams...");
            }
        }
    }
}

玩家:

import greenfoot.*;

public class Player extends Actor
{
    private MyWorld myWorld;
    private Player2 player2;

    public Player(MyWorld myWorl)
    {
        myWorld = myWorl;
    }

    private boolean startSelectionBool = false;

    public void act() 
    {
        if(!startSelectionBool)
        {
            if(Greenfoot.getMouseInfo() != null)
            {
                if(Greenfoot.mouseClicked(this))
                {
                    myWorld.init();
                    startSelectionBool = true;
                }
            }
        }
        else
        {
            if(myWorld.Server == true)
            {
                updateServer();
                //System.out.println("Server");
            }else
            {
                updateClient();
                //System.out.println("Client");
            }
        }
    }   

    public void updateServer()
    {
        if(Greenfoot.isKeyDown("w"))
        {
            setLocation(this.getX(), this.getY()-1);
        }
        if(Greenfoot.isKeyDown("s"))
        {
            setLocation(this.getX(), this.getY()+1);
        }
        if(Greenfoot.isKeyDown("a"))
        {
            setLocation(this.getX()-1, this.getY());
        }
        if(Greenfoot.isKeyDown("d"))
        {
            setLocation(this.getX()+1, this.getY());
        }
        myWorld.server.sendInts(this.getX(), this.getY());

        updatePosition();
    }

    public void updatePosition()
    {
        if (myWorld.server.receiveInts() != null)
        {
            System.out.println("Works Server");
            int[] w1 = myWorld.server.receiveInts();
            //System.out.println("1");
            player2 = getWorld().getObjects(Player2.class).get(0);
            player2.setLocation(w1[0], w1[1]);
            //System.out.println("2");
        }
        else
        {
            System.out.println("1");
        }
    }

    public void updateClient()
    {
        if(Greenfoot.isKeyDown("w"))
        {
            setLocation(this.getX(), this.getY()-1);
        }
        if(Greenfoot.isKeyDown("s"))
        {
            setLocation(this.getX(), this.getY()+1);
        }
        if(Greenfoot.isKeyDown("a"))
        {
            setLocation(this.getX()-1, this.getY());
        }
        if(Greenfoot.isKeyDown("d"))
        {
            setLocation(this.getX()+1, this.getY());
        }
        myWorld.client.sendInts(this.getX(), this.getY());

        if (myWorld.client.receiveInts() == null)
        {
            System.out.println("Return Client");
            return;
        }
        else
        {
            player2 = getWorld().getObjects(Player2.class).get(0);
            
            int[] w2 = myWorld.client.receiveInts();

            System.out.println("Position: " + w2[0] + " - " + w2[1]);
            player2.setLocation(w2[0], w2[1]);
        }
    }
}
java sockets client-server serversocket greenfoot
1个回答
0
投票

看起来奇怪的一件事是,在

updatePosition()
中,您调用
receiveInts()
两次,因此第一个将从套接字读取然后丢弃它,第二个将不得不等待下一个相应的
sendInts()
调用。我怀疑您希望在
w1
中的 if 语句之前对
updatePosition()
进行赋值,然后检查
w1
是否为空。

© www.soinside.com 2019 - 2024. All rights reserved.