2017-02-15 18 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); 
     } 
    } 
} 

код работает отлично подходит для всех эфирных внутрисетевых машин. Когда Wi-Fi-клиент подключен, беспроводной ПК может отправлять данные, но не принимать данные. Когда я проверяю IP, у ether-net-клиента есть IP-адрес 192.168.211 .---. в то время как беспроводной ПК имеет 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.

Предположим, что вы на стороне клиента Ethernet подключением, можно выполнить с помощью следующей командной строки, чтобы попытаться проследить маршрут к беспроводной ПК (предположим, он имеет адрес 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

Пробовал трассировки. Результаты подключенной трассирующей машины Ether-net ** Запрошенный временной интервал ** при успешном отслеживании с беспроводного подключенного ноутбука. Я не понимаю, почему соединение может идти только в одном направлении. –

+1

Возможно, это проблема конфигурации брандмауэра. Убедитесь, что все порты, необходимые для связи с вашим приложением, открыты на обеих машинах. – STLDeveloper