如何在.NET/C#中查找分配给UDP客户端的端口号?

7
如果我使用 socket() 创建一个套接字
var socket = new UdpClient(0,AddressFamily.InterNetwork);

那么,我如何找到套接字的端口呢?

可能是我太蠢了,但我在MSDN / Google上没有找到信息(可能是因为现在是周五的4:42,阳光明媚)。

背景:

我的目标是找到一个开放的端口,并通知另一个进程在该端口上向我转发消息。由于可能有多个客户端,因此我不想使用固定的端口。

谢谢。

2个回答

17

UdpClient是Socket类的封装,通过LocalEndPoint属性暴露了它绑定到的终结点。由于你正在使用UDP/IP客户端,因此它是一个具有所需Port属性的IPEndPoint:

int port = ((IPEndPoint)socket.Client.LocalEndPoint).Port;

谢谢。我会在周一早上第一时间实现这个。我缺少的是对IPEndPoint的转换,所以智能感知没能帮到我。:( - Charley Rathkopf
该死...从没想过那个...谢谢。:D - Cipi
遗憾的是,在.NET 4.0中,系统从未设置UDP套接字的端口字段。而且由于它是只读属性,您也无法手动设置它。 - Jesse Chisholm
糟糕。我应该说:系统在绑定时不会为RAW UDP套接字设置端口,但是会为DGRAM套接字设置。 - Jesse Chisholm

0

对于那些(像我一样)需要使用原始套接字的人,这里是解决方法。

目标:

  1. 在任意端口上创建一个原始UDP套接字
  2. 了解系统选择的端口号

期望结果:(socket.LocalEndPoint as IPEndPoint).Port

问题:

  • 虽然DGRAM UDP套接字知道它的 (socket.LocalEndPoint as IPEndPoint).Port
  • 但原始UDP套接字总是返回零

解决方案:

  1. 创建一个普通的DGRAM UDP套接字
  2. 绑定该套接字
  3. 找出它的端口号
  4. 关闭该普通套接字
  5. 创建原始UDP套接字

注意事项:

  • 使用修改后的local IPEndPoint变量来知道端口号,因为套接字总是报告零。

代码:

public Socket CreateBoundRawUdpSocket(ref IPEndPoint local)
{
    if (0 == local.port)
    {
        Socket wasted = new Socket(local.AddressFamily,
                                   SocketType.Dgram,
                                   ProtocolType.Udp);
        wasted.Bind(local);
        local.Port = (wasted.LocalEndPoint as IPEndPoint).Port;
        wasted.Close();
    }
    Socket goal = new Socket(local.AddressFamily,
                             SocketType.Raw,
                             ProtocolType.Udp);
    goal.Bind(local);
    return goal;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接