【问题标题】:Java server-client gameJava服务器-客户端游戏
【发布时间】:2015-03-24 04:11:59
【问题描述】:

好的,我对网络编程很陌生,我正在尝试解决这个问题:

我有一个基于 GUI 的 Java SE 游戏,最多可容纳 7 名玩家,我希望它支持 Internet 上的多人游戏。

每个游戏实例都有自己的客户端发送和接收字符串。

我无法充分解决的问题来了。我需要服务器,它的唯一功能是保持客户端的套接字打开,并在接收到一些字符串时将其转发给其他客户端。我的第一个想法是在第一个玩家的机器上运行服务器,其他玩家可以通过其 IP 从外部连接到该服务器。现在我发现获取公共接口 IP 并不像我想象的那么容易,所以我搜索并找到下面编写的代码来获取一些应该从外部可用的 IP。当我在 localhost 尝试此操作时,结果 IP 始终是某个 IPv6 + 端口,并且使用此凭据从客户端连接成功并且可以正常工作。当我在另一台计算机上启动服务器并复制这些凭据以从另一台计算机连接时它失败(它要么不连接,要么如果它连接并且客户端发送消息,服务器没有收到任何消息)。

所以我的下一个想法是在远程托管服务器上使用一些公共 IP。所以会有一些服务器 24/7 运行(或者如果我从游戏中以编程方式告诉他),我使用它的 IP 来联合所有客户端。我只是不知道如何使这个东西工作以及使用什么技术。

我希望我清楚地解释了我的问题,并感谢任何想法甚至解决方案:)

获取机器的公共接口 IP(服务器运行的地方)并打印出代码:

    Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
        while (interfaces.hasMoreElements()) {
            NetworkInterface iface = interfaces.nextElement();
            if (iface.isLoopback() || !iface.isUp()) { //127.xxx loopback
                continue;
            }
            Enumeration<InetAddress> addresses = iface.getInetAddresses();
            while (addresses.hasMoreElements()) {
                InetAddress addr = addresses.nextElement();
                String tmp = addr.getHostAddress();
                if (tmp.startsWith("192.168.")       //local IP
                        || tmp.startsWith("10.")     //local IP
                        || tmp.startsWith("172.16.") //local IP
                        || tmp.startsWith("172.31.") //local IP
                        || tmp.startsWith("169.254") //single network IP
                        || tmp.equals("255.255.255.255")) { //broadcast address
                    continue;
                }
                //cut "%net9","%wlan" etc stuff off
                IP = tmp.substring(0, Math.max(0, tmp.indexOf('%')));
                port=server.getPort();
                System.out.println(IP + " " + port);
            }
        }

【问题讨论】:

    标签: java sockets client server


    【解决方案1】:

    如果在“本地网络”上运行,那么有一个 serversocket 就可以了,但是我们处理 NAT 和互联网,这意味着 98% 的机器不能直接在互联网上可见。 (即在机器上打开 TCP 端口进行监听不会导致机器 Internet IP 地址具有该端口被监听。)

    最初的选择是在公共主机上安装一个服务器,用于调解玩家之间的通信,每台玩家机器负责维护“游戏状态”,但随后会遇到同步问题。 (例如,一台玩家机器认为在该机器接收到告诉它对手已经移动的命令之前,他们已经击中并杀死了另一名玩家。)

    目前考虑这个特殊问题的方法是让服务器保持“游戏状态”(例如玩家位置、健康、武器伤害等)

    让玩家向服务器发送“命令”(例如移动、开火、跳跃。),然后让服务器向所有玩家报告“次要”游戏状态变化。 (所以时间成为一个重要因素,客户端和服务器之间的所有消息都需要时间戳。)

    让您的客户保持他们认为的“游戏状态”,从服务器接收更新以“纠正”错误。

    除此之外,服务器应每隔一段时间将整个“游戏状态”的转储作为“同步”消息发送给每个玩家,以确保他们认为的游戏状态“是”实际游戏状态。

    如果您选择的语言是“C”,那么获取整个游戏状态结构的 md5 校验和然后定期将其传输给玩家并且只执行同步消息将是微不足道的。..

    下面的链接应该会给你一个很好的起点。

    A good start

    And the enclosing page with a little bit more detail

    【讨论】:

    • 谢谢...关于同步 - 这个游戏是回合制游戏,所以这并不重要,因为每个人都在等待服务器向他们发送“许可”玩...我想我知道关于基础知识的一些事情,但我仍然不知道服务器使用什么技术......也许是PHP? JPS?我不知道:))
    • 仍然会存在游戏状态管理问题,因为(我假设)玩家一次只能获得一个回合并且可能以特定顺序进行。最简单的解决方案是 php,其中游戏中的玩家使用 ID 号注册并轮询服务器以了解状态变化。当轮到他们时,服务器会告诉他们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多