0

我首先编写了一个示例 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);
4

1 回答 1

4

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

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

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

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

在您的问题中,您写道:

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

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

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

于 2013-02-28T09:58:51.237 回答