UDP套接字无法将数据包发送到DHCP地址

时间:2017-02-15 03:38:12

标签: c# sockets dhcp udpclient

我创建了简单的UDP套接字连接,以便在本地网络之间发送数据。连接有两种类型:对等和组广播。以下是我的课程: 点对点服务器:

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客户端时,无线电脑可以发送数据但不能接收数据。当我检查IP时,以太网客户端的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 个答案:

答案 0 :(得分: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请求。