У меня есть приложение Linux C ++, которое получает последовательные UDP-пакеты. Из-за последовательности я могу легко определить, когда пакет потерян или переупорядочен, то есть когда встречается «пробел». Система имеет механизм восстановления для устранения пробелов, однако, во-первых, лучше избегать пробелов. Используя простой основанный на libpcap анализатор пакетов, я определил, что в данных нет аппаратных пробелов. Тем не менее, я вижу много пробелов в моем приложении. Это говорит о том, что ядро отбрасывает пакеты; это подтверждается просмотром файла / proc / net / snmp . Когда мое приложение обнаруживает разрыв, счетчик Udp InErrors увеличивается.
На системном уровне мы увеличили максимальный приемный буфер:
# sysctl net.core.rmem_max
net.core.rmem_max = 33554432
На уровне приложения мы увеличили размер буфера приема:
int sockbufsize = 33554432
int ret = setsockopt(my_socket_fd, SOL_SOCKET, SO_RCVBUF,
(char *)&sockbufsize, (int)sizeof(sockbufsize));
// check return code
sockbufsize = 0;
ret = getsockopt(my_socket_fd, SOL_SOCKET, SO_RCVBUF,
(char*)&sockbufsize, &size);
// print sockbufsize
После вызова getsockopt () значение печати всегда в 2 раза больше установленного значения (67108864 в приведенном выше примере), но я считаю, что этого следовало ожидать.
Я знаю, что неспособность использовать данные достаточно быстро может привести к потере пакета. Однако все это приложение проверяет последовательность, а затем помещает данные в очередь; фактическая обработка выполняется в другом потоке. Кроме того, машина современна (двойной Xeon X5560, 8 ГБ оперативной памяти) и очень легко загружена. У нас есть буквально десятки идентичных приложений, получающих данные со скоростью намного выше , которые не сталкиваются с этой проблемой.
Помимо слишком медленного использования приложения, есть ли другие причины, по которым ядро Linux может отбрасывать UDP-пакеты?
FWIW, это на CentOS 4, с ядром 2.6.9-89.0.25.ELlargesmp.