詳解Java如何通過(guò)Socket實(shí)現(xiàn)查詢IP
在本文中,我們來(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)從套接字中讀取和寫入。為了向服務(wù)器發(fā)送消息,讓我們創(chuàng)建一個(gè)方法來(lái)向連接的套接字寫入。
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地址。
以上就是詳解Java如何通過(guò)Socket實(shí)現(xiàn)查詢IP的詳細(xì)內(nèi)容,更多關(guān)于Java Socket查詢IP的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
企業(yè)級(jí)Kubernetes管理平臺(tái)Wayne功能特性介紹
這篇文章主要為大家介紹了企業(yè)級(jí)Kubernetes管理平臺(tái)Wayne的功能特性及架構(gòu)設(shè)計(jì),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-02-02
SpringCloud筆記(Hoxton)Netflix之Ribbon負(fù)載均衡示例代碼
這篇文章主要介紹了SpringCloud筆記HoxtonNetflix之Ribbon負(fù)載均衡,Ribbon是管理HTTP和TCP服務(wù)客戶端的負(fù)載均衡器,Ribbon具有一系列帶有名稱的客戶端(Named?Client),對(duì)SpringCloud?Ribbon負(fù)載均衡相關(guān)知識(shí)感興趣的朋友一起看看吧2022-06-06
Springboot+jwt實(shí)現(xiàn)在線用戶功能(示例代碼)
這篇文章主要介紹了Springboot+jwt實(shí)現(xiàn)在線用戶功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-12-12
springboot攔截器無(wú)法注入redisTemplate的解決方法
在工作中我們經(jīng)常需要做登錄攔截驗(yàn)證或者其他攔截認(rèn)證功能,但是在寫攔截器的時(shí)候發(fā)現(xiàn)redisTemplate一直無(wú)法注入進(jìn)來(lái),本文就詳細(xì)的介紹了解決方法,感興趣的可以了解一下2021-06-06
mybatis主從表關(guān)聯(lián)查詢,返回對(duì)象帶有集合屬性解析
這篇文章主要介紹了mybatis主從表關(guān)聯(lián)查詢,返回對(duì)象帶有集合屬性解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03

