Как выделить память для отправки большого файла pcap (размером больше доступной памяти) с высокой производительностью при использовании winpcap? - PullRequest
1 голос
/ 30 октября 2011

Я использовал код из примера winpcap для отправки файла pcap (оригинальный код из документации winpcap находится по адресу эта ссылка )

Он отлично работает для отправки небольших файлов pcap, но если япопытался отправить большой файл pcap (больше доступного объема памяти, скажем, 2 Гб), он точно не получится.Этот код используется для выделения размера файла в памяти, чтобы отправить его позже

caplen= ftell(capfile)- sizeof(struct pcap_file_header);
...
/* Allocate a send queue */
squeue = pcap_sendqueue_alloc(caplen);

Вопрос состоит в том, как заставить это работать для больших файлов (в Гб или больше, чем максимальный объем памяти, доступный для выделения)?Должен ли я выделить, например, только 100 МБ и отправить очередь, а затем взять следующие 100 МБ?Если да, каков правильный размер буфера?И как это сделать?

Важной проблемой здесь является производительность отправки этого файла, которую нужно было сделать как можно быстрее (я посылаю видео пакеты).

Вкратце, как управлять памятью здесь, чтобыдостичь этой цели?

Будет ли у кого-нибудь правильное решение или предложение?


Фрагмент из примера кода (ненужный код для этого вопроса заменен на ...)

...
#include <pcap.h>
#include <remote-ext.h>

...

void main(int argc, char **argv)
{
pcap_t *indesc,*outdesc;
...
FILE *capfile;
int caplen, sync;
...
pcap_send_queue *squeue;
struct pcap_pkthdr *pktheader;
u_char *pktdata;
...

/* Retrieve the length of the capture file */
capfile=fopen(argv[1],"rb");
if(!capfile){
    printf("Capture file not found!\n");
    return;
}

fseek(capfile , 0, SEEK_END);
caplen= ftell(capfile)- sizeof(struct pcap_file_header);
fclose(capfile);

...

...

/* Open the capture file */
if ( (indesc= pcap_open(source, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf) ) == NULL)
{
    fprintf(stderr,"\nUnable to open the file %s.\n", source);
    return;
}

/* Open the output adapter */
if ( (outdesc= pcap_open(argv[2], 100, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf) ) == NULL)
{
    fprintf(stderr,"\nUnable to open adapter %s.\n", source);
    return;
}

...

/* Allocate a send queue */
squeue = pcap_sendqueue_alloc(caplen);

/* Fill the queue with the packets from the file */
while ((res = pcap_next_ex( indesc, &pktheader, &pktdata)) == 1)
{
    if (pcap_sendqueue_queue(squeue, pktheader, pktdata) == -1)
    {
        printf("Warning: packet buffer too small, not all the packets will be sent.\n");
        break;
    }

    npacks++;
}

if (res == -1)
{
    printf("Corrupted input file.\n");
    pcap_sendqueue_destroy(squeue);
    return;
}

/* Transmit the queue */



if ((res = pcap_sendqueue_transmit(outdesc, squeue, sync)) < squeue->len)
{
    printf("An error occurred sending the packets: %s. Only %d bytes were sent\n", pcap_geterr(outdesc), res);
}


/* free the send queue */
pcap_sendqueue_destroy(squeue);

/* Close the input file */
pcap_close(indesc);

/* 
 * lose the output adapter 
 * IMPORTANT: remember to close the adapter, otherwise there will be no guarantee that all the 
 * packets will be sent!
 */
pcap_close(outdesc);


return;
}

1 Ответ

1 голос
/ 30 октября 2011

Просто ограничьте его, скажем, 50 МБ (это несколько произвольно, но я считаю разумной отправной точкой), и улучшите бит кода, который предупреждает, когда не все пакеты помещаются в очередь, чтобы он просто отправлял то, что у него есть далеко и начинает заполнять очередь с начала оставшимися пакетами.

...