UDP Socket получает пакеты с одного IP-адреса, игнорируя другие.

У меня проблема. У меня открыт сокет UDP на порту 49473, в то время как один IP-адрес распознается, другой - нет. Я вижу в wireshark пакеты, поступающие от 18.x.x.x и 24.x.x.x, читаются только пакеты 18.x.x.x. Есть идеи, что может происходить? (Примечание 18.x.x.x не пройдено, но 24.x.x.x не уверен, имеет ли это значение..) Также я пытался увеличить буфер с 8192 до 150 КБ, это не помогло. Буфер не отбрасывает пакеты, так что, к сожалению, они отсутствуют.

Изображение из wireshark. Нажмите, чтобы увеличить

    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. Также я принял неограниченный IP-адрес SocketOptions как правильный. В моем случае Socket.Connect был проблемой, когда вы делаете это, он позволяет только этому IP-адресу выполнять передачи.


person Levon Ravel    schedule 09.07.2018    source источник
comment
Следует ли вам использовать recv() вместо recvFrom()?   -  person PaulHK    schedule 09.07.2018
comment
@PaulHK recv() не включает конечную точку, я использую recvFrom(), чтобы включить конечную точку отправителя для последующего использования.   -  person Levon Ravel    schedule 09.07.2018
comment
@PaulHK Вы не можете использовать recv() в неподключенном сокете UDP.   -  person user207421    schedule 10.07.2018
comment
Позвольте мне прикрепить источник Magic Fairy Dust   -  person Lies    schedule 28.12.2020


Ответы (1)


Это может быть проблема, связанная с NAT. Попробуй

_buffer.Stream.SetIPProtectionLevel(IPProtectionLevel.Unrestricted);

до или сразу после Bind. UDPClient делает именно это с помощью метода AllowNatTraversal .

Или это может быть проблема, связанная с брандмауэром/AV. Временно отключите их и попробуйте.

person lilo0    schedule 09.07.2018
comment
к сожалению, в .net 3.5 не было SetIPProtectionLevel, однако я вижу эту опцию в 4.0. Я отключил брандмауэры на ПК с той же проблемой. Я изучаю идею SetIPProtectionLevel, чтобы проверить, есть ли что-то подобное в 3.5. -Левон - person Levon Ravel; 09.07.2018
comment
Я принял ваш ответ как правильный, потому что, если кто-то наткнется на это, это может помочь. В моем случае Socket.Connect был проблемой, когда вы делаете это, он позволяет только этому ip делать запросы, все остальные ips будут игнорироваться - Левон - person Levon Ravel; 09.07.2018