2013-02-28 111 views
0

我第一次写了一个示例Java服务器和Android客户端。我想跟踪登录到服务器的客户端。在套接字对象中,每个Android客户端将有一个唯一的端口号和套接字IP地址连接。所以这些是彼此识别客户的选项。getLocalSocketAddress()和getRemoteSocketAddress()不返回正确的值

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

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

要使用的功能是:

服务器

socket.getRemoteSocketAddress() 

,并在客户端

socket.getLocalSocketAddress() 

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

如果我在客户端的套接字对象上使用getLocaSocketlAddress(),并将它作为字符串发送到服务器,那么稍后我必须在服务器的套接字连接上使用getRemoteSocketAddress(),并查看它是否如此我从客户端收到的地址作为字符串。这样做是为了确定我从哪个客户端收到消息。这两个地址不符合他们应有的要求。

实施例,客户机通过在客户端套接字对象调用getLocalSocketAddress()获得套接字地址------->发送地址作为字符串消息发送到服务器----->服务器获取信息以及套接字调用getRemoteSocketAddress()到只选择那个客户端发回消息。并非所有其他客户。

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

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

因此,我可以使用客户端端口号作为可靠地识别哪个客户端发送消息的方式。

getLocalSocketAddress()方法有什么问题或者它们是否被破坏?还有另一种方法可以确定哪个客户端连接到服务器?使用IP地址

在服务器端

,的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); 
+0

顺便说一句,你不介意分享你用它来测试它的网络设置更多的细节? – 2013-02-28 11:27:28

回答

4

跟踪客户端是一般一个坏主意,有几个原因。

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

注意,在这样的设置几个WiFi设备将出现(从服务器的角度),从相同的IP地址连接。明显的含义:客户端的IP地址不是唯一的,它是唯一的IP /端口对。确切地说,TCP连接可以由(本地IP,本地端口,远程IP,远程端口)元组来唯一标识。

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

在你的问题,你写道:

例如,客户端通过调用getLocalSocketAddress() 在客户端Socket对象上获取套接字地址------->发送地址字符串 消息服务器----->服务器获取信息和套接字调用 getRemoteSocketAddress()只选择客户端发送 消息发回。并非所有其他客户。

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

如果你真的想找出每个连接设备,你必须这样做的TCP/IP之上,在应用程序协议。连接后您只需发送一些唯一的标识符。但这完全是另一回事。