我正在開發C++中的RTSP源代碼過濾器,並且使用WINSOCK 2.0 - 阻塞套接字。WINSOCK - 在不存在的IP上設置連接嘗試超時?
當我創建一個阻塞套接字,我設置其SO_RCVTIMEO
至3秒,像這樣:
int ReceiveTimeout = 3000;
int e = setsockopt(Socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&ReceiveTimeout, sizeof(int));
我的過濾器試圖連接到IP_ADDRESS:554
(554 RTSP服務器端口)。如果有一個服務器偵聽的端口554上IP,一切順利,但是:
如果我的過濾器創建一個套接字到現有IP地址,但一個隨機端口上沒人聽
connect()
等待3秒鐘並返回WSAETIMEDOUT
。所以3秒後,我知道提供的URL是不好的。如果我的過濾器創建一個套接字到不存在的IP地址,並嘗試連接,它返回SOCKET_ERROR前掛機約10秒。因此,如果IP不存在網絡上
SO_RCVTIMEO
被忽略......
問題: 如何設置超時爲不存在的IP,在第二種情況下?我是否需要首先發送ICMP PING來查看IP是否存在,或者執行其他類似的檢查?
任何幫助將不勝感激。 Thanx。 :)
我的問題的答案
因爲我使用的是阻塞插座,來電connect()
塊,直到建立連接,或者因爲主機沒有響應連接失敗,或者被拒絕連接。如果我將套接字的超時設置爲3秒,並嘗試連接到一個不存在的主機,我的電腦(客戶端)將發送帶有SYN
標誌的TCP數據包,啓動三通握手。通常情況下,主機如果啓用,將使用包含ACK
和SYN
標誌集的TCP數據包進行響應,然後客戶機(我)將發送標記爲ACK
的TCP數據包。然後建立連接。但是如果主機關閉,並且發送了SYN
,則客戶端會等到3秒超時過期,然後再次嘗試重新嘗試,直到達到TcpMaxConnectRetransmissions
(MICROSOFT ARTICLE)註冊表設置爲止,因爲主機可以處於UP狀態,但是SYN
數據包可能會丟失...我的Windows XP的設置爲4,我猜,所以每次嘗試發送SYN
時,它會等待3秒,當第四次嘗試失敗時,它會返回SOCKET_ERROR
(12秒後),並且將WSAETIMEDOUT
設置爲最後一次WSA錯誤。
解決方法是使用非阻塞套接字,並嘗試手動測量連接嘗試時間(因爲現在connect()
不會像Martin James所建議的那樣)。
另一種方法是使用註冊表,這是不得已而爲之撥弄......
這是在Windows或控制檯應用程序?這個問題很重要,因爲它讓我知道你可以使用的wsapi中的哪些工具。 – johnathon 2011-06-01 12:23:47
它是一個DirectShow推送源過濾器,DLL庫。 – Cipi 2011-06-01 12:29:28