2014-07-10 78 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