#c #queue
#c #очередь
Вопрос:
Я пытаюсь настроить очередь на C, но когда что-то новое ставится в очередь, оно каждый раз дублирует значение head вместо сохранения этого нового элемента.
#include <pcap.h>
#include <pthread.h>
#include <stdlib.h>
struct packet_queue {
struct pcap_pkthdr *header;
unsigned char *packet;
struct packet_queue *next;
};
struct packet_queue *head = NULL;
struct packet_queue *tail = NULL;
int run = 0;
int packets = 0;
int v;
void enqueue(struct packet_queue *pq) {
if (head == NULL) {
head = pq;
}
else {
struct packet_queue *current = head;
while (current->next != NULL) {
current = current->next;
}
current->next = pq;
}
packets ;
}
void printqueue() {
struct packet_queue * current = head;
int i = 50;
while (i > 0 amp;amp; current != NULL) {
printf("%dn", current->header->len);
current = current->next;
i--;
}
}
void dispatch(struct pcap_pkthdr *header,
const unsigned char *packet,
int verbose) {
v = verbose;
int i;
struct packet_queue *next_packet = (struct packet_queue *) malloc(sizeof(struct packet_queue));
next_packet->header = (struct pcap_pkthdr *) header;
next_packet->packet = (unsigned char * ) packet;
next_packet->next = NULL;
enqueue(next_packet);
}
При печати очереди printqueue()
с ее использованием каждый раз выводится одно и то же значение (значение заголовка), предполагающее, что заголовок дублируется в очереди.
РЕДАКТИРОВАТЬ: провел еще немного тестирования и понял, что вся очередь настроена на то, что является последним добавленным элементом.
struct pcap_pkthdr header;
const unsigned char *packet;
//initialise dynamic array
dynarray_init(amp;syn_adds, 5);
while (1) {
// Capture a packet
packet = pcap_next(pcap_handle, amp;header);
if (packet == NULL) {
// pcap_next can return null if no packet is seen within a timeout
if (verbose) {
printf("No packet received. %sn", pcap_geterr(pcap_handle));
}
} else {
// Optional: dump raw data to terminal
if (verbose) {
//dump(packet, header.len);
}
// Dispatch packet for processing
dispatch(amp;header, packet, verbose);
}
}
}
Комментарии:
1. Не связано с рассматриваемой проблемой, но преобразование a
const unsigned char *
в anunsigned char *
не является хорошей идеей.2. Что вызывает
dispatch
? Где находятсяheader
иpacket
выделяются?3. @JosephSible-Переустановите Monica Я добавил const в структуру спасибо! Я отредактировал вопрос, чтобы добавить, где вызывается отправка
4. «Структура pcap_pkthdr и пакетные данные не должны освобождаться вызывающим объектом и не гарантируется, что они будут действительными после следующего вызова pcap_next_ex(), pcap_next(), pcap_loop() или pcap_dispatch(); если код нуждается в том, чтобы они оставались действительными, он должен сделать копиюиз них. » manpages.ubuntu.com/manpages/xenial/man3 /…
Ответ №1:
Ваша очередь в порядке. Проблема в том, что вы вызываете dispatch
с теми же указателями. Вы продолжаете передавать адрес того же struct pcap_pkthdr header;
, header
что и, и в руководстве для pcap_next
этого сказано:
pcap_next() считывает следующий пакет (вызывая pcap_dispatch() с cnt равным 1) и возвращает указатель u_char на данные в этом пакете. Данные пакета не должны освобождаться вызывающим объектом и не гарантируется, что они будут действительными после следующего вызова pcap_next_ex(), pcap_next(), pcap_loop() или pcap_dispatch(); если коду необходимо, чтобы они оставались действительными, он должен сделать их копию. Структура pcap_pkthdr, на которую указывает h, заполняется соответствующими значениями для пакета.
Для них обоих решение одно и то же: вам нужно malloc
обновлять указатели для каждого вызова dispatch
и копировать в них данные.
Комментарии:
1. Извините, все еще немного запутался. Будет ли это во втором фрагменте кода перед вызовом отправки? или мне нужно было бы сделать копию внутри функции отправки?
2. @finn_101 Не имеет значения, где вы это делаете, просто то, что вы делаете.
3. Имеет смысл. Каков наилучший способ скопировать постоянный символ без знака * ?
4. @finn_101 Если это строка с нулевым завершением, то
strdup
. Если это просто массив байтов, затемmalloc
следуетmemcpy
.5. Как мне получить размер данных? Я пытаюсь
strlen(packet)
, но каждый раз получается 1 или 2, что, очевидно, неверно