Я хотел измерить пропускную способность и задержку устройства, поэтому подключил два кабеля Ethernet от устройства к системе Linux RHEL 8. Я создал приложение Python 3, работающее в системе Linux, которое имеет 3 процесса: 1) 1 для отправки данных на один интерфейс, 2) 1 для получения обработанных данных на другом интерфейсе и 3) 1 для отправки фиктивных данных в противоположном направлении. чтобы измерения можно было проводить при загрузке данных, идущих в обоих направлениях.
Я использую многопроцессорную библиотеку Python и использую сокеты Linux udp из библиотеки сокетов, а также необработанные сокеты для пользовательских протокол (iperf 3 в моем случае не работает из-за кастомного протокола). Чтобы измерить пропускную способность и задержку, я создаю группу тестовых пакетов и отмечаю время каждого из них после его отправки из процесса 1). Пока процесс 1) отправляет пакеты, процесс 2) принимает пакеты и присваивает им временные метки на другой стороне. После получения всех объемов данных он вычисляет разницу между соседними полученными пакетами, чтобы получить измерение пропускной способности, а также вычисляет разницу между отправкой и получением, чтобы получить измерения задержки.
Проблема связано с взаимодействием многопроцессорной обработки и сокетов. На машине, когда я вызываю sock.sendto(data, (dest, port)) из процесса 1 и вызываю sock2.receivefrom(data) из процесса 2, похоже, что они не работают одновременно. Кажется, что процесс 1) отправляет все свои пакеты (я пробую это с пакетами размером 1000 байт, 300 пакетов), а затем процесс 2) начинает получать. Из трассировок Wireshark я знаю, что полученные пакеты фактически достигают системы Linux еще до того, как она начнет их обрабатывать. Даже более странный процесс 3) отправляет все свои пакеты раньше, чем процесс 2) отправляет даже один пакет. Что еще хуже, процесс 1) иногда пропускает пакеты, если общее количество байтов пакета превышает 200000.
Ниже приведен некоторый псевдокод того, что я делаю
Код: Выделить всё
import multiprocessing
import time
import socket
def sender(socket, queue, data_list, dest):
timestamps = []
for data in data_list:
socket.sendto(data, dest)
timestamps.append(time.perf_counter())
queue.put(timestamps)
def sender_dummy(socket, queue, data_list, dest):
for data in data_list:
socket.sendto(data, dest)
def main():
## Setup the sockets with appropriate timeouts and interfaces and protocols
....
## Setup the test data
....
## Begin multi-processing
q = multiprocessing.Queue()
task_main = multiprocessing.Process(target=sender, args=(sender_sock, q, test_data, (dest_addr, dest_port)))
task_dummy = multiprocessing.Process(target=sender_dummy, args=(sender_dummy_sock, q, dummy_data, (dest_addr, dest_port)))
timestamps_recv = []
task_dummy.start()
task_main.start()
for i in range(len(test_data)):
recv_sock.receivefrom(TEST_DATA_SIZE)
timestamps_recv.append(time.perf_counter())
task_dummy.join()
task_main.join()
timestamps_send = q.get()
# Calculate latency and throughput
...
Подробнее здесь: https://stackoverflow.com/questions/783 ... nd-python3
Мобильная версия