2012-05-04 150 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。