【问题标题】:UDP Socket receives packets from one IP Address while it ignores othersUDP Socket 从一个 IP 地址接收数据包,而忽略其他 IP 地址
【发布时间】:2018-12-16 15:35:31
【问题描述】:

我遇到了一个问题,我在端口 49473 上打开了一个 UDP 套接字,而一个 IP 地址被识别,另一个未被识别。我在来自 18.x.x.x 和 24.x.x.x 的 wireshark 数据包中看到只有 18.x.x.x 数据包被读取。任何想法可能会发生什么? (旁注 18.x.x.x 没有被遍历,但 24.x.x.x 不确定这是否会有所不同。)我还尝试将缓冲区从 8192 增加到 150k,但没有帮助。缓冲区没有丢弃数据包,所以不幸的是......

来自wireshark的图片点击到enlarge

    public UdpSocket(int port = 0)
    {
        sw.Start();

        _buffer.Client = this;

        if (port != 0)
            _buffer.IsHost = true;

        _discovery = new Discovery(_buffer);
        _buffer.NatOp = new NatOperation(_buffer, _buffer.IsHost);

        _endPoint = new IPEndPoint(IPAddress.Any, port);
        _buffer.Stream = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        _buffer.Stream.ReceiveBufferSize = 8192;
        _buffer.Stream.SendBufferSize = 8192;
        _buffer.Stream.EnableBroadcast = true;

        //***********Magic Fairy Dust*************
        uint IOC_IN = 0x80000000;
        uint IOC_VENDOR = 0x18000000;
        uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;
        _buffer.Stream.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null);
        //*********** Fairy Dust End *************

        _buffer.Stream.Bind(_endPoint);

        Thread receive = new Thread(ReceiveUdp);
        Thread send = new Thread(SendThread);

        receive.IsBackground = true;
        send.IsBackground = true;

        receive.Start();
        send.Start();
    }

    private void ReceiveUdp()
    {
        while (IsRunning)
        {
            try
            {
                Packet packet = _buffer.CreatePacket();
                EndPoint _ep = new IPEndPoint(IPAddress.Any, 0);
                count = _buffer.Stream.ReceiveFrom(data, 1024, SocketFlags.None, ref _ep);

                if (((IPEndPoint)_ep).Address.ToString() != "18.x.x.x")
                    Console.WriteLine("Foreign Address Connection " + packet.RemoteEp.Address.ToString()); //never returns so 18.x.x.x only processing 

                packet.Data.MirrorData(count, data);
                packet.RemoteEp = _ep as IPEndPoint;

                packet.ReadHeader();

                lock (_inProcess)
                    _inProcess.Enqueue(packet);
            }
            catch { }
        }
    }

对于阅读此 SendTo 和 ReceiveFrom 创建 ICMP 响应的任何人,魔法仙尘会禁用它,此解决方案仅适用于 Windows / Linux。 我也接受了 SocketOptions IP unrestricted 为正确的。在我的情况下 Socket.Connect 是问题,当你这样做时,它只允许该 ip 进行传输。

【问题讨论】:

  • 你应该使用 recv() 而不是 recvFrom() 吗?
  • @PaulHK recv() 不包括端点,我使用 recvFrom() 来包括发件人端点以供以后使用。
  • @PaulHK 你不能在未连接的 UDP 套接字上使用 recv()
  • 请允许我附上source of the Magic Fairy Dust

标签: c# sockets networking udp


【解决方案1】:

这可能是与 NAT 相关的问题。试试看

_buffer.Stream.SetIPProtectionLevel(IPProtectionLevel.Unrestricted);

Bind 之前或之后。 UDPClient 正是通过 AllowNatTraversal 方法实现的。

或者这可能是与防火墙/AV 相关的问题。暂时关闭它们并尝试一下。

【讨论】:

  • 不幸的是 .net 3.5 没有 SetIPProtectionLevel 但是我在 4.0 中看到了该选项。我关闭了PC上的防火墙同样的问题。我正在研究 SetIPProtectionLevel 的想法,以检查 3.5 是否有类似的东西。 -莱文
  • 我接受你的回答是正确的,因为如果有人偶然发现它可能会有所帮助。在我的情况下 Socket.Connect 是问题,当你这样做时,它只允许该 ip 向所有其他 ip 发出请求将被忽略 - Levon
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-30
  • 1970-01-01
相关资源
最近更新 更多