【问题标题】:UDP socket unable to send packet to DHCP addressUDP 套接字无法将数据包发送到 DHCP 地址
【发布时间】:2017-02-15 03:38:12
【问题描述】:

我创建了简单的 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客户端后,无线pc可以发送数据但不能接收数据。当我检查 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);           
        }

    }

【问题讨论】:

    标签: c# sockets dhcp udpclient


    【解决方案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 请求。

    【讨论】:

    • 很遗憾,我无法访问设备。
    • 尝试过追踪。以太网连接的跟踪机结果 Request Timed Out,而从无线连接的笔记本电脑进行跟踪是成功的。我不明白为什么连接只能去一个方向。
    • 这可能是防火墙配置问题。确保您的应用程序通信所需的所有端口在两台机器上均已打开。
    猜你喜欢
    • 1970-01-01
    • 2014-05-08
    • 1970-01-01
    • 2010-11-13
    • 2015-11-26
    • 2020-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多