2012-05-04 123 views
1

我正在用Java创建一个模拟经典5卡扑克游戏,玩2到4个玩家。 大部分数据将由服务器处理,但由于我无法使用在线服务器,我的想法是允许用户通过创建本地服务器来托管游戏。广播服务器发现

现在,我不想强​​制使用IP连接到游戏,所以我创建了一个“发现”界面,用户可以看到所有可用的游戏。这是通过使用UDP协议和一个共同的组广播的研究做:

(代码简化为只显示正在执行的操作,因为它是在这里显示可能无法正常工作)

客户

MulticastSocket socket = new MulticastSocket(6020); 
InetAddress group = InetAddress.getByName("226.0.0.1"); 
socket.joinGroup(group); 

DatagramPacket packet = new DatagramPacket(new byte[] {(byte) 0xF0}, 1, group, 6020); 
socket.send(packet); 

while(true) { 
    buf = new byte[1]; 
    packet = new DatagramPacket(buf, buf.length); 
    socket.receive(packet); 

    if(packet.getData()[0] == 15) { 
     Socket client = new Socket(packet.getAddress(), 6020); 
    } 
} 

服务器

MulticastSocket socket = new MulticastSocket(6020); 
InetAddress group = InetAddress.getByName("226.0.0.1"); 
socket.joinGroup(group); 

// new thread listening on port 6020 TCP 
ServerSocket server = new ServerSocket(6020); 
new Thread(new Runnable() { 

      public void run() { 
       while(true) { 
        // new thread communicating with client and back listening on port 6020 
        new ServerThread(server.accept()); 
       } 
      } 
}).start(); 

// listening on port 6020 UDP 
byte[] buf; 
DatagramPacket packet; 
while(true) { 
    buf = new byte[1]; 
    packet = new DatagramPacket(buf, buf.length); 
    socket.receive(packet); 

    if(packet.getData()[0] == -16) { 
     DatagramPacket packet = new DatagramPacket(new byte[] {(byte) 0x0F}, 1, packet.getSocketAddress()); 
     socket.send(packet); 
    } 
} 

客户端在端口6020发送一个UDP广播数据包。当服务器接收到这个数据包,如果它由字节0xF0组成的话,他会向客户端发回一个字节0x0F。每个客户端也监听6020端口,当收到一个由字节0x0F组成的数据包时,它会启动一个新的连接TCP到端口6020上的服务器。

我的问题:是否有更好的方法来实现这个“发现“系统? 我知道这只能在本地网络中工作,是否有可能使用本地服务器将“发现”扩展到“外部”?

回答

1

除非您想设置某种可以将玩家连接到服务器(或向他们提供服务器列表)的已知代理,否则您可能不太好。正如您发现的,多播和广播通常不会通过大多数交换机发送到广域网(并且绝对不能遍历Internet)。

如果您在设置已知服务器/代理时遇到的问题是您有家庭连接以及动态IP,我建议您查看动态DNS。有许多提供商允许您在他们的系统中设置一个子域,并在IP更改时自动更改为指向您的IP。