当前位置:  开发笔记 > 编程语言 > 正文

在.Net中查找下一个TCP端口

如何解决《在.Net中查找下一个TCP端口》经验,为你挑选了5个好方法。

我想为WCF服务调用创建一个新的net.tcp:// localhost:x/Service端点,并使用动态分配的新的open tcp端口.

我知道当我打开与给定服务器的连接时,TcpClient将分配一个新的客户端端口.

有没有一种简单的方法可以在.Net中找到下一个打开的TCP端口?

我需要实际的数字,以便我可以构建上面的字符串,0不起作用,因为我需要将该字符串传递给另一个进程,以便我可以回调该新的通道.



1> TheSeeker..:

这是我在寻找的东西:

static int FreeTcpPort()
{
  TcpListener l = new TcpListener(IPAddress.Loopback, 0);
  l.Start();
  int port = ((IPEndPoint)l.LocalEndpoint).Port;
  l.Stop();
  return port;
}


如果另一个进程在重新打开之前打开该端口会发生什么?
我成功地使用这种技术获得了一个免费端口.我也担心竞争条件,其他一些进程潜入并抓住最近被发现的自由端口.所以我在`var port = FreeTcpPort()`之间用强制`Sleep(100)`编写了一个测试,并在自由端口上启动了一个HttpListener.然后我在循环中运行了8个相同的过程.我永远不会遇到比赛的情况.我的轶事证据(Win 7)是操作系统显然是在短暂的端口(几千个)之间循环再次出现之前.所以上面的片段应该没问题.
然后你会得到一个错误,但这不是我的上下文的问题.
如果我理解这是如何正常工作的,你不能这样做:`TcpListener myActualServer = new TcpListener(ipAddress,0); myActualServer.Start(); return((IPEndPoint)myActualServer.LocalEndpoint).Port;`或者OP在实际启动监听器之前获取端口是否重要?

2> Jerub..:

使用端口号0. TCP堆栈将分配下一个空闲的堆栈.


这不起作用,因为我需要实际的#,而不仅仅是0.我需要数字来构建一个字符串.

3> jan.vdbergh..:

首先打开端口,然后将正确的端口号提供给另一个进程.

否则,某些其他进程仍然可能首先打开端口,但您仍然有另一个进程.



4> Eric Boumend..:

该解决方案可与TheSeeker的公认答案相媲美。虽然我认为它更具可读性:

using System;
using System.Net;
using System.Net.Sockets;

    private static readonly IPEndPoint DefaultLoopbackEndpoint = new IPEndPoint(IPAddress.Loopback, port: 0);

    public static int GetAvailablePort()
    {
        using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
        {
            socket.Bind(DefaultLoopbackEndpoint);
            return ((IPEndPoint)socket.LocalEndPoint).Port;
        }
    }



5> zumalifeguar..:

如果您只想提供一个起始端口,并让它返回下一个可用的TCP端口,请使用如下代码:

public static int GetAvailablePort(int startingPort)
{
    var portArray = new List();

    var properties = IPGlobalProperties.GetIPGlobalProperties();

    // Ignore active connections
    var connections = properties.GetActiveTcpConnections();
    portArray.AddRange(from n in connections
                        where n.LocalEndPoint.Port >= startingPort
                        select n.LocalEndPoint.Port);

    // Ignore active tcp listners
    var endPoints = properties.GetActiveTcpListeners();
    portArray.AddRange(from n in endPoints
                        where n.Port >= startingPort
                        select n.Port);

    // Ignore active UDP listeners
    endPoints = properties.GetActiveUdpListeners();
    portArray.AddRange(from n in endPoints
                        where n.Port >= startingPort
                        select n.Port);

    portArray.Sort();

    for (var i = startingPort; i < UInt16.MaxValue; i++)
        if (!portArray.Contains(i))
            return i;

    return 0;
}

推荐阅读
可爱的天使keven_464
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有