看來這個話題對其他人來說也很有趣,所以我描述了我目前的解決方案。
- 軟件做一個檢測的IPv6是否工作並記住狀態 - >這是做一個TCP連接到已知的IPv6地址來實現(isReachable平安()是不可靠的,看到這個錯誤報告: https://josm.openstreetmap.de/ticket/11452)。
- 基於記憶狀態,軟件以「java.net.preferIPv6Addresses」設置爲「true」開始。
- 這意味着從IPv4切換到IPv6網絡時,它將使用IPv4,直到下次重新啓動爲止。
- 對於從支持IPv6的網絡切換到僅支持IPv4的網絡,根本無法通過重新啓動軟件解決。
- 如有疑問,我們假設IPv6不起作用。
- 檢測後無法更改「java.net.preferIPv6Addresses」,因爲這些值似乎只能在第一次網絡連接之前讀取。如果有在運行時重置該狀態的方法,我想知道它。
這個解決方案似乎有效,我們在日誌ATM中有大約4%的IPv6連接,但這不是一個令人滿意的解決方案。
/**
* Check if IPv6 can be safely enabled and do so. Because this cannot be done after network activation,
* disabling or enabling IPV6 may only be done with next start.
*/
private static void checkIPv6() {
if ("auto".equals(Main.pref.get("prefer.ipv6", "auto"))) {
new Thread(new Runnable() { /* this may take some time (DNS, Connect) */
public void run() {
boolean hasv6 = false;
boolean wasv6 = Main.pref.getBoolean("validated.ipv6", false);
try {
/* Use the check result from last run of the software, as after the test, value
changes have no effect anymore */
if (wasv6) {
Utils.updateSystemProperty("java.net.preferIPv6Addresses", "true");
}
for (InetAddress a : InetAddress.getAllByName("josm.openstreetmap.de")) {
if (a instanceof Inet6Address) {
if (a.isReachable(1000)) {
/* be sure it REALLY works */
Socket s = new Socket();
s.connect(new InetSocketAddress(a, 80), 1000);
s.close();
Utils.updateSystemProperty("java.net.preferIPv6Addresses", "true");
if (!wasv6) {
Main.info(tr("Detected useable IPv6 network, prefering IPv6 over IPv4 after next restart."));
} else {
Main.info(tr("Detected useable IPv6 network, prefering IPv6 over IPv4."));
}
hasv6 = true;
}
break; /* we're done */
}
}
} catch (IOException | SecurityException e) {
if (Main.isDebugEnabled()) {
Main.debug("Exception while checking IPv6 connectivity: "+e);
}
}
if (wasv6 && !hasv6) {
Main.info(tr("Detected no useable IPv6 network, prefering IPv4 over IPv6 after next restart."));
Main.pref.put("validated.ipv6", hasv6); // be sure it is stored before the restart!
new RestartAction().actionPerformed(null);
}
Main.pref.put("validated.ipv6", hasv6);
}
}, "IPv6-checker").start();
}
}
Java對於完全有效的系統也是失敗的,其中IPV6僅用於本地,因爲這些系統使用IPv6,而系統本身知道它沒有IPv6連接。你的建議根本沒有幫助。首先,我無法修復我們用戶的所有安裝。其次,我不知道如何取代Java中完整的網絡處理。我需要一個真實世界的解決方案,而不僅僅是學術上的興趣。 – 2013-04-24 07:52:51
對不起。如果是其他語言,我可以給你大量的示例代碼。不過,這是你應該走的方向。 – 2013-04-24 14:58:47
你誤解了複雜性。這個軟件沒有一個地方可以訪問網絡。可能有數百個不同的職位,其中一些職位隱藏在Java系統的深處。因此,爲了讓您的建議成立,必須有可能立即替換整個網絡連接處理。我認爲這不是一件容易的事(但也許有人知道一種方式)。目前,我們遇到的問題是向正在發佈的所有HTTP連接添加正確的用戶代理(對於其中一些而言沒有問題,但對所有人來說都很難)。 – 2013-04-24 15:11:24