Пакеты UDP Winsock отбрасываются?

Это будет очень трудно, потому что Ваша функция лямбды будет скомпилирована в байт-код, и Ваш объект myfunction будет только указывать на байт-код а не человекочитаемый код, который Вы записали.

, Например, если Вы определяете 2 функции, один синтаксис лямбды использования и одно использование оператора определения, следующим образом:

>>> lambda_func = lambda x: x==2
>>> def def_func(x): return x == 2
...

Эти 2 объекта (lambda_func и def_func) будут эквивалентны, насколько Python затронут. На самом деле, если Вы будете идти вперед и демонтировать их использующий модуль скидки (как rebra предложенный), Вы получите идентичные результаты:

>>> import dis
>>> dis.dis(lambda_func)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               1 (2)
              6 COMPARE_OP               2 (==)
              9 RETURN_VALUE
>>> dis.dis(def_func)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               1 (2)
              6 COMPARE_OP               2 (==)
              9 RETURN_VALUE

При этом, Вы видите, как было бы трудно получить исходный код, когда это - многие к отношениям

10
задан Warren Young 2 October 2009 в 02:31
поделиться

6 ответов

The default socket buffer size in Windows sockets is 8k, or 8192 bytes. Use the setsockopt Windows function to increase the size of the buffer (refer to the SO_RCVBUF option).

But beyond that, increasing the size of your receive buffer will only delay the time until packets get dropped again if you are not reading the packets fast enough.

Typically, you want two threads for this kind of situation.

The first thread exists solely to service the socket. In other words, the thread's sole purpose is to read a packet from the socket, add it to some kind of properly-synchronized shared data structure, signal that a packet has been received, and then read the next packet.

The second thread exists to process the received packets. It sits idle until the first thread signals a packet has been received. It then pulls the packet from the properly-synchronized shared data structure and processes it. It then waits to be signaled again.

As a test, try short-circuiting the full processing of your packets and just write a message to the console (or a file) each time a packet has been received. If you can successfully do this without dropping packets, then breaking your functionality into a "receiving" thread and a "processing" thread will help.

12
ответ дан 3 December 2019 в 17:20
поделиться

Да, стеку разрешено отбрасывать пакеты - даже незаметно - когда его буферы переполняются. Это часть природы UDP, одна из составляющих надежности, от которой вы отказываетесь при переключении с TCP. Вы можете либо заново изобрести TCP - плохо - добавив логику повтора, пакеты ACK и т. Д., Либо вы можете переключиться на что-то среднее, например SCTP .

Есть способы увеличить размер буфера стека, но это в значительной степени упускает суть. Если вы читаете недостаточно быстро, чтобы буферное пространство уже оставалось доступным, увеличение буфера только отсрочит время, необходимое вам, чтобы исчерпать буферное пространство. Правильным решением является создание буферов большего размера в вашем собственном коде и перемещение данных из буферов стека в буфер вашей программы как можно скорее,

5
ответ дан 3 December 2019 в 17:20
поделиться

Возможно ли, что чтение этого буфера приведет к отбрасыванию входящих пакетов?

Пакеты могут быть отброшены, если они прибывают быстрее, чем вы их читаете.

Если да, то какие есть ли варианты, чтобы исправить это?

Один из вариантов - изменить сетевой протокол: использовать TCP или реализовать какое-то подтверждение + «управление потоком» с использованием UDP.

В противном случае вам нужно понять, почему вы не читаете быстро / достаточно часто.

Если ЦП загружен на 100%, вам нужно выполнять меньше работы на каждый пакет или получить более быстрый ЦП (или использовать многопоточность и больше ЦП, если вы еще этого не сделали).

Если ЦП не загружен 100%, тогда, возможно, происходит следующее:

  • Вы читаете пакет
  • Вы выполняете некоторую работу, которая занимает x мсек реального времени, часть из которых тратится заблокированной на другие операции ввода-вывода (так что ЦП не не занята, но этоs не используется для чтения другого пакета)
  • В течение этих x мсек приходит поток пакетов, а некоторые из них отбрасываются

Лекарством от этого может быть изменение потоковой передачи.

Другой возможностью является одновременное выполнение нескольких пакетов. читает из сокета (каждое из ваших операций чтения предоставляет буфер, в который может быть получен UDP-пакет).

Другая возможность - посмотреть, есть ли (специфичная для O / S) опция конфигурации для увеличения количества полученных UDP-пакетов которые сетевой стек готов буферизовать, пока вы не попытаетесь их прочитать.

Другая возможность - выполнить несколько одновременных чтений из сокета (каждое из ваших чтений предоставляет буфер, в который может быть принят пакет UDP).

Другая возможность - проверить, есть ли (специфичный для O / S) параметр конфигурации для увеличения количества полученных пакетов UDP, которые сетевой стек готов буферизовать, пока вы не попытаетесь их прочитать.

Другая возможность - выполнить несколько одновременных чтений из сокета (каждое из ваших чтений предоставляет буфер, в который может быть принят пакет UDP).

Другая возможность - проверить, есть ли (специфичный для O / S) параметр конфигурации для увеличения количества полученных пакетов UDP, которые сетевой стек готов буферизовать, пока вы не попытаетесь их прочитать.

3
ответ дан 3 December 2019 в 17:20
поделиться

Не уверен, но в Windows невозможно опросить сокет и вызвать отбрасывание пакета. Windows собирает пакеты отдельно от вашего опроса, и это не должно вызывать сбоев.

Я предполагаю, что вы используете select () для опроса сокета? Насколько я знаю, не может вызвать падение.

0
ответ дан 3 December 2019 в 17:20
поделиться

First step, increase the receiver buffer size, Windows pretty much grants all reasonable size requests.

If that doesn't help, your consume code seems to have some fairly slow areas. I would use threading, e.g. with pthreads and utilize a producer consumer pattern to put the incoming datagram in a queue on another thread and then consume from there, so your receive calls don't block and the buffer does not run full

3rd step, modify your application level protocol, allow for batched packets and batch packets at the sender to reduce UDP header overhead from sending a lot of small packets.

4th step check your network gear, switches, etc. can give you detailed output about their traffic statistics, buffer overflows, etc. - if that is in issue get faster switches or possibly switch out a faulty one

... just fyi, I'm running UDP multicast traffic on our backend continuously at avg. ~30Mbit/sec with peaks a 70Mbit/s and my drop rate is bare nil

3
ответ дан 3 December 2019 в 17:20
поделиться

Пакеты могут быть потеряны из-за увеличения несвязанного сетевого трафика в любом месте маршрута или из-за полных буферов приема. Чтобы смягчить это, вы можете увеличить размер приемного буфера в Winsock.

По сути, UDP является ненадежным протоколом в том смысле, что доставка пакетов не гарантируется, и при сбое доставки отправителю не возвращается ошибка. Если вас беспокоит потеря пакетов, было бы лучше внедрить пакеты подтверждения в свой протокол связи или перенести их на более надежный протокол, такой как TCP. На самом деле нет других действительно надежных способов предотвратить потерю UDP-пакетов.

0
ответ дан 3 December 2019 в 17:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: