2017-02-15 125 views
1

我已經創建了簡單的UDP套接字連接在本地網絡之間發送數據。該連接有兩種類型:對等和組播。下面是我的課: 點對點服務器:UDP套接字無法發送數據包到DHCP地址

public class CandyCaneUdpServer 
{ 
    Socket sck; 
    EndPoint LocalEP; 
    EndPoint RemoteEP; 
    int port = 80; 
    IAsyncResult oldAsyncResult; 

    public event EventHandler<MessageObject> RaiseMessageReceivedEvent; 

    public CandyCaneUdpServer() 
    { 
     sck = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 
     sck.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 
     sck.ExclusiveAddressUse = false; 
     LocalEP = new IPEndPoint(IPAddress.Parse(UdpUtility.GetLocalIP()), port); 
     RemoteEP = new IPEndPoint(IPAddress.Any, port); 
    } 

    public void Serve() 
    { 
     sck.Bind(LocalEP); 
     byte[] _buffer = new byte[1500]; 
     oldAsyncResult = sck.BeginReceiveFrom(_buffer, 0, _buffer.Length, SocketFlags.None, ref RemoteEP, new AsyncCallback(MessageCallBack), _buffer); 
    } 

    private void MessageCallBack(IAsyncResult aResult) 
    { 
     int size = sck.EndReceiveFrom(aResult, ref RemoteEP); 
     if (size > 0) 
     { 
      byte[] receivedData; 
      receivedData = (byte[])aResult.AsyncState; 
      MessageObject obj; 
      IFormatter f = new BinaryFormatter(); 
      using (MemoryStream s = new MemoryStream(receivedData)) 
      { 
       obj = (MessageObject)f.Deserialize(s); 
      } 
      OnRaiseMessageReceivedEvent(obj); 
     } 

     var _buffer = new byte[1500]; 
     oldAsyncResult = sck.BeginReceiveFrom(_buffer, 0, _buffer.Length, SocketFlags.None, ref RemoteEP, new AsyncCallback(MessageCallBack), _buffer); 
    } 

    protected virtual void OnRaiseMessageReceivedEvent(MessageObject e) 
    { 
     EventHandler<MessageObject> handler = RaiseMessageReceivedEvent; 
     if (handler != null) 
     { 
      handler(this, e); 
     } 
    } 
} 

下面是點對點客戶端(發送方):

public class CandyCaneUdpClient 
{ 
    Socket sck; 
    EndPoint RemoteEP; 

    public CandyCaneUdpClient(string RemoteIP, int RemotePort) 
    { 
     sck = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 
     sck.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 
     sck.ExclusiveAddressUse = false; 
     RemoteEP = new IPEndPoint(IPAddress.Parse(RemoteIP), RemotePort); 
    } 

    public void Send(int MessageId, string Message, __MessageObjectType t = __MessageObjectType.P2P) 
    { 
     byte[] msg; 
     msg = Encoding.UTF8.GetBytes(Message); 
     var obj = new MessageObject() 
     { 
      Id = MessageId, 
      Type = t, 
      SourceIP = UdpUtility.GetLocalIP(), 
      TargetIP = ((IPEndPoint)RemoteEP).Address.ToString(), 
      SentTime = DateTime.Now, 
      Message = Message 
     }; 
     IFormatter f = new BinaryFormatter(); 
     using (MemoryStream ms = new MemoryStream()) 
     { 
      f.Serialize(ms, obj); 
      var msgByte = ms.ToArray(); 
      sck.SendTo(msgByte, msgByte.Length, SocketFlags.None, RemoteEP); 
     } 
    } 
} 

的代碼對所有以太網機工作正常。當連接wifi客戶端時,無線PC可以發送數據但不接收數據。當我檢查IP時,以太網客戶端的IP爲192.168.211 .---。而無線PC的IP爲192.168.0 .---。我想知道DHCP地址是否會導致此問題。羣聊功能正常。

public class CandyCaneUdpGroupChatListener 
    { 
     UdpClient listener; 

     IPAddress routerBindIP; 
     readonly int routerBindPort = UdpUtility.GroupChatDefinedPort(); 
     EndPoint routerEP, senderEP; 

     public event EventHandler<MessageObject> RaiseMessageReceivedEvent; 

     public CandyCaneUdpGroupChatListener() 
     { 
      routerBindIP = IPAddress.Parse(UdpUtility.GroupChatRouterBindAddress()); 
      routerEP = new IPEndPoint(routerBindIP, routerBindPort); 
      senderEP = new IPEndPoint(IPAddress.Parse(UdpUtility.GetLocalIP()), routerBindPort); 


      listener = new UdpClient(); 

      listener.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); 

      listener.ExclusiveAddressUse = false; 
      listener.Client.Bind(senderEP); 
      listener.JoinMulticastGroup(routerBindIP); 

      var _buffer = new byte[1500]; 

      listener.Client.BeginReceiveFrom(_buffer, 0, _buffer.Length, SocketFlags.None, ref routerEP, 
       new AsyncCallback(ReceiveMessage), _buffer); 
     } 

     private void ReceiveMessage(IAsyncResult result) 
     { 
      if (listener == null) return; 
      if (listener.Client == null) return; 
      int size = listener.Client.EndReceiveFrom(result, ref routerEP); 

      if (size > 0) 
      { 
       byte[] receivedData; 
       receivedData = (byte[])result.AsyncState; 
       MessageObject obj; 
       IFormatter f = new BinaryFormatter(); 
       using (MemoryStream s = new MemoryStream(receivedData)) 
       { 
        obj = (MessageObject)f.Deserialize(s); 
        //if (obj.SourceIP == UdpUtility.GetLocalIP()) return; 
       } 
       MessageReceived(obj); 
      } 

      var _buffer = new byte[1500]; 
      listener.Client.BeginReceiveFrom(_buffer, 0, _buffer.Length, SocketFlags.None, ref routerEP, 
       new AsyncCallback(ReceiveMessage), _buffer); 
     } 

     protected virtual void MessageReceived(MessageObject e) 
     { 
      EventHandler<MessageObject> handler = this.RaiseMessageReceivedEvent; 
      if (handler != null) 
      { 
       handler(this, e); 
      } 
     } 

     public void Disconnect() 
     { 
      listener.DropMulticastGroup(routerBindIP);   
     } 

    } 

回答

1

查看如何佈置有線和無線網絡子網。看起來你有兩臺不同的DHCP服務器在這裏工作 - 一臺用於有線網絡,另一臺用於無線網絡。

確保您的網絡路由器配置爲使得一個子網上的主機可以與另一個子網上的主機進行通信。

要確定一個子網上的主機是否可以與另一個子網上的主機通信,可以使用網絡跟蹤路由實用程序或ping實用程序。

在Windows上,跟蹤路由實現爲tracert.exe應用程序,您應該在C:\Windows\System32目錄中找到該應用程序。

假設你是以太網連接的客戶端上,你可能會用下面的命令行執行它試圖跟蹤路由到無線PC(假設它有地址192.168.0.104):

C:> \Windows\System32\tracert.exe 192.168.0.104 

您應該看到輸出類似於此:

Tracing route to 192.168.0.104 
over a maximum of 30 hops: 

1 1 ms  1 ms <1 ms 192.168.211.54 
... (possibly other entries her) 
2 1 ms  1 ms  1 ms 192.168.0.104 

Trace complete. 

如果跟蹤未能完成,這是一個表明您的網絡流量不能得到你想跟蹤到機器。

請注意,如果tracert發生故障,它不是100%指示連接失敗。這可能表示ICMP流量正在被防火牆阻止,或者目標機器未響應ICMP請求。

+0

不幸的是,我無法訪問設備。 –

+0

嘗試跟蹤。以太網附加追蹤機結果**請求超時**無線連接的筆記本電腦追蹤成功。我不明白爲什麼連接只能走一個方向。 –

+1

也許這是一個防火牆配置問題。確保在兩臺機器上都打開應用程序通信所需的所有端口。 – STLDeveloper