简体   繁体   English

如何使用套接字获取Java,TCP / IP服务器/客户端模型中的远程IP地址?

[英]How to get the remote IP adress in Java, TCP/IP Server/Client model with sockets?

So i have a TCP/IP Server/Client model using Socket and ServerSocket in an desktop application (A game that's suposed to be played in network). 因此,我有一个在桌面应用程序中使用Socket和ServerSocket的TCP / IP服务器/客户端模型(本应在网络中玩的游戏)。

I need to get the servers Remote IP address so that the client application can connect to it at the opened Server application at the specific port opened. 我需要获取服务器的远程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;
    }
}

It works well on localhost, but I want it to be capable to run anywhere (the server and the client). 它在localhost上运行良好,但我希望它能够在任何地方(服务器和客户端)运行。 So i need a way for the server to find out it's current remote IP the user will send it via some comunication line (IM, E-mail etc...) and afterward the client will input the address and connect to the server. 因此,我需要让服务器找到它的当前远程IP的方法,用户将通过一些通信线路(IM,电子邮件等...)将其发送,然后客户端将输入地址并连接到服务器。 Therefore one single application can act as both server or client, so there is no need for a stable server application that will run continously and serve clients 因此,一个应用程序既可以充当服务器又可以充当客户端,因此不需要稳定的服务器应用程序来连续运行并为客户端提供服务。

If your client and the server live in the same network segment, Zeroconf is a very attractive zero configuration (well...) solution. 如果您的客户端和服务器位于同一网段,那么Zeroconf是一个非常有吸引力的零配置(很好...)解决方案。 you will find a Java implementation with JmDNS 您会发现使用JmDNS的Java实现

Furthermore, it's not an easy task to implement a stable protocol from scratch. 此外,从头开始实现稳定的协议并非易事。 If it is not for education purposes i'd recommend relying on something like 如果不是出于教育目的,我建议您依靠类似

  • Apache Mina 阿帕奇米娜
  • Grizzly 灰熊
  • Netty 3 净值3
  • QuickServer 快速服务器
  • xSocket xSocket

These libraries give you many features that are important here, like error handling and concurrency (non blocking calls). 这些库为您提供了许多在这里很重要的功能,例如错误处理和并发(非阻塞调用)。

If you want to reach your server from outside, you can not bind to "localhost". 如果要从外部访问服务器,则不能绑定到“ localhost”。 See ServerSocket.bind. 请参阅ServerSocket.bind。 You can bind to "null" and request the network adapter that has been used by default via ServerSocket.getInetAddress. 您可以绑定到“空”并通过ServerSocket.getInetAddress请求默认使用的网络适配器。

You need to make two adjustments: 您需要进行两项调整:

  • Server socket must be bound to something else than localhost. 服务器套接字必须绑定到非本地主机。 Typically you create server socket by using new ServerSocket(port) , without specifying a hostname. 通常,您使用new ServerSocket(port)创建服务器套接字,而不指定主机名。 This way, server socket will listen on given port for all available addresses on the machine. 这样,服务器套接字将在给定的端口上侦听机器上所有可用的地址。 If you bind your socket to 'localhost', then it will be accessible through localhost only. 如果将套接字绑定到“ localhost”,则只能通过localhost访问。 That's not what you want. 那不是你想要的。 After creating server socket, you can try to find out its SocketAddress by using serverSocket.getLocalSocketAddress() . 创建服务器套接字后,可以尝试使用serverSocket.getLocalSocketAddress()找出其SocketAddress

  • Client will need to connect to the address that you've specified when creating/binding the server socket. 客户端将需要连接到创建/绑定服务器套接字时指定的地址。 If you have created server socket without specifying an address (ie binding to all available addresses), then client can connect to any of those (usually localhost + external ip address). 如果您在创建服务器套接字时未指定地址(即绑定到所有可用地址),则客户端可以连接到其中任何一个(通常是localhost +外部IP地址)。

Servers typically don't need to know their address. 服务器通常不需要知道其地址。 They simply bind to <any address>:port , and client must know the address to connect to. 它们只是绑定到<any address>:port ,客户端必须知道要连接的地址。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM