Код: Выделить всё
send
Код: Выделить всё
recv
Код: Выделить всё
recv
Код: Выделить всё
sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
Код: Выделить всё
recv
У меня есть приложение Ping/Pong, где приложение A работает в поле A и приложении B запускается в поле B. , и коробка A и B подключены друг к другу одним кабелем Ethernet:
app a :
Код: Выделить всё
while (1) {
// Send PING + pass sockaddr_ll with interface info
sendto(...);
// Block until PONG is received + logic to ignore irrelevant traffic
recv(...);
}
Код: Выделить всё
while (1) {
// Block until we recv a PING + logic to ignore irrelevant traffic
recv(...);
// Reply with a PONG + pass sockaddr_ll with interface info
sendto(...);
}
< /code>
Как упомянуто, все работает нормально. Проблема возникает при изменении приложения [b] [/b] на:
while (1) {
sendto(...); // PING 1
sendto(...); // PING 2
recv(...); // PONG 1
recv(...); // PONG 2?
}
< /code>
Некоторые важные наблюдения: < /p>
[*] Второй вызов к recv < /code> может заблокировать неопределенное время. Чем больше вы позволяете ему цикть, тем больше вероятность, что это произойдет, но обычно происходит в течение первых 10-20 итераций. < /P>
< /li>
Я думал это Может быть просто плохим кодом, но если я контролирую интерфейс в поле A с TCPDUMP, даже TCPDUMP не сообщит о виде кадра на интерфейсе. После ожидания несколько секунд и нажатия Ctrl+C в приложении A, запущенном ifconfig
< li> Я знаю, что коробка B отвечает на Pong, потому что я использовал оборудование для мониторинга сети, чтобы отразить ответы от B -> A в отдельную коробку C, и TCPDUMP, работающий в отчетах C, видя Pong. < /P>
< /li>
Если я заменяю приложение A, чтобы запустить в поле B и приложение B, чтобы запустить в поле A, такая же проблема все еще возникает, поэтому Я не думаю (?) Это просто проблема с коробкой a. второй recv и я Используйте отдельную программу, чтобы отправить любую произвольную непонгскую кадр на том же интерфейсе, и через провод, на котором приложение A+B общается, а затем «начнет», что окончательный донг и приложение A прекратит блокировать recv . Я могу сделать это из любой коробки A или коробки B, пока он отправляется на интерфейс субъекта, и он все равно будет «выбить» его. Это просто нужен трафик, чтобы протолкнуть его. Интерфейс, но в конечном итоге снова застрянет. > Просто приложение A , Отправка этих первоначальных "Ping" S будет «пнуть» интерфейса, и первый поин, который он получает > Скорость отправки может иметь какое -то отношение к этому. Если я удаляю петлю и просто повторно заполняю приложение вручную, это не произойдет (или я еще не был свидетелем этого), поэтому у меня есть это на петле. Но логически, что когда -нибудь должно быть только 2 кадра, ожидающих за провод за раз? Что касается того, что я здесь свидетелем? Похоже, ядро или даже Ник просто держатся за кадр и не отпускают, пока что -то еще за ним не пройдет? Я не думаю, что это может быть алгоритм Nagle, потому что я имею дело с необработанными рамами Ethernet, а не TCP. Тот факт, что даже TCPDUMP не сообщает, что видение потерянного кадры - это ошеломляющий. < /P>
это плохая версия ядра? Плохие NIC на обеих коробках (см. Точка 4)? Как я могу отладить это дальше?
Подробнее здесь: https://stackoverflow.com/questions/794 ... me-dropped