2010-10-26 29 views
4

我在Linux上看到奇怪的行爲,我發現遠程端和本地端都顯示相同的IP和端口組合。以下是netstat輸出在本地主機上使用相同的IP和端口創建套接字

netstat -anp | grep的6102

TCP 0 0 139.185.44.123:61020 0.0.0.0:* LISTEN 3361/a.out的
TCP 0 0 139.185.44.123:61021 139.185.44.123:61021 ESTABLISHED 3361/a.out的

任何人都可以告訴我這是甚至可能嗎?如果是,那麼情況會是怎樣?

+0

那是奇怪了,從來沒有見過這樣的事。 – Jack 2010-10-26 06:41:54

回答

1

當多線程服務器軟件接受連接時,通常會創建另一個套接字,它在獨立線程中與新連接的客戶端通信,而原始服務器套接字仍在原線程中偵聽新客戶端。在這種情況下,兩個插座的端口是相同的。所以,沒有任何問題。

2

這是一個可以想象的場景。連接的調用者可以在調用連接之前調用綁定。連接的主叫方可以與listen的主叫方合作,並故意綁定到比監聽端口號碼更高的端口號1。

如果內核繼續爲偵聽器重新使用套接字號,我會稱之爲內核錯誤。

0

沒有什麼奇怪的。它有63k的機會發生。你不會看到兩個這樣的ESTABLISHED連接:TCP的規則是不可能的。

+0

爲什麼downvote?上面的錯誤?哪裏?我想我們應該被告知。 – EJP 2010-10-27 11:11:12

1

這是一個有點奇怪的情況,稱爲TCP「主動/主動打開」。一個套接字已被打開,綁定到一個本地端口,然後連接到自己,使用connect()以其自己的地址作爲目的地。

3

連接是由一個4元組標識((源IP,源端口),(目標IP,目標端口)),以及源和目標端口可以令人信服地沒有任何問題是相同的。這個連接甚至可以由一個進程建立,這會導致你看到的輸出。

不過,我只是得到了一個討厭的錯誤,其中一個客戶端套接字將嘗試與端口號的臨時端口範圍連接到服務器套接字在同一臺機器上咬傷。連接操作將重試操作直到成功。

重試功能的問題是:如果服務器應用程序未運行,並且隨機選取的源端口與目標端口相同(這是可能的,因爲目標端口處於臨時範圍內),客戶端套接字將連接到它自己(這對客戶端應用程序的內部邏輯造成嚴重破壞,你可以想象)。

由於客戶端是儘可能快地執行重試,在1 30.000的賠率,這可能發生被擊中的速度不夠快。

以下Python腳本也再現:

import socket 

host = 'localhost' 
port = 35911 

ctr = 0 
while True: 
    try: 
     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     s.settimeout(5) 
     ctr += 1 
     s.connect((host, port)) 
     print "Connected to self after", ctr, "tries" 
     break 
    except socket.error, e: 
     print e 
     # Retry 
+0

完美的例子。非常感謝。在'self.socket.getsockname()== self.socket.getpeername()'上添加重新啓動後,我的程序開始工作更加可預測。 – wibotwi 2013-07-04 18:56:08

相關問題