在本文中,我們來(lái)學(xué)習(xí)下如何找到連接到服務(wù)器的客戶端計(jì)算機(jī)的IP地址。我們將創(chuàng)建一個(gè)簡(jiǎn)單的客戶端-服務(wù)器場(chǎng)景,讓我們探索用于TCP/IP通信的java.net
API。
背景
Java應(yīng)用程序使用套接字在互聯(lián)網(wǎng)上進(jìn)行通信和發(fā)送數(shù)據(jù)。Java為客戶端應(yīng)用程序提供了java.net.Socket
類。
java.net.ServerSocket
類用于TCP/IP的服務(wù)器端套接字實(shí)現(xiàn)。我們平時(shí)只關(guān)注TCP/IP的應(yīng)用層面。
使用示例
讓我們假設(shè)我們的系統(tǒng)上有一個(gè)應(yīng)用服務(wù)器在運(yùn)行。這個(gè)服務(wù)器向客戶發(fā)送問(wèn)候信息。在這種情況下,服務(wù)器使用一個(gè)TCP套接字進(jìn)行通信。
該應(yīng)用服務(wù)器被綁定到一個(gè)特定的TCP端口。它的套接字地址是該端口和本地網(wǎng)絡(luò)接口的IP地址的組合。由于這個(gè)原因,客戶應(yīng)該使用這個(gè)特定的套接字地址來(lái)連接服務(wù)器。
應(yīng)用例子
現(xiàn)在我們已經(jīng)定義了我們的用例,讓我們開(kāi)始構(gòu)建服務(wù)器。
應(yīng)用服務(wù)器
首先,我們需要實(shí)例化一個(gè)ServerSocket
,用于監(jiān)聽(tīng)進(jìn)入的連接請(qǐng)求。ServerSocket
類的構(gòu)造函數(shù)需要一個(gè)端口號(hào)作為參數(shù)。
public class ApplicationServer {
private ServerSocket serverSocket;
private Socket connectedSocket;
public void startServer(int port) throws IOException {
serverSocket = new ServerSocket(port);
connectedSocket = serverSocket.accept();
//...
獲取客戶端的IP地址
現(xiàn)在我們已經(jīng)為進(jìn)入的客戶端建立了Socket
,讓我們看看如何獲得客戶端的IP地址。Socket
實(shí)例包含了遠(yuǎn)程客戶端的套接字地址。我們可以使用getRemoteSocketAddress
方法來(lái)檢查這個(gè)。
ThegetRemoteSocketAddress
方法返回一個(gè)類型為SocketAddress
的對(duì)象。這是一個(gè)抽象的Java類。在這個(gè)例子中,我們知道它是一個(gè)TCP/IP連接,所以我們可以把它轉(zhuǎn)換為InetSocketAddress
。
InetSocketAddress socketAddress = (InetSocketAddress) connectedSocket.getRemoteSocketAddress();
正如我們已經(jīng)看到的,一個(gè)套接字地址是一個(gè)IP地址和端口號(hào)的組合。我們可以使用getAddress
來(lái)獲得IP地址。這返回一個(gè)InetAddress
對(duì)象。然而,我們也可以使用getHostAddress
來(lái)獲得IP地址的字符串表示。
String clientIpAddress = socketAddress.getAddress()
.getHostAddress();
向客戶端發(fā)送消息
現(xiàn)在,服務(wù)器和客戶端可以交換問(wèn)候信息。
String msg = in.readLine();
System.out.println("Message received from the client : " + msg);
PrintWriter out = new PrintWriter(connectedSocket.getOutputStream(), true);
out.println("Hello Client !!");
測(cè)試應(yīng)用程序
現(xiàn)在讓我們建立一個(gè)客戶端應(yīng)用程序來(lái)測(cè)試我們的代碼。這個(gè)客戶端將在一個(gè)單獨(dú)的計(jì)算機(jī)上運(yùn)行并連接到我們的服務(wù)器。
建立一個(gè)客戶端應(yīng)用程序
首先,我們需要使用IP地址和端口號(hào)與服務(wù)建立一個(gè)Socket
連接。
public class ApplicationClient {
public void connect(String ip, int port) throws IOException {
clientSocket = new Socket(ip, port);
}
}
與服務(wù)器應(yīng)用程序類似,我們將使用BufferedReader
和PrintWriter
來(lái)從套接字中讀取和寫(xiě)入。為了向服務(wù)器發(fā)送消息,讓我們創(chuàng)建一個(gè)方法來(lái)向連接的套接字寫(xiě)入。
public void sendGreetings(String msg) throws IOException {
out.println(msg);
String reply = in.readLine();
System.out.println("Reply received from the server :" + reply);
}
運(yùn)行應(yīng)用程序
接下來(lái),讓我們運(yùn)行客戶端應(yīng)用程序,為它選擇一個(gè)不常用的端口
之后,我們需要從另一臺(tái)電腦上啟動(dòng)客戶端應(yīng)用程序。在這個(gè)例子中,我們假設(shè)服務(wù)器機(jī)器的IP地址是192.168.0.100
,端口5000是不常用的,不會(huì)影響其他的服務(wù)。
java -cp com.javanorth.clientaddress.ApplicationClient 192.168.0.100 5000 Hello
這里,我們假設(shè)客戶機(jī)和服務(wù)器在同一個(gè)網(wǎng)絡(luò)上。在客戶端與服務(wù)器建立成功的連接后,客戶端的IP地址將被打印在服務(wù)器控制臺(tái)。
例如,如果客戶端的IP地址是192.168.0.102,我們應(yīng)該能在控制臺(tái)中看到它。
IP address of the connected client: 192.168.0.102
在后臺(tái)發(fā)生了什么?
一般來(lái)說(shuō),當(dāng)應(yīng)用服務(wù)器被啟動(dòng)時(shí),ServerSocket
使用給定的端口號(hào)和通配符IP地址實(shí)例化一個(gè)套接字對(duì)象。之后,它將其狀態(tài)改為監(jiān)聽(tīng)
,以接收連接請(qǐng)求。然后,當(dāng)客戶端發(fā)送一個(gè)連接請(qǐng)求時(shí),ServerSocket
通過(guò)調(diào)用accept
方法實(shí)例化一個(gè)新的套接字。
新創(chuàng)建的套接字實(shí)例包含服務(wù)器的IP地址和端口,以及遠(yuǎn)程客戶端。對(duì)于服務(wù)器的IP地址,ServerSocket
類使用本地網(wǎng)絡(luò)接口的IP地址,它通過(guò)該接口收到傳入的請(qǐng)求。然后,為了獲得遠(yuǎn)程客戶端的IP地址,它對(duì)收到的TCP數(shù)據(jù)包的IP頭進(jìn)行解碼并使用源地址。
總結(jié)
在這篇文章中,我們定義了一個(gè)客戶機(jī)-服務(wù)器用例,并使用Java套接字編程來(lái)查找連接到服務(wù)器的客戶機(jī)的IP地址。
-
計(jì)算機(jī)
+關(guān)注
關(guān)注
19文章
7494瀏覽量
87953 -
服務(wù)器
+關(guān)注
關(guān)注
12文章
9160瀏覽量
85419 -
JAVA
+關(guān)注
關(guān)注
19文章
2967瀏覽量
104750 -
ip地址
+關(guān)注
關(guān)注
0文章
303瀏覽量
17055 -
應(yīng)用程序
+關(guān)注
關(guān)注
37文章
3268瀏覽量
57705
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論