2009-07-02 28 views
38

我需要一個將UDP數據包發送到某個網絡服務器並接收響應的應用程序。服務器回覆相同的請求來自的端口號,所以我首先需要綁定()我的套接字到任何UDP端口號。如何綁定到任何可用的端口?

硬編碼的UDP端口號是一個壞主意,因爲它可能是由同一臺PC上運行的任何其他應用程序使用。

是否有可用的綁定的UDP套接字任何端口的方法是什麼? IMO應該是快速獲得空閒端口#的有效方式,該空閒端口被例如accept()函數。

如果不是,那麼嘗試綁定並檢查WSAEADDRINUSE/EADDRINUSE狀態的最佳策略是:從1025或1025 + rand()或其他某個端口順序嘗試端口?

+1

accept()用於基於連接的套接字,而不是數據報套接字。 – Beano

+1

也許這將有助於:http://serverfault.com/questions/447044 – yegor256

+0

在POSIX?還要求範圍1024+:http://stackoverflow.com/questions/913501/how-to-let-kernel-choose-a-port-number-in-the-range-1024-5000-in-tcp-socket- pr –

回答

34

呼叫sendto沒有調用bind第一,插座會自動綁定(自由港)。

+5

Downvoting只是因爲正確的答案應該是@ Remy的一個(使用綁定中的端口0)。 – claf

+4

@claf隱式綁定也綁定,不是嗎?在我看來,這兩個答案都很有用。 – WGH

+0

@WGH:你是對的,這種行爲記錄的針對Windows套接字(注:如果一個套接字被打開,一個setsockopt調用製成,然後sendto調用製成,Windows套接字執行隱綁定函數調用),但我我不確定這是其他實現的情況。此外,我對隱性呼叫的看法是,這是一個壞習慣。 – claf

0

我必須失去了一些東西,你爲什麼不使用UDP套接字發回的數據? 從sendto開始,然後使用recvfrom函數讀取傳入數據,您也可以從中獲取數據發送地址的獎勵,在那裏您可以發送迴應。

+0

有些協議要求您關心您使用的端口號。例如,[TFTP](http://tools.ietf.org/html/rfc1350)客戶端使用它來區分來自同一服務器的多個併發傳輸。服務器不能從同一端口發回,每個文件傳輸都需要服務器從不同的源端口發送。正如你所概述的那樣,服務器確實會回覆客戶端的源地址和端口。 – doug65536

+1

在我的具體例子中,爲每個傳輸使用一個新的套接字,然後盲目地執行'sendto'會隱式地選擇一個源端口,但是在你實際執行sendto之前,可能會有其他協議關心端口號。 。 – doug65536

+0

@ doug65536這是一個有效的例子,但原來的問題沒有包含任何具體細節的原因。 – Jonke

168

另一種選擇是指定端口0至bind()。這將允許你綁定到一個特定的IP地址(如果你有安裝多個),同時仍綁定到一個隨機端口。如果您需要知道選擇了哪個端口,則可以在執行綁定後使用getsockname()

+18

綁定到端口0是官方記錄的綁定到操作系統分配的隨機端口的方式。 –

+0

記錄在哪裏?我不是說這是錯誤的,我想看到一個權威性的聲明。 –

+8

它在['bind()'](http://msdn.microsoft.com/en-us/library/windows/desktop/ms737550.aspx)文檔中:「如果端口被指定爲零,則服務提供程序從動態客戶端端口範圍爲應用程序分配一個唯一端口在Windows Vista和更高版本上,動態客戶端端口範圍是一個介於49152和65535之間的值。這是從Windows Server 2003和更早版本開始的一個變化,是1025到5000之間的值......應用程序可以在調用bind之後使用getsockname來了解已分配給套接字的地址和端口。「 –

相關問題