2014-10-31 52 views
0

在C#,.Net 4中,我需要在端口上發送UDP消息並在同一個端口上偵聽響應。UDP客戶端太晚分配空閒端口

我使用的是固定端口,但客戶遇到了問題,所以我想使用任何可用的端口。似乎我可以通過爲端口號使用0來做到這一點,但它不起作用。再深入探討一下,它似乎並沒有在實際使用前分配端口,所以我的兩個綁定語句可能會轉到不同的端口。

從MSDN:

「如果你不關心它的本地端口使用時,可以使用0的端口號創建 IPEndPoint在這種情況下,服務 提供商將分配可用。端口號在1024和5000之間。 如果使用上述方法,您可以通過調用 LocalEndPoint來發現本地網絡 地址和端口號已被分配...如果使用的是無連接協議,則您的 不會有權訪問此信息,直到您完成發送 r收到。「

問題是,我想設置我的發送和接收初始化。如果我等到第一次發送來設置接收,我可能會錯過一些響應。有沒有比發送垃圾郵件分配端口更好的答案,以便我可以完成初始化?

我的代碼:

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; 
     } 
    } 

感謝

回答

2

兩個選項:

  1. 創建包含端口號的配置文件。初始化時,讀取配置文件並在設置客戶端時使用該端口號。提供具有默認端口號的配置文件,並根據需要向客戶提供有關如何更改它的說明。
  2. 在初始化過程中,創建一個接收器,給它一個非常短的接收超時值,並致電Receive。這將導致端口綁定。然後,您可以獲取本地終點,並在創建發件人時使用該終點。有關設置接收超時的信息,請參閱Can I set the timeout for UdpClient in C#?
+0

好主意,但我試過#2,它仍然回來後開始/結束接收由於某種原因後端口0 ... – 2014-10-31 16:30:52

+0

好吧..得到它 - localep沒有改變,但我可以得到該端口通過使用listener.Client.LocalEndPoint。謝謝。 – 2014-10-31 16:39:15