首页 文章

Java服务器 - 客户端游戏

提问于
浏览
1

好的,我是网络编程的新手,我正在尝试解决这个问题:

我有最多7名玩家的基于GUI的Java SE游戏,我希望它通过互联网支持多人游戏 .

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

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

所以我的下一个想法是在远程托管服务器上使用一些公共IP . 所以会有一些服务器全天候运行(或者如果我从游戏中以编程方式告诉他),我使用它的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);
            }
        }

1 回答

  • 1

    如果在“本地网络”上运行,那么拥有serversocket就可以,但是我们处理NAT和互联网,这意味着98%的机器不能直接在互联网上看到 . (即,打开用于在计算机上侦听的TCP端口不会导致收听该端口的计算机的Internet IP地址 . )

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

    目前解决这个问题的方法是让服务器保持“游戏状态”(例如玩家位置, Health ,武器伤害等)

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

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

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

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

    以下链接应该为您提供一个良好的起点 .

    A good start

    And the enclosing page with a little bit more detail

相关问题