Java网络游戏:如何列出可用的服务器?
我正在开发一款使用局域网的游戏。像大多数多人游戏一样,有一个服务器-客户端系统。计算机A运行程序实例,创建服务器并等待;计算机B也做同样的事情。现在计算机C运行这个程序,我想要的是他可以看到计算机A和B列在那里作为游戏服务器。我该怎么做?Java网络游戏:如何列出可用的服务器?,java,sockets,networking,serversocket,Java,Sockets,Networking,Serversocket,我正在开发一款使用局域网的游戏。像大多数多人游戏一样,有一个服务器-客户端系统。计算机A运行程序实例,创建服务器并等待;计算机B也做同样的事情。现在计算机C运行这个程序,我想要的是他可以看到计算机A和B列在那里作为游戏服务器。我该怎么做? 为了列出所有可用的服务器,一个简单的解决方案可能是:我需要检查特定范围内的所有IP地址,看看它们是否通过我的特定端口响应。如果是,则游戏实例正在其上运行,并应列在服务器列表中。 上述解决方案是好的吗? 我已经搜索并获得了这段代码: public void ch
为了列出所有可用的服务器,一个简单的解决方案可能是:我需要检查特定范围内的所有IP地址,看看它们是否通过我的特定端口响应。如果是,则游戏实例正在其上运行,并应列在服务器列表中。
上述解决方案是好的吗? 我已经搜索并获得了这段代码:
public void checkHosts(String subnet){
int timeout=1000;
for (int i=1;i<254;i++){
String host=subnet + "." + i;
if (InetAddress.getByName(host).isReachable(timeout)){
System.out.println(host + " is reachable");
}
}
}
public void checkHosts(字符串子网){
int超时=1000;
对于(int i=1;i您可以使用udp;如果服务器启动,则发送广播,并让所有节点侦听udp数据包
根据要求,这里有一些关于utp的示例代码;这些是两个类,一个是heart(wich beats),另一个是listener
public class Heart extends Observable implements Runnable {
private String groupName = "229.5.38.17";
private int port = 4567;
MulticastSocket multicastSocket;
DatagramPacket datagramPacket;
public Heart(int connectionListenerPort, Observer...observers) {
for(Observer observer : observers) {
this.addObserver(observer);
}
try {
multicastSocket = new MulticastSocket();
InetAddress group = InetAddress.getByName(groupName);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(new Beat(connectionListenerPort));
objectOutputStream.flush();
objectOutputStream.close();
byte[] buf = byteArrayOutputStream.toByteArray();
datagramPacket = new DatagramPacket(buf, buf.length, group, port);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while(true) {
beat();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void beat() {
try {
multicastSocket.send(datagramPacket);
message(new Message(TYPE.INFO, KEY.MESSAGE, "Heart beat sent."));
} catch (IOException e) {
e.printStackTrace();
}
}
private void message(Message message) {
setChanged();
notifyObservers(message);
}
}
public class BeatListener extends Observable implements Runnable {
private boolean run = true;
private String groupName = "229.5.38.17";
MulticastSocket multicastSocket;
private Network network;
public BeatListener(Network network, Observer... observers) {
for(Observer observer : observers) {
addObserver(observer);
}
try {
multicastSocket = new MulticastSocket(4567);
multicastSocket.joinGroup(InetAddress.getByName(groupName));
} catch (IOException e) {
error(e);
e.printStackTrace();
}
this.network = network;
}
@Override
public void run() {
while(run) {
DatagramPacket datagramPacket = new DatagramPacket(new byte[1500], 1500);
try {
multicastSocket.receive(datagramPacket);
if(!isLocalhost(datagramPacket.getAddress().getHostAddress())) {
Beat beat = getBeat(datagramPacket);
if(beat != null) {
network.setPeer(new Peer(datagramPacket.getAddress(), beat.getConnectionListenerPort()));
message(new Message(TYPE.NETWORK, KEY.NETWORK, network));
}
}
} catch (IOException e) {
error(e);
e.printStackTrace();
}
}
}
private void message(Message message) {
setChanged();
notifyObservers(message);
}
private void error(Exception e) {
message(new Message(TYPE.ERROR, KEY.MESSAGE, e.getClass().getSimpleName()));
}
public void stop() {
run = false;
}
private boolean isLocalhost(String hostAddress) {
boolean isLocalhost = false;
Enumeration<NetworkInterface> networkInterfaces;
try {
networkInterfaces = NetworkInterface.getNetworkInterfaces();
if(networkInterfaces != null) {
OUTER:
while(networkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = networkInterfaces.nextElement();
Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
if(inetAddresses != null) {
while(inetAddresses.hasMoreElements()) {
InetAddress inetAddress = inetAddresses.nextElement();
if(hostAddress.equals(inetAddress.getHostAddress())) {
isLocalhost = true;
break OUTER;
}
}
}
}
}
} catch (SocketException e) {
error(e);
e.printStackTrace();
}
return isLocalhost;
}
private Beat getBeat(DatagramPacket datagramPacket) {
Beat beat = null;
byte[] data = datagramPacket.getData();
if(data != null) {
try {
ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(data));
beat = (Beat)objectInputStream.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return beat;
}
}
public类Heart扩展了可观察的实现Runnable{
私有字符串groupName=“229.5.38.17”;
专用int端口=4567;
多播套接字多播套接字;
DatagramPacket DatagramPacket;
公共心脏(int连接侦听器端口、观察员…观察员){
观察员(观察员:观察员){
这是一个观察者(观察者);
}
试一试{
multicastSocket=新的multicastSocket();
InetAddress组=InetAddress.getByName(groupName);
ByteArrayOutputStream ByteArrayOutputStream=新建ByteArrayOutputStream();
ObjectOutputStream ObjectOutputStream=新的ObjectOutputStream(byteArrayOutputStream);
writeObject(新的Beat(connectionListenerPort));
objectOutputStream.flush();
objectOutputStream.close();
字节[]buf=byteArrayOutputStream.toByteArray();
datagramPacket=新的datagramPacket(buf,buf.length,group,port);
}捕获(IOE异常){
e、 printStackTrace();
}
}
@凌驾
公开募捐{
while(true){
拍();
试一试{
睡眠(5000);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}
私人空拍(){
试一试{
多播套接字发送(datagramPacket);
消息(新消息(TYPE.INFO,KEY.message,“心跳已发送”);
}捕获(IOE异常){
e、 printStackTrace();
}
}
专用无效消息(消息消息消息){
setChanged();
通知观察员(信息);
}
}
公共类BeatListener扩展了可观察实现Runnable{
私有布尔运行=true;
私有字符串groupName=“229.5.38.17”;
多播套接字多播套接字;
专用网络;
公共BeatListener(网络、观察者…观察者){
观察员(观察员:观察员){
观察员(观察员);
}
试一试{
multicastSocket=新的multicastSocket(4567);
multicastSocket.joinGroup(InetAddress.getByName(groupName));
}捕获(IOE异常){
错误(e);
e、 printStackTrace();
}
这个网络=网络;
}
@凌驾
公开募捐{
while(运行){
DatagramPacket DatagramPacket=新的DatagramPacket(新字节[1500],1500);
试一试{
多播套接字接收(datagramPacket);
如果(!isLocalhost(datagramPacket.getAddress().getHostAddress())){
Beat-Beat=getBeat(数据包);
如果(节拍!=null){
network.setPeer(新的对等(datagramPacket.getAddress(),beat.getConnectionListenerPort());
消息(新消息(TYPE.NETWORK、KEY.NETWORK、NETWORK));
}
}
}捕获(IOE异常){
错误(e);
e、 printStackTrace();
}
}
}
专用无效消息(消息消息消息){
setChanged();
通知观察员(信息);
}
私有无效错误(异常e){
消息(新消息(TYPE.ERROR,KEY.message,e.getClass().getSimpleName());
}
公共停车场(){
运行=错误;
}
专用布尔值isLocalhost(字符串主机地址){
布尔值isLocalhost=false;
枚举网络接口;
试一试{
networkInterfaces=NetworkInterface.getNetworkInterfaces();
if(网络接口!=null){
外部:
while(networkInterfaces.hasMoreElements()){
NetworkInterface NetworkInterface=networkInterfaces.nextElement();
枚举inetAddresses=networkInterface.getInetAddresses();
if(inetAddresses!=null){
while(inetAddresses.hasMoreElements()){
InetAddress InetAddress=inetAddresses.nextElement();
if(hostAddress.equals(inetAddress.getHostAddress())){
isLocalhost=true;
打破外部;
}
}
}
}
}
}捕获(SocketException e){
错误(e);
e、 printStackTrace();
}
返回isLocalhost;
}
私人节拍getBeat(DatagramPacket DatagramPacket){
拍=空;
byte[]data=datagramPacket.getData();
如果(数据!=null){
试一试{
ObjectInputStream ObjectInputStream=新的ObjectInputStream(新的ByteArrayInputStream(数据));
beat=(beat)objectInputStream.readObject();
}捕获(IOE异常){
e、 printStackTrace();
}catch(classnotfounde异常){
e、 printStackTrace();
}
}
回击;
}
}
如果您在本地网络上运行,您的方法可能会花费大量时间,而且肯定不是最佳解决方案
您可以通过让服务器定期在网络中广播其地址并让所有客户端监听来解决此问题。可以在中找到一个很好的示例。Sen