2016-09-30 281 views
0

我們在設備上使用Linux 2.6.33。將使用PC應用程序通過TCP套接字連接到設備。根據應用程序的要求,最多可以傳輸1 MB的數據。如何突然關閉TCP套接字並重新連接

考慮如果應用程序已連接並正常工作,並且設備的IP地址發生變化(可通過命令執行)。現在,連接在應用程序中突然中斷,但在設備上卻沒有。但用戶期望用新的IP地址重新連接到設備。在某些情況下,「send()」已經過了一半,並且可能沒有發送完所有數據,然後這種關閉不會立即發生,因此用戶將無法重新連接,直到套接字在設備上關閉。

我使用「關閉(襪子,RDWR),接近(襪子)」序列 了netstat輸出顯示:

$ netstat -nt 
Proto Recv-Q Send-Q Local Address   Foreign Address   State 
tcp  0 29200 xx.xx.xx.xx:3000  xx.xx.xx.xx:50639  ESTABLISHED 

因爲它顯示了發送-Q是仍然不爲空,因此該連接仍然處於ESTABLISED狀態這種情況。 socket在一段時間後關閉,我不知道它有多少時間,可以通過套接字實現來定義

如何關閉t他的套接字立即通過PC應用程序可以通過相同的TCP端口進行新的連接?

+0

它是通過完成未決發送所需的時間來定義的,或者如果它們未被確認則中止它們。我不明白'用戶期望重新連接到具有新IP地址的設備'的部分。爲什麼一個新的IP地址? – EJP

+0

由於以太網IP地址被用戶命令更改。現在,用戶需要在IP更改後立即重新啓動應用程序,並重新啓動新的IP地址。 –

+0

如何通過丟棄未完成的Send-Q數據包找出關閉此孤立套接字所需的時間? –

回答

0

關閉套接字總是需要時間,但是您可以使用setsockopt()重新使用同一個端口。在此鏈接上查找更多 detail

0

如何立即關閉此套接字,以便通過 可以從PC應用程序獲得相同的TCP端口的新連接?

您可以通過課程的調用close()關閉它,但你真的想知道的是如何檢測這種情況下,讓你知道什麼時候調用close()。答案是:不容易 - 就您的Linux設備而言,(the_old_ip_address)處的客戶端已停止響應。 Linux設備無法知道這種情況是由於客戶端的IP地址發生了變化,而不是(例如)暫時的網絡中斷,所以Linux設備會在超時前繼續嘗試幾分鐘。

至於解決您遇到的問題,可能最好的方法是設計您的服務器,以便它可以一次接受和服務多個TCP連接。如果你這樣做了,那麼舊的TCP連接會持續幾分鐘就沒有關係,因爲用戶仍然可以立即從他的新IP地址重新連接,並且無需等待就可以恢復工作。

也就是說,另一種方法是將超時添加到您的服務器,以便如果沒有數據在TCP套接字上發送或接收N秒(對於您認爲合適的任何N值),則服務器將明確在套接字上調用close()並偵聽新的傳入連接。然而,這並不是一個很好的解決方案,因爲它假設了TCP連接的性能(也就是說,當它處於「工作」狀態時,它將始終每隔N秒發送或接收數據一次),以及該假設可能並非如此 - 即,如果您的客戶端和服務器不想在一段時間內發送任何內容,或者網絡連接性不夠好,導致數據無法通過超過N秒。風險在於這會導致誤報,導致您的服務器關閉仍然有效的TCP連接。因此,如果可能的話,我建議採用第一種方法而不是這種方法。