UDP客户端分配空闲端口太晚了

时间:2014-10-31 15:57:47

标签: c# sockets udp udpclient

在C#,。Net 4中,我需要在端口上发送UDP消息并在同一端口上侦听响应。

我使用的是固定端口,但客户遇到了问题,所以我想使用任何可用的端口。似乎我可以通过使用0作为端口号来做到这一点,但它不起作用。再深入研究一下,看起来在实际使用之前它并没有分配端口,所以我的两个绑定语句可能会转到不同的端口。

来自MSDN:

  

"如果您不关心使用哪个本地端口,您可以创建一个   IPEndPoint使用0作为端口号。在这种情况下,服务   提供商将分配1024到5000之间的可用端口号。   如果您使用上述方法,您可以发现什么是本地网络   地址和端口号已通过调用分配   LocalEndPoint。 ...如果您使用的是无连接协议,那么   在您完成之前,我们将无法访问此信息   发送或接收。"

麻烦的是,我想在初始化时设置我的发送和接收。如果我等到第一次发送设置接收,我可能会错过一些回复。有没有比发送垃圾信息来分配端口更好的答案,所以我可以完成初始化?

我的代码:

    public bool InitializeSockets()
    {
        try
        {
            IPAddress localaddr = LocalIPAddress();
            localep = new IPEndPoint(localaddr, 0);  //(was port 50000);


            //-----------------------------------------------------------------
            // set up listener port for responses coming back on the same port
            //-----------------------------------------------------------------
            listener = new UdpClient();
            listener.ExclusiveAddressUse = false;
            listener.Client.SetSocketOption(SocketOptionLevel.Socket,
                SocketOptionName.ReuseAddress, true);
            listener.Client.Bind(localep);

            detailsOutputText = "Ready to listen on " + localep;

            ustate = new UdpState();
            ustate.e = localep;
            ustate.u = listener;

            //------------------------
            // set up broadcast port
            //------------------------
            bcast = new UdpClient();
            bcast.Client.SetSocketOption(SocketOptionLevel.Socket,
                SocketOptionName.ReuseAddress, true);
            bcast.Client.Bind(localep);

            //-------------------------------
            // start listening for responses
            //-------------------------------
            msgRxCallback = listener.BeginReceive(new AsyncCallback(DiscoveryCallback), ustate);

            return true;
        }
        catch (Exception exc)
        {
            if (exc is SocketException)
            {
                // This only catches if another process has opened that port without sharing it
                // or if firewall blocks it?
                MessageBox.Show("Error opening IP address:Port : " + localep;
            }
            else
                MessageBox.Show(exc.ToString());
            return false;
        }
    }

由于

1 个答案:

答案 0 :(得分:2)

两个选项:

  1. 创建包含端口号的配置文件。初始化时,请在设置客户端时读取配置文件并使用该端口号。提供带有默认端口号的配置文件,并在需要时向客户提供有关如何更改它的说明。
  2. 在初始化时,创建一个接收器,给它一个非常短的接收超时,然后调用Receive。这将导致端口绑定。然后,您可以获取本地端点,并在创建发件人时使用该端点。有关设置接收超时的信息,请参阅Can I set the timeout for UdpClient in C#?
相关问题