2012-05-10 67 views
0

因此,我有一個在桌面應用程序中使用Socket和ServerSocket的TCP/IP服務器/客戶端模型(一種可以在網絡中播放的遊戲)。如何在帶有套接字的Java,TCP/IP服務器/客戶端模型中獲取遠程IP地址?

我需要獲取服務器的遠程IP地址,以便客戶端應用程序可以在打開的特定端口打開的服務器應用程序連接到它。

public class ServerConnection { 

private int PORT = 8100; 
private ServerSocket serverSocket = null; 

public void create() throws IOException { 
    serverSocket = new ServerSocket(); 
    serverSocket.bind(new InetSocketAddress("localhost", PORT)); 
} 

public void close() throws IOException { 
    serverSocket.close(); 
} 

public ClientConnection acceptRequest() throws IOException { 
    Socket socket = serverSocket.accept(); 
    return new ClientConnection(socket); 
} 

public ServerConnection() throws IOException { 
} 
} 
public class ClientConnection { 

    private String adress = "127.0.0.1"; 
    private int PORT = 8100; 
    private Socket socket = null; 
    private PrintWriter out = null; 
    private BufferedReader in = null; 

    public ClientConnection() { 

    } 

    public ClientConnection(Socket socket) throws IOException { 
     this.socket = socket; 
     out = new PrintWriter(socket.getOutputStream(), true); 
     in = new BufferedReader(new InputStreamReader(
       socket.getInputStream())); 
    } 

    public void connect() throws UnknownHostException, IOException { 
     socket = new Socket(adress, PORT); 
     out = new PrintWriter(socket.getOutputStream(), true); 
     in = new BufferedReader(new InputStreamReader(
       socket.getInputStream())); 
    } 


    public void close() throws IOException { 
     if (out != null) { 
      out.close(); 
     } 
     if (in != null) { 
      in.close(); 
     } 
     if (socket != null) { 
      socket.close(); 
      socket = null; 
     } 
    } 

    public void send(String request) { 
     if (socket != null) { 
      out.println(request); 
     }    
    } 

    public String receive() throws IOException { 
     if (socket != null) { 
      return in.readLine(); 
     } 
     return null; 
    } 
} 

它在localhost上運行良好,但我希望它能夠在任何地方運行(服務器和客戶端)。所以我需要一種方法讓服務器找出它是當前的遠程IP,用戶將通過一些通信線(IM,E-mail等)發送它,然後客戶端將輸入地址並連接到服務器。因此,一個應用程序既可以作爲服務器,也可以作爲客戶端,因此不需要穩定的服務器應用程序,可以連續運行併爲客戶端提供服務。

+0

硬碼嗎?如果不是,請硬編碼一個域來指向它? – Jeremy

+0

我希望能夠在任何我想要的地方運行我的服務器應用程序,我如何硬編碼一個域來指向它? –

+1

它並不需要硬編碼到您的代碼中。客戶端只需要能夠以某種方式查找IP地址(或域)。 Ii可以在用戶可配置的屬性文件或類似的東西。 – Jeremy

回答

1

如果您的客戶端和服務器位於同一網段,Zeroconf是一個非常有吸引力的零配置(好...)解決方案。你會發現一個Java實現with JmDNS

此外,從零開始實現一個穩定的協議並不是一件容易的事情。如果它不是爲教育目的,我建議你依靠像

  • Apache的米納
  • 灰熊
  • 的Netty 3
  • 了QuickServer
  • 了xSocket

這些庫給你在這裏很重要的許多功能,如錯誤處理和併發(非阻塞調用)。

如果您想從外部訪問您的服務器,則無法綁定到「localhost」。請參閱ServerSocket.bind。您可以綁定到「null」並通過ServerSocket.getInetAddress請求默認使用的網絡適配器。

+0

我說我希望它能夠在任何地方工作 –

+0

你不明白,我有一個既可以作爲服務器也可以作爲客戶端的應用程序,我不需要除了計算機的遠程地址以外,還需要其他任何東西(例如http://whatismyipaddress.com/) –

0

你需要作出兩項調整:

  • 服務器套接字必須綁定到localhost別的東西。通常,您使用new ServerSocket(port)創建服務器套接字,而不指定主機名。這樣,服務器套接字將在給定端口上監聽機器上所有可用的地址。如果將套接字綁定到「localhost」,則只能通過本地主機訪問它。這不是你想要的。在創建服務器套接字後,您可以嘗試使用serverSocket.getLocalSocketAddress()來查找其SocketAddress

  • 客戶端需要連接到創建/綁定服務器套接字時指定的地址。如果您已經創建了服務器套接字而沒有指定地址(即綁定到所有可用地址),則客戶端可以連接到任何這些地址(通常是本地主機+外部IP地址)。

服務器通常不需要知道他們的地址。他們只需綁定到<any address>:port,客戶端必須知道要連接的地址。

相關問題