詳解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)從套接字中讀取和寫(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地址。
以上就是詳解Java如何通過(guò)Socket實(shí)現(xiàn)查詢IP的詳細(xì)內(nèi)容,更多關(guān)于Java Socket查詢IP的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java那點(diǎn)事——StringBuffer與StringBuilder原理與區(qū)別
本文給大家分享StringBuffer與StringBuilder的區(qū)別,它們的應(yīng)用場(chǎng)景是什么?非常不錯(cuò),面試考官經(jīng)??嫉囊粋€(gè)問(wèn)題,有需要的朋友跟著腳本之家小編一起學(xué)習(xí)吧2016-06-06SchedulingConfigurer實(shí)現(xiàn)動(dòng)態(tài)定時(shí),導(dǎo)致ApplicationRunner無(wú)效解決
這篇文章主要介紹了SchedulingConfigurer實(shí)現(xiàn)動(dòng)態(tài)定時(shí),導(dǎo)致ApplicationRunner無(wú)效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05Mybatis結(jié)果集映射與生命周期詳細(xì)介紹
結(jié)果集映射指的是將數(shù)據(jù)表中的字段與實(shí)體類中的屬性關(guān)聯(lián)起來(lái),這樣 MyBatis 就可以根據(jù)查詢到的數(shù)據(jù)來(lái)填充實(shí)體對(duì)象的屬性,幫助我們完成賦值操作2022-10-10Java8 Optional判空詳解(簡(jiǎn)化判空操作)
這篇文章主要給大家介紹了關(guān)于Java8 Optional判空(簡(jiǎn)化判空操作)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05SpringBoot @ConfigurationProperties注解的簡(jiǎn)單使用
即便現(xiàn)在簡(jiǎn)化了配置,但是一個(gè)獨(dú)立的配置文件總是易于理解而且使人安心的。Spring在構(gòu)建完項(xiàng)目后,會(huì)默認(rèn)在resources文件夾下創(chuàng)建一個(gè)application.properties文件,application.yml也是一樣的效果。@ConfigurationProperties可以獲取配置文件中的數(shù)據(jù),將其注入類。2021-05-05Java通過(guò)PowerMockito和Mokito進(jìn)行單元測(cè)試的實(shí)現(xiàn)
PowerMockito和Mockito都是Java語(yǔ)言中的測(cè)試框架,用于進(jìn)行單元測(cè)試和集成測(cè)試,本文就來(lái)詳細(xì)的介紹一下通過(guò)PowerMockito和Mokito進(jìn)行單元測(cè)試,感興趣的可以了解一下2023-08-08SpringBoot2中使用@RequestHeader獲取請(qǐng)求頭的方法
springMVC/SpringBoot中提供了@RequestHeader注解用來(lái)獲取請(qǐng)求頭。本文就詳細(xì)的來(lái)介紹一下如何使用,感興趣的可以了解下2021-10-10