1. Introduction
1.绪论
In this quick tutorial, we’re going to learn how to find the IP address of a client computer connected to a server.
在这个快速教程中,我们将学习如何找到连接到服务器的客户电脑的IP地址。
We’ll create a simple client-server scenario to allow us to explore the java.net APIs available for TCP/IP communication.
我们将创建一个简单的客户端-服务器场景,让我们探索可用于TCP/IP通信的java.netAPI。
2. Background
2. 背景
Java applications use sockets for communicating and sending data over the internet. Java provides the java.net.Socket class for client applications.
Java应用程序使用套接字来在互联网上进行通信和发送数据。Java为客户端应用程序提供了java.net.Socket类。
The java.net.ServerSocket class is used for TCP/IP-based server-side socket implementation. However, let’s focus only on TCP/IP applications.
java.net.ServerSocket类用于基于TCP/IP的服务器端套接字实现。然而,让我们只关注TCP/IP应用。
3. Sample Use-Case
3.使用案例样本
Let’s assume that we have an application server running on our system. This server sends greetings messages to the clients. In this case, the server uses a TCP socket for communication.
让我们假设我们的系统上有一个应用服务器在运行。这个服务器向客户发送问候信息。在这种情况下,服务器使用一个TCP套接字进行通信。
The application server is bound to a specific TCP port. Its socket address is the combination of that port and the IP address of the local network interface. For this reason, the client should use this particular socket address for connecting to the server.
应用服务器被绑定到一个特定的TCP端口。它的套接字地址是该端口和本地网络接口的IP地址的组合。由于这个原因,客户应该使用这个特定的套接字地址来连接服务器。
4. Sample Application
4.申请书样本
Now that we’ve defined our use-case, let’s start by building the server.
现在我们已经定义了我们的用例,让我们开始构建服务器。
4.1. The Application Server
4.1.应用服务器
First, we need to instantiate a ServerSocket for listening to incoming connection requests. The constructor of the ServerSocket class requires a port number as an argument:
首先,我们需要实例化一个ServerSocket,用于监听进入的连接请求。ServerSocket类的构造函数需要一个端口号作为参数。
public class ApplicationServer {
private ServerSocket serverSocket;
private Socket connectedSocket;
public void startServer(int port) throws IOException {
serverSocket = new ServerSocket(port);
connectedSocket = serverSocket.accept();
//...
4.2. Obtaining the Client IP Address
4.2.获得客户的IP地址
Now that we’ve established our Socket for the incoming client, let’s see how to obtain the client’s IP address. The Socket instance contains the socket address of the remote client. We can use the getRemoteSocketAddress method to inspect this.
现在我们已经为进入的客户端建立了Socket,让我们看看如何获得客户端的IP地址。Socket实例包含远程客户端的套接字地址。我们可以使用getRemoteSocketAddress方法来检查这个。
ThegetRemoteSocketAddress method returns an object of type SocketAddress. This is an abstract Java class. In this instance, we know it’s a TCP/IP connection, so we can cast it to InetSocketAddress:
getRemoteSocketAddress方法返回一个SocketAddress类型的对象。这是一个抽象的Java类。在这个例子中,我们知道它是一个TCP/IP连接,所以我们可以把它转换成InetSocketAddress。
InetSocketAddress socketAddress = (InetSocketAddress) connectedSocket.getRemoteSocketAddress();
As we’ve already seen, a socket address is a combination of an IP address and port number. We can use getAddress to get the IP address. This returns an InetAddress object. However, we can also use getHostAddress to get a string representation of the IP address:
正如我们已经看到的,一个套接字地址是一个IP地址和端口号的组合。我们可以使用getAddress来获取IP地址。这将返回一个InetAddress对象。然而,我们也可以使用getHostAddress来获得IP地址的字符串表示。
String clientIpAddress = socketAddress.getAddress()
.getHostAddress();
4.3. Sending Greeting Message to the Client
4.3.向客户发送问候信息
Now, the server and client can exchange greeting messages:
现在,服务器和客户端可以交换问候信息。
String msg = in.readLine();
System.out.println("Message received from the client :: " + msg);
PrintWriter out = new PrintWriter(connectedSocket.getOutputStream(), true);
out.println("Hello Client !!");
5. Test the Application
5.测试应用程序
Let’s now build a client application to test our code. This client will run on a separate computer and connect to our server.
现在让我们建立一个客户端应用程序来测试我们的代码。这个客户端将在一个单独的计算机上运行,并连接到我们的服务器。
5.1. Build a Client Application
5.1.构建一个客户端应用程序
First, we need to establish a Socket connection to the service using the IP address and the port number:
首先,我们需要使用IP地址和端口号建立一个Socket连接到服务。
public class ApplicationClient {
public void connect(String ip, int port) throws IOException {
clientSocket = new Socket(ip, port);
}
}
Similar to the server application, we’ll use the BufferedReader and PrintWriter to read from and write to the socket. For sending messages to the server, let’s create a method to write to the connected socket:
与服务器应用程序类似,我们将使用BufferedReader和PrintWriter来从套接字中读取和写入。为了向服务器发送消息,让我们创建一个方法来向连接的套接字写入。
public void sendGreetings(String msg) throws IOException {
out.println(msg);
String reply = in.readLine();
System.out.println("Reply received from the server :: " + reply);
}
5.2. Run the Application
5.2.运行应用程序
Next, let’s run the client application, choosing a free port for it.
接下来,让我们运行客户端应用程序,为其选择一个免费端口。
After that, we need to start the client application from another PC. For this example, let’s say the IP address of the server machine is 192.168.0.100 and port 5000 is free:
之后,我们需要从另一台电脑上启动客户端应用程序。在这个例子中,我们假设服务器机器的IP地址是192.168.0.100,端口5000是空的。
java -cp com.baeldung.clientaddress.ApplicationClient 192.168.0.100 5000 Hello
Here, we’re assuming that the client and server are on the same network. After the client establishes a successful connection to the server, the IP address of the client will be printed on the server console.
这里,我们假设客户机和服务器在同一个网络上。在客户机与服务器建立成功连接后,客户机的IP地址将被打印在服务器控制台。
If the client IP address, for example, is 192.168.0.102, we should be able to see it in the console:
例如,如果客户的IP地址是192.168.0.102,我们应该能在控制台看到它。
IP address of the connected client :: 192.168.0.102
5.3. What Happened in the Background?
5.3.背景中发生了什么?
In general, when the application server is started, the ServerSocket instantiates a socket object using the given port number and a wildcard IP address. After that, it changes its status to “Listening” for incoming connection requests. Then, when the client sends a connection request, ServerSocket instantiates a new socket by invoking the accept method.
一般来说,当应用服务器启动时,ServerSocket会使用给定的端口号和通配符IP地址实例化一个套接字对象。之后,它将其状态改为“监听”,以接收连接请求。然后,当客户端发送一个连接请求时,ServerSocket通过调用accept方法实例化一个新的套接字。
The newly created socket instance contains the IP address and port of the server as well as the remote client. For server IP address, the ServerSocket class uses the IP address of the local network interface through which it received the incoming request. Then, to obtain the remote client IP address, it decodes the IP header of the received TCP packet and uses the source address.
新创建的套接字实例包含服务器以及远程客户端的IP地址和端口。对于服务器的IP地址,ServerSocket类使用本地网络接口的IP地址,它通过该接口接收传入的请求。然后,为了获得远程客户端的IP地址,它对收到的TCP数据包的IP头进行解码并使用源地址。
6. Conclusion
6.结语
In this article, we defined a sample client-server use-case and used Java socket programming to find the IP address of a client connected to a server.
在这篇文章中,我们定义了一个客户机-服务器的用例,并使用Java socket编程来查找连接到服务器的客户机的IP地址。
As always, the code of this application is available over on GitHub.
一如既往,本应用程序的代码可在GitHub上获取。