J'utilise packet_mmap pour lire un flux rapide de paquets UDP. Lorsque vous utilisez l'un des segments de code suivants pour attendre les trames entrantes, il fonctionne très bien.Quelques problèmes avec PACKET_MMAP
// ring[i].iov_base points to the start address of the ith frame
struct tpacket_hdr *header = (struct tpacket_hdr *) ring[i].iov_base;
// Using poll on socket to wait for data
while(!(header -> tp_status & TP_STATUS_USER))
{
struct pollfd pfd;
pfd.fd = _socket;
pfd.events = POLLIN | POLLERR;
pfd.revents = 0;
poll(&pfd, 1, -1);
}
// Using nanosleep to wait for incoming data
while(!(header -> tp_status & TP_STATUS_USER))
{
struct timespec t, r;
t.tv_nsec = 1;
t.tv_sec = 0;
nanosleep(&t, &r)
}
Cependant lorsque je tente d'attente occupé (while(!(header -> tp_status & TP_STATUS_USER)) ;
la déclaration reste vrai indéfiniment après quelques paquets sont lus Pourquoi est-ce donc? ? est-ce que le noyau ne transférer que des cadres dans la mémoire tampon de sonnerie lorsqu'un appel système est émis la prise d'entrée est initialisée comme si:. socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))
aussi, lorsque vous utilisez ce code (en utilisant sondage ou nanosleep), il semble être à la baisse des paquets, alors qu'un simple code de réception utilisant une socket UDP ne le fait pas, ce qui rend l'implémentation de packet_mmap plus lente, parfois les paquets perdus sont détectés par les sockets, mais en utilisant leOption-getsockopt
:
if (header -> tp_status & TP_STATUS_LOSING)
{
struct tpacket_stats stats;
socklen_t size_sock = sizeof(tpacket_stats);
if (getsockopt(_socket, SOL_PACKET, PACKET_STATISTICS, &stats, &size_sock) > -1)
printf("Dropped packets: [%d, %d]\n", stats.tp_drops, stats.tp_packets);
}
il déclare qu'aucun paquet ont été abandonnées (exemple de sortie: "la perte de paquets: [0, 5]"). Est-ce que PACKET_STATISTICS
se comporte différemment sur les sockets PACKET_RX_RING
?
Le code complet pour ce code liste est disponible here