我有兩個監聽套接字(通過呼叫創建socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)),此時它們由一個執行緒維護。
創建后,它們必須被關閉 ( closesocket(...)) 并在相同的埠上再次重新打開。但是bind(...)呼叫在其中一個套接字上回傳錯誤 10048 WSAEADDRINUSE(第二個已成功打開),并且我看到通過使用netstatUDP 埠保持打開狀態(closesocket(...)未回傳錯誤,SO_REUSEADDR在所有套接字上始終設定為 TRUE)。只要第二個套接字打開,這個“關閉”的 UDP 埠就會保持打開狀態(它們沒有關系,但是在第二個套接字關閉后,“關閉”埠會關閉一秒鐘)。
讓我們總結一下:
- 打開套接字并將它們系結到埠 8888 和 9999。
- 關閉 8888 套接字,創建新套接字,將其系結到埠 8888 -> 成功。
- 關閉 9999 套接字,創建新套接字,并嘗試將其系結到埠 9999 -> 錯誤
WSAEADDRINUSE。 - 關閉 8888 套接字 -> 成功。
- 在#4 之后大約一秒鐘后,埠 9999 被釋放(通過在外部工具中觀察)。
我發現了與我的問題類似的東西:https ://stackoverflow.com/a/26129726/10101917 ,但在我的情況下,將所有套接字操作移動到一個執行緒并不能解決問題。
這里發生了什么?
uj5u.com熱心網友回復:
我找到了導致這個問題的原因。我編程的東西是DLL。我發現,這個應用程式的另一個 DLL 正在使用 Qt 庫版本 5.7.1 的 QProcess 類。我檢查了 Qt 的來源,發現這個類實際上啟動了 bInheritHandles 設定為 TRUE 的行程。當我手動將此值重置為 FALSE 時,所有問題都消失了。
很明顯,問題是由以下原因引起的:子行程繼承了一個 UDP 套接字句柄,并且該行程沒有讓套接字句柄關閉,直到該行程停止。
感謝此評論指出解決方案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/532383.html
標籤:C 视窗插座UDP
