2013-02-28 110 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之上,在應用程序協議。連接後您只需發送一些唯一的標識符。但這完全是另一回事。