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

标签 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客户端后,无线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);           
        }

    }

最佳答案

查看如何布置有线和无线网络子网。看来您在这里有两台不同的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请求。

关于c# - UDP套接字无法将数据包发送到DHCP地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42240268/

相关文章:

c# - SonarQube VSTS Task 版本 3.0.1 是否无法支持多种 msbuild 类型?

java - 在 Sockets 和 ServerSockets 之间发送和接收信息

c# - 是否可以通过 API 调用知道有多少未处理的已完成操作在 IOCP 上排队?

linux - 如何使用 connman 为 wifi 网络设置静态 IP 地址

nginx - Kubernetes MetalLB 外部 IP 无法访问

c# - 如何在c#中使用线程池和互斥锁?

c# - 在包含其他控件的 C# UserControl 中重写 OnPaint 和抓取鼠标事件的问题

c# - 如何知道反序列化类的类型?(或对象)

java - 无阻塞读写java套接字

vagrant - 有没有办法使用 Virtualbox 由 DHCP 分配的 VagrantFile 中的 IP 地址?