2014-07-10 124 views
1

我已經創建了一個服務器應用程序,爲其客戶端動態打開端口。我現在使用一個綁定到端口0的套接字,所以我得到一個隨機分配的端口。這工作正常,但缺點是我需要打開防火牆的所有端口進行此過程。限制動態IP端口範圍

我寧願將範圍限制在40000-41000之間,並在此範圍內選取隨機端口。有沒有一種方法讓OS在這個範圍內選擇一個自由端口?

對於cource,我可以在這個範圍內自己挑選一個端口,如果它是免費的,那就使用它。否則,嘗試另一個端口,直到我們找到一個空閒端口。我不認爲這是一個很好的解決方案。我可以註冊自己的端口,但其他服務也可以預留此範圍內的端口。

任何人的解決方案?我使用定製的C#4.5服務器工作在Windows Server 2008 R2系統上。

+0

你怎麼能指望客戶端在正確的端口號猜? –

+0

我有一個設置端口轉發的命令,它用主機名和端口號響應(它已經以這種方式工作)。然後請求者可以連接到端點來做任何想做的事情。無需猜測:-) –

+0

如果您使用的是Windows防火牆,則可以將其配置爲允許基於應用程序而不是端口號進行訪問。這似乎是一個更簡單的解決方案。 –

回答

1

IPGlobalProperties可以給你當前繁忙的端口。這裏有一種方法可以做到這一點:

// Returns available port number or zero if no port is available 
public static int GetFirstAvailableRandomPort (int startPort, int stopPort) 
{ 
    Random r = new Random() ; 

    IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties(); 
    TcpConnectionInformation[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections(); 

    var busyPorts = tcpConnInfoArray.Select(t => t.LocalEndPoint.Port).Where(v => v >= startPort&& v <= stopPort).ToArray() ; 

    var firstAvailableRandomPort = Enumerable.Range(startPort, stopPort - startPort).OrderBy(v => r.Next()).FirstOrDefault(p => !busyPorts .Contains(p)) 

    return firstAvailableRandomPort ; 
} 

使用

var randomPort = GetFirstAvailableRandomPort(40000, 41000) ; 
+1

我不知道那個班,但它會完成這項工作。我需要一些鎖定,因爲多個線程可能同時請求一個端口。 –

+0

如果您的端口範圍與操作系統使用的動態/暫時端口範圍重疊,則這似乎與其他進程/軟件有競爭狀態。您可以選擇端口號,並在您進行綁定時可以使用該端口號。 – Cameron