![](/img/trans.png)
[英]How can I retrieve a user's public IP address via Amazon API Gateway (JAVA)
[英]How can I determine the IP of my router/gateway in Java?
如何在 Java 中確定路由器/網關的 IP? 我可以很容易地獲得我的IP。 我可以使用網站上的服務獲取我的互聯網 IP。 但是如何確定網關的 IP?
如果您了解自己的方法,這在 .NET 中會比較容易。 但是你如何在 Java 中做到這一點呢?
在 Windows、OSX、Linux 等上,使用 Chris Bunch 的答案可以大大改進
netstat -rn
代替traceroute
命令。
您網關的 IP 地址將出現在以default
或0.0.0.0
開頭的行的第二個字段中。
這解決了嘗試使用traceroute
的許多問題:
traceroute
實際上是tracert.exe
,因此代碼中不需要 O/S 依賴項traceroute
有時會被網絡阻止唯一的缺點是有必要繼續從netstat
輸出中讀取行,直到找到正確的行,因為將有不止一行輸出。
編輯:如果您使用的是 MAC(在 Lion 上測試),則默認網關的 IP 地址位於以“default”開頭的行的第二個字段中,或者位於以“0.0.0.0”開頭的行的第三個字段中(在 Windows 7 上測試)
視窗:
網絡目標網絡掩碼網關接口指標
0.0.0.0 0.0.0.0 192.168.2.254 192.168.2.46 10
蘋果:
目標網關標志引用使用 Netif 過期
默認192.168.2.254 UGSc 104 4 en1
不幸的是,Java 並不像其他語言那樣令人愉快。 這是我所做的:
import java.io.*;
import java.util.*;
public class ExecTest {
public static void main(String[] args) throws IOException {
Process result = Runtime.getRuntime().exec("traceroute -m 1 www.amazon.com");
BufferedReader output = new BufferedReader(new InputStreamReader(result.getInputStream()));
String thisLine = output.readLine();
StringTokenizer st = new StringTokenizer(thisLine);
st.nextToken();
String gateway = st.nextToken();
System.out.printf("The gateway is %s\n", gateway);
}
}
這假定網關是第二個令牌而不是第三個。 如果是,則需要額外添加一個st.nextToken();
將標記器再推進一個位置。
在 Windows 上解析 IPConfig 的輸出將為您提供默認網關,而無需等待跟蹤。
try{
String gateway;
Process result = Runtime.getRuntime().exec("netstat -rn");
BufferedReader output = new BufferedReader(new InputStreamReader(result.getInputStream()));
String line = output.readLine();
while(line != null){
if ( line.trim().startsWith("default") == true || line.trim().startsWith("0.0.0.0") == true )
break;
line = output.readLine();
}
if(line==null) //gateway not found;
return;
StringTokenizer st = new StringTokenizer( line );
st.nextToken();
st.nextToken();
gateway = st.nextToken();
System.out.println("gateway is: "+gateway);
} catch( Exception e ) {
System.out.println( e.toString() );
gateway = new String();
adapter = new String();
}
您最好使用諸如 checkmyip.org 之類的東西,它會確定您的公共 IP 地址 - 不一定是您的第一跳路由器:在 Uni 我有一個“真實”的 IP 地址,而在家里,它是我本地路由器的公共 IP 地址。
您可以解析返回的頁面,或者找到另一個站點,該站點允許您將 IP 地址作為唯一的字符串返回。
(我的意思是在 Java 中加載這個 URL/任何東西,然后獲取你需要的信息)。
這應該是完全獨立於平台的。
關於 UPnP:請注意,並非所有路由器都支持 UPnP。 如果他們這樣做,它可能會被關閉(出於安全原因)。 因此,您的解決方案可能並不總是有效。
您還應該看看 NatPMP。
可以在http://miniupnp.free.fr/找到一個簡單的 UPnP 庫,盡管它是在 C 中...
要克服 traceroute(基於 ICMP,廣域命中)提到的問題,您可以考慮:
netstat -rn 的輸出是特定於語言環境的。 在我的系統 (locale=de) 上,輸出如下所示: ... Standardgateway: 10.22.0.1
所以沒有以“default”開頭的行。
所以使用 netstat 可能不是一個好主意。
此版本連接到 www.whatismyip.com,讀取站點內容並通過正則表達式搜索 ip 地址並將其打印到 cmd。 它是對 MosheElishas Code 的一點改進
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
BufferedReader buffer = null;
try {
URL url = new URL(
"http://www.whatismyip.com/tools/ip-address-lookup.asp");
InputStreamReader in = new InputStreamReader(url.openStream());
buffer = new BufferedReader(in);
String line = buffer.readLine();
Pattern pattern = Pattern
.compile("(.*)value=\"(\\d+).(\\d+).(\\d+).(\\d+)\"(.*)");
Matcher matcher;
while (line != null) {
matcher = pattern.matcher(line);
if (matcher.matches()) {
line = matcher.group(2) + "." + matcher.group(3) + "."
+ matcher.group(4) + "." + matcher.group(5);
System.out.println(line);
}
line = buffer.readLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (buffer != null) {
buffer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
BufferedReader buffer = null;
try {
URL url = new URL(
"http://www.whatismyip.com/tools/ip-address-lookup.asp");
InputStreamReader in = new InputStreamReader(url.openStream());
buffer = new BufferedReader(in);
String line = buffer.readLine();
Pattern pattern = Pattern
.compile("(.*)value=\"(\\d+).(\\d+).(\\d+).(\\d+)\"(.*)");
Matcher matcher;
while (line != null) {
matcher = pattern.matcher(line);
if (matcher.matches()) {
line = matcher.group(2) + "." + matcher.group(3) + "."
+ matcher.group(4) + "." + matcher.group(5);
System.out.println(line);
}
line = buffer.readLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (buffer != null) {
buffer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
這並不像聽起來那么容易。 Java 是獨立於平台的,所以我不確定如何在 Java 中做到這一點。 我猜測.NET 會聯系某個網站,然后將其報告回來。 有幾種方法可以走。 首先,深入了解 ICMP 協議可能會為您提供所需的信息。 您還可以跟蹤您通過的 IP(您的路由)。 當您遇到不在以下范圍內的 IP 時:
它是距離您的 IP 一跳的 IP,並且可能與您的 IP 共享幾個八位字節的信息。
祝你好運。 我很想聽到這個問題的明確答案。
如果你有的話,試着去追蹤路由。
'traceroute -m 1 www.amazon.com' 將發出如下內容:
traceroute to www.amazon.com (72.21.203.1), 1 hops max, 40 byte packets
1 10.0.1.1 (10.0.1.1) 0.694 ms 0.445 ms 0.398 ms
解析第二行。 是的,它很丑,但它會讓你繼續前進,直到有人發布更好的東西。
馬修:是的,這就是我所說的“我可以使用網站上的服務獲取我的互聯網 IP”。 抱歉我是油嘴滑舌的。
Brian/Nick:Traceroute 應該沒問題,除了很多這些路由器都禁用了 ICMP 並因此它總是停滯不前。
我認為 traceroute 和 uPnP 的組合會奏效。 這就是我打算做的,我只是希望我遺漏了一些明顯的東西。
謝謝大家的評論,所以聽起來我沒有遺漏任何明顯的東西。 我已經開始實施一些 uPnP 以發現網關。
在 Windows 中,您可以只使用以下命令:
ipconfig | findstr /i "Gateway"
這將為您提供如下輸出:
Default Gateway . . . . . . . . . : 192.168.2.1
Default Gateway . . . . . . . . . : ::
但是我無法使用 Java 運行此命令,當我弄清楚這一點時會發布。
您可以查詢網址“ http://whatismyip.com/automation/n09230945.asp ”。 例如:
BufferedReader buffer = null;
try {
URL url = new URL("http://whatismyip.com/automation/n09230945.asp");
InputStreamReader in = new InputStreamReader(url.openStream());
buffer = new BufferedReader(in);
String line = buffer.readLine();
System.out.println(line);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (buffer != null) {
buffer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
您可以使用在 Windows、OSX、Linux 等平台上可用的netstat -rn
命令。 這是我的代碼:
private String getDefaultAddress() {
String defaultAddress = "";
try {
Process result = Runtime.getRuntime().exec("netstat -rn");
BufferedReader output = new BufferedReader(new InputStreamReader(
result.getInputStream()));
String line = output.readLine();
while (line != null) {
if (line.contains("0.0.0.0")) {
StringTokenizer stringTokenizer = new StringTokenizer(line);
stringTokenizer.nextElement(); // first element is 0.0.0.0
stringTokenizer.nextElement(); // second element is 0.0.0.0
defaultAddress = (String) stringTokenizer.nextElement();
break;
}
line = output.readLine();
} // while
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return defaultAddress;
} // getDefaultAddress
我不確定它是否適用於每個系統,但至少在這里我發現了這一點:
import java.net.InetAddress;
import java.net.UnknownHostException;
public class Main
{
public static void main(String[] args)
{
try
{
//Variables to find out the Default Gateway IP(s)
String canonicalHostName = InetAddress.getLocalHost().getCanonicalHostName();
String hostName = InetAddress.getLocalHost().getHostName();
//"subtract" the hostName from the canonicalHostName, +1 due to the "." in there
String defaultGatewayLeftover = canonicalHostName.substring(hostName.length() + 1);
//Info printouts
System.out.println("Info:\nCanonical Host Name: " + canonicalHostName + "\nHost Name: " + hostName + "\nDefault Gateway Leftover: " + defaultGatewayLeftover + "\n");
System.out.println("Default Gateway Addresses:\n" + printAddresses(InetAddress.getAllByName(defaultGatewayLeftover)));
} catch (UnknownHostException e)
{
e.printStackTrace();
}
}
//simple combined string out of the address array
private static String printAddresses(InetAddress[] allByName)
{
if (allByName.length == 0)
{
return "";
} else
{
String str = "";
int i = 0;
while (i < allByName.length - 1)
{
str += allByName[i] + "\n";
i++;
}
return str + allByName[i];
}
}
}
對我來說,這會產生:
Info:
Canonical Host Name: PCK4D-PC.speedport.ip
Host Name: PCK4D-PC
Default Gateway Leftover: speedport.ip
Default Gateway Addresses:
speedport.ip/192.168.2.1
speedport.ip/fe80:0:0:0:0:0:0:1%12
我需要對其他系統/配置/PC 網關設置進行更多測試,以確認它是否適用於所有地方。 有點懷疑,但這是我發現的第一個。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.