多人游戏服务器客户端套接字

时间:2015-11-13 08:57:30

标签: java sockets server client multiplayer

我正在为多人游戏创建简单的客户端服务器通信。服务器应该只向所有其他连接的播放器广播消息。我希望每个玩家都有一个单独的线程,这就是我做到的:

服务器:

public class Server extends Thread {
    private static final Logger LOGGER = Logger.getLogger(Server.class.getName());

    private ServerSocket serverSocket;
    private static final int SERVER_PORT = 6066;

    public Server(int port) {
        try {
            serverSocket = new ServerSocket(port);
        } catch (IOException e) {
            LOGGER.log(Level.SEVERE, "Couldn't start server");
        }
    }

    public void run() {
        while (true) {
            try {
                System.out.println("LISTENING...");
                Socket clientSocket = serverSocket.accept();
                System.out.println("GOT CONNECTION");

                PlayerThread playerThread = new PlayerThread(clientSocket);
                playerThread.start();
            } catch (IOException e) {
                LOGGER.log(Level.SEVERE, "Exception occured on server");
                break;
            }
        }
        try {
            serverSocket.close();
        } catch (IOException e) {
            LOGGER.log(Level.SEVERE, "Server is down.");
        }
    }

    public static void main(String[] args) {
        Thread t = new Server(SERVER_PORT);
        t.start();
    }
}

PlayerThread:

public class PlayerThread extends Thread {
    private static final Logger LOGGER = Logger.getLogger(PlayerThread.class.getName());

    private static List<PlayerThread> players = new ArrayList<PlayerThread>(4);

    private Socket socket;
    private DataInputStream in;
    private DataOutputStream out;

    private String playerName;
    private ObjectMapper objectMapper = new ObjectMapper();

    public PlayerThread(Socket socket) throws IOException {
        try {
            this.socket = socket;
            in = new DataInputStream(socket.getInputStream());
            out = new DataOutputStream(socket.getOutputStream());
        } catch (IOException e) {
            LOGGER.log(Level.INFO, "Couldn't read stream");
        }
    }

    @Override
    public void run() {
        while (true) {
            try {
                String inputMessage = in.readUTF();
                System.out.println("GOT: " + inputMessage);
                JsonNode jsonNode = objectMapper.readTree(inputMessage);
                String senderName = jsonNode.get("senderName").asText();

                if (!players.contains(this)) {
                    playerName = senderName;
                    players.add(this);
                    players.forEach((p) -> System.out.println(p));
                }

                for (PlayerThread p : players) {
                    p.getOut().writeUTF(inputMessage);
                }

            } catch (IOException e) {
                LOGGER.log(Level.INFO, "Player disconnected: " + playerName);
                players.remove(this);
                break;
            }
        }

        try {
            socket.close();
        } catch (IOException e) {
            LOGGER.log(Level.INFO, "Couldn't close stream");
        }
    }

    @Override
    public String toString() {
        return "Player [name=" + playerName + "]";
    }

    public DataInputStream getIn() {
        return in;
    }

    public DataOutputStream getOut() {
        return out;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((playerName == null) ? 0 : playerName.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        PlayerThread other = (PlayerThread) obj;
        if (playerName == null) {
            if (other.playerName != null)
                return false;
        } else if (!playerName.equals(other.playerName))
            return false;
        return true;
    }
}

在客户端,我创建套接字并发送JSON:

    playerSocket = new Socket(SERVER_ADDRESS, SERVER_PORT);
    in = new DataInputStream(playerSocket.getInputStream());
    out = new DataOutputStream(playerSocket.getOutputStream());
    out.writeUTF(JSONConverter.ObjectToJSON(message));

问题是,对于每个连接,都会创建新线程和新套接字。我可以做另一个Player类并将它们保存在List中,但它仍然意味着每个连接都创建它自己的线程。 来自播放器的消息每100ms发送一次,因此在1s后我将有10个线程,这显然是错误的。我该怎么办?

0 个答案:

没有答案