1

我已使用 winpcap 示例中的代码发送 pcap 文件(在此链接中找到来自 winpcap 文档的原始代码)

发送一个小的 pcap 文件可以正常工作,但是如果我尝试发送一个大的 pcap 文件(大于可用内存大小,比如 2 Gb),它肯定会失败。此代码用于在内存中分配文件的大小,以便稍后发送

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

问题是如何使它适用于大文件(以 Gb 或大于可分配的最大内存空间)?例如,我是否应该只分配 100 Mb 并发送队列,然后再占用下一个 100 Mb?如果是,那么正确的缓冲区大小是多少?以及如何做到这一点?

这里的一个重要问题是发送此文件的性能,这需要尽可能快地完成(我正在发送视频数据包)。

总之如何管理这里的内存来达到这个目的呢?

有人会有适当的解决方案或建议吗?


示例代码的片段(此问题的不必要代码替换为 ... )

...
#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;
}
4

1 回答 1

1

只需将其限制为 50 MB(这有点武断,但我认为是合理的起点),并增强当并非所有数据包都适合队列时发出警告的代码位,以便它只发送到目前为止的内容并开始用剩余的数据包从头开始填充队列。

于 2011-10-30T14:02:38.597 回答