Socket socket = new Socket(ip,port);
如果ip是IPV4,则可以成功连接,但如果ip是ipv6,则会出现如下异常
java.net.ConnectException:failed to connect to /fe80::c64:5cff:feb5:8787 (port 9555) from /::(port): connect failed:EINVAL(Invalid argument)
Android模拟器版本是API级别28。
您可能需要指定
scope_id
(网络接口),这在 Inet6Address Android 文档中进行了描述。
这是类似的问题,可能会帮助您了解如何做到这一点的实施细节: Android 上的 IPv6 套接字
在我的测试中,与使用 java/kotlin 的主机相比,模拟器与 IPv6 地址的连接工作方式相同。如果您使用的参数似乎被用作错误消息 ip="/fe80::c64:5cff:feb5",则必须删除“/”。它是纯主机名,如“google.com”或纯 IPv6 地址“2a00:1450:4026:804::200e”。
但是 IPv6 连接无法从外部连接到模拟器,并且没有说明如何执行此操作。似乎模拟器只获得虚假的 IPv6 地址,无法从主机到模拟器进行 ping 操作。
https://developer.android.com/studio/run/emulator-networking
我将添加我对正在发生的事情的想法:
模拟器运行时,不会连接到开发者网络。它将自身与该网络环境隔离。在内部,它使用虚拟路由器和 DNS 来保持自身隔离。就我而言,我的开发者网络使用 192.168.50.0/24,而 Android 模拟器使用 10.0.2.0/8。
我无法从外部 ping 通模拟器的 ipv4 或 ipv6 地址。这是因为来自外界的 ping 命令与 android 模拟器网络是隔离的。不过,我可以使用“adb”向模拟器 ipv4 地址发出“ping”命令。同样,我可以使用“adb”发出“ping6”命令来 ping 模拟器的 ipv6 地址。当使用“adb”时,两个 ping 命令都可以工作。请注意,您可能会注意到与模拟器关联的多个 IPV6 地址。我注意到并非所有这些 IPV6 地址都是可 ping 通的。我不太清楚为什么,但我也不确定所有这些 ipv6 地址的用途。我查看了所有这些地址的详细 InetAddress。如果 IPV6 地址为“本地链接”,我无法对其执行 ping 操作。我无法 ping “辅助”或“临时”IPv6 地址,除非它也启用了“DAD”。这些只是观察结果,与必然的因果关系无关。
回到最初的问题,Lee 说他可以在套接字命令中使用 ipV4 地址,并且它可以工作。不幸的是,我们不知道他使用的是全局还是链接本地 ipv4 和 ipv6 地址。所以 Janis B 所说的可能是正确的。我注意到,当我使用“-a”选项执行 ping 和 ping6 命令时,我得到了 ipv4 地址的名称,而不是 ipv6 地址的名称。这种可能性表明,原因可能与模拟器内部 DNS 的工作方式有关。如果我没记错的话,我很确定我可以在模拟器上的 WebView 开发环境中使用 ipV4 地址,并且它可以工作。我从未尝试过使用 ipv6 地址访问该网站。如果它不起作用,这将类似于 Lee 所观察到的情况,但使用 WebView 而不是套接字。将来某个时候我会尝试一下。