【问题标题】:getLocalSocketAddress() and getRemoteSocketAddress() not returning correct valuesgetLocalSocketAddress() 和 getRemoteSocketAddress() 没有返回正确的值
【发布时间】:2013-02-28 07:46:03
【问题描述】:

我首先编写了一个示例 Java 服务器和 Android 客户端。我想跟踪登录到服务器的客户端。在套接字对象中,每个 Android 客户端都有一个唯一的端口号和连接的套接字 IP 地址。因此,这些是用于识别彼此的客户的选项。

我决定不使用每个客户端套接字的端口号,因为为两个 Android 客户端随机选择的端口号可能是相同的数字的可能性很小。机会很小,但有可能。

相反,我决定使用 IP 套接字地址,它是每个客户端套接字中包含的另一串信息。好主意,对吧?没那么快。

要使用的函数有:

在服务器中

   socket.getRemoteSocketAddress()

在客户端

  socket.getLocalSocketAddress()

但是当我使用这些方法时,返回的地址是不一样的。

如果我在客户端的套接字对象上使用 getLocaSocketlAddress() 并将其作为字符串发送到服务器,那么稍后我必须在服务器的套接字连接上使用 getRemoteSocketAddress() 并查看它是否为相同的地址我从客户那里收到一个字符串。这样做是为了识别我从哪个客户端接收到消息。这两个地址不匹配。

例如,客户端通过在客户端的套接字对象上调用getLocalSocketAddress()来获取套接字地址------->将地址作为消息中的字符串发送到服务器----->服务器获取消息并调用getRemoteSocketAddress()在套接字上仅选择要发送回消息的客户端。不是所有其他客户。

服务器将所有连接的客户端的套接字存储在一个ArrayList中。

在客户端的套接字上使用getLocalSocketAddress() 会返回例如XXX.XXX.11.17,如果我在服务器端的套接字中使用getRemoteSocketAddress(),我会得到XXX。 XXX.0.13,这搞砸了,但是如果我在客户端使用getLocalPort(),在服务器使用getPort(),端口号信息完全匹配。

所以我可以使用客户端端口号来可靠地识别向哪个客户端发送消息。

getLocalSocketAddress() 方法有什么问题或者它们坏了?还有另一种方法可以识别哪个客户端已连接到服务器?

在服务器端,Java swing 桌面应用程序

  // desktop connected to the internet by eathernet cable

  socket = serversocket.accept();

    System.out.println("SOCKET ADDRESS: "
    + socket.getRemoteSocketAddress().toString());

在客户端,

   // Android tablet connected to internet by wifi

   public void run() {

       socket = new Socket(InetAddress.getByName(serverIP), 6789);
       socketAddress = (socket.getLocalSocketAddress().toString());

   Log.i(TAG, "SOCKET ADDRESS: " + socketAddress);

【问题讨论】:

  • 顺便说一句,您介意分享有关您用于测试它的网络设置的更多详细信息吗?

标签: java android sockets


【解决方案1】:

出于多种原因,使用 IP 地址跟踪客户通常是个坏主意。

首先,客户端可以通过一些NAT 进行连接——在这种情况下,服务器看到的远程地址与客户端的地址不同。想象一下,例如使用 ADSL/WiFi 路由器进行 NAT 的设置 - 它(很可能)有一个公共 IP 地址,WiFi 设备将使用内部 IP 地址,例如从 10.0.0.x 或 192.168.x.x 池(非常流行的设置)。

请注意,在这样的设置中,多个 WiFi 设备会出现(从服务器的角度来看)从同一个 IP 地址连接 - 路由器的公共 IP。显而易见的含义:客户端的 IP 地址不是唯一的,它是唯一的 IP/端口对。准确的说,TCP连接可以通过(本地IP,本地端口,远程IP,远程端口)元组来唯一标识。

最后但同样重要的是:客户端可以从不同的 IP 地址断开连接并再次连接,这在移动网络中非常常见(实际上在任何动态分配 IP 的网络中)。

在你的问题中你写道:

例如,客户端通过调用 getLocalSocketAddress() 获取套接字地址 在客户端的套接字对象上------->将地址作为字符串发送 向服务器发送消息 -----> 服务器获取消息并调用 套接字上的 getRemoteSocketAddress() 仅选择要发送的客户端 回消息。不是所有其他客户。

我不太明白你所说的只选择那个客户端发送回消息。对于每个连接的客户端,您将有一个单独的 TCP 连接和单独的 Socket 实例。要将数据发送到特定客户端,请使用与该特定客户端关联的套接字,就是这样。你根本不应该关心客户端的IP/端口,真的,这是TCP/IP协议栈的任务。

如果您真的想识别每个连接设备,您必须在应用程序协议中的 TCP/IP 之上进行。您只需在连接后发送一些唯一标识符。但那是完全不同的故事。

【讨论】:

    猜你喜欢
    • 2014-11-26
    • 2017-04-02
    • 2019-03-21
    • 1970-01-01
    • 2014-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多