Good questions.
1.) It's MPEG video so it has continuity counters that help you detect if packets are missing. I can watch it on devices that are very sensitive to data being missing and those devices show no problems. The real application (that this sample is emulating) actually writes those packets to disk for later playout.
2.) I've only actually run the sample program for the last several hours but the real program exhibiting the problem has been run at least overnight and up to 24+ hours at a time.
3.) During an overnight period, the delay has increased from approx. 400ms to 5000ms
Thanks for responding.
Mike
"David Barnish"
<[EMAIL PROTECTED]>
04/20/2005 06:46 PM
|
|
Mike,
A few questions:
1. How do you know that you are keeping up with the bitstream? Your app is getting packets from the driver's buffer. Could you be falling behind while the buffer fills up?
2. How long have you run your program before restarting?
3. What was the largest delta you saw at this time?
Thank you,
David Barnish
"God does not play dice!"
-- Albert Einstein
"Not only does God play dice with
the Universe - he sometimes casts them where they can't be seen."
-- Stephen Hawking
-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
Sent: Wednesday, April 20, 2005 5:24 PM
To: winpcap-users@winpcap.polito.it
Subject: [WinPcap-users] capture delay based on timestamps increases?
Hello,
Below is a sample program adapted from the print packets sample in the
documentation.
Instead of printing the packets, for each packet it calculates the difference
between the current
time and the timestamp in the pcap packet header and puts those deltas
into 500ms buckets.
It prints those buckets and the maximum delay value after so many samples
to a file. My problem
is that when capturing, for example, from a constant bitrate
4Mbps stream, over time that maximum
delta value keeps getting larger and larger but the program is keeping
up with the input data.
If I restart the application, the delay goes back to the minimum value.
Can anyone help explain this increased delay in timestamps, please?
Thanks very much.
Mike Maffa
[EMAIL PROTECTED]
The sample was built using VS.NET 2003 using WinPcap3.1-Beta4
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include "stdafx.h"
#define HAVE_REMOTE
#include "pcap.h"
__int64 m_i64_500OrLess = 0;
__int64 m_i64_500To1000 = 0;
__int64 m_i64_1000To1500 = 0;
__int64 m_i64_1500To2000 = 0;
__int64 m_i64_2000To2500 = 0;
__int64 m_i64_2500To3000 = 0;
__int64 m_i64_3000OrMore = 0;
__int64 m_i64TotalSamples = 0;
__int64 m_i64Max = 0;
__int64 m_i64Min = 0;
void AddDeltaTimeStat(struct
timeval ts);
int _tmain(int
argc, _TCHAR* argv[])
{
pcap_if_t *alldevs;
pcap_if_t *d;
int
inum;
int
i=0;
pcap_t *adhandle;
int
res;
char
errbuf[PCAP_ERRBUF_SIZE];
// struct tm *ltime;
// char timestr[16];
struct
pcap_pkthdr *header;
const
u_char *pkt_data;
/*
Retrieve the device list on the local machine */
if
(pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) ==
-1)
{
fprintf(stderr,"Error in pcap_findalldevs:
%s\n", errbuf);
exit(1);
}
/*
Print the list */
for(d=alldevs;
d; d=d->next)
{
printf("%d. %s", ++i, d->name);
if
(d->description)
printf(" (%s)\n",
d->description);
else
printf(" (No description
available)\n");
}
if(i==0)
{
printf("\nNo interfaces found! Make sure
WinPcap is installed.\n");
return
-1;
}
printf("Enter the interface number (1-%d):",i);
scanf("%d", &inum);
if(inum
< 1 || inum > i)
{
printf("\nInterface number out of range.\n");
/*
Free the device list */
pcap_freealldevs(alldevs);
return
-1;
}
/*
Jump to the selected adapter */
for(d=alldevs,
i=0; i< inum-1 ;d=d->next, i++);
/*
Open the device */
if
( (adhandle= pcap_open(d->name, //
name of the device
65536,
// portion of
the packet to capture.
//
65536 guarantees that the whole packet will be captured on all the link
layers
PCAP_OPENFLAG_PROMISCUOUS, //
promiscuous mode
1000,
// read timeout
NULL,
// authentication
on the remote machine
errbuf
// error buffer
) ) == NULL)
{
fprintf(stderr,"\nUnable to open the
adapter. %s is not supported by WinPcap\n", d->name);
/*
Free the device list */
pcap_freealldevs(alldevs);
return
-1;
}
//
compile the filter
struct
bpf_program fcode;
unsigned
int
uiNetMask = 0xffffff;
char
szFilter[] = "ip and udp and dst host 238.5.5.21 and dst port 258";
if(pcap_compile(adhandle,
&fcode, szFilter, 1, uiNetMask) < 0)
{
_tprintf(_T("Unable to compile the packet
filter. Check the syntax.\n"));
}
//
set the filter
if(pcap_setfilter(adhandle,
&fcode) < 0)
{
_tprintf(_T("Unable to set the packet
filter, error from pcap_setfilter()."));
}
printf("\nlistening on %s...\n", d->description);
/*
At this point, we don't need any more the device list. Free it */
pcap_freealldevs(alldevs);
/*
Retrieve the packets */
while((res
= pcap_next_ex( adhandle, &header, &pkt_data)) >= 0){
if(res
== 0)
/*
Timeout elapsed */
continue;
AddDeltaTimeStat(header->ts);
/*
convert the timestamp to readable format */
//ltime=localtime(&header->ts.tv_sec);
//strftime(
timestr, sizeof timestr, "%H:%M:%S", ltime);
//printf("%s,%.6d
len:%d\n", timestr, header->ts.tv_usec, header->len);
}
if(res
== -1){
printf("Error reading the packets: %s\n",
pcap_geterr(adhandle));
return
-1;
}
return
0;
}
void AddDeltaTimeStat(struct
timeval ts)
{
#define EPOCHFILETIME (116444736000000000i64)
LARGE_INTEGER liNow;
FILETIME ftNow;
__int64
i64Now;
struct
timeval tvNow;
GetSystemTimeAsFileTime(&ftNow);
liNow.LowPart = ftNow.dwLowDateTime;
liNow.HighPart = ftNow.dwHighDateTime;
i64Now = liNow.QuadPart; /*
In 100-nanosecond intervals */
i64Now -= EPOCHFILETIME; /*
Offset to the Epoch time */
i64Now /= 10;
/* In
microseconds */
tvNow.tv_sec = (long)(i64Now
/ 1000000);
tvNow.tv_usec = (long)(i64Now
% 1000000);
__int64
i64TsInusec = 0;
i64TsInusec = Int32x32To64(ts.tv_sec, 1000000) + ts.tv_usec;
__int64
i64DiffInusec = 0;
if
((i64Now - i64TsInusec) > 0)
{
i64DiffInusec = i64Now - i64TsInusec;
// in microseconds
}
__int64
i64DiffInms = i64DiffInusec / 1000; //
in milliseconds
if
(i64DiffInms <= m_i64Min)
{
m_i64Min = i64DiffInms;
}
if
(i64DiffInms >= m_i64Max)
{
m_i64Max = i64DiffInms;
}
// bucketize
if
(i64DiffInms <= 500)
{
++m_i64_500OrLess;
}
else
if
((i64DiffInms > 500) && (i64DiffInms <= 1000))
{
++m_i64_500To1000;
}
else
if
((i64DiffInms > 1000) && (i64DiffInms <= 1500))
{
++m_i64_1000To1500;
}
else
if
((i64DiffInms > 1500) && (i64DiffInms <= 2000))
{
++m_i64_1500To2000;
}
else
if
((i64DiffInms > 2000) && (i64DiffInms <= 2500))
{
++m_i64_2000To2500;
}
else
if
((i64DiffInms > 2500) && (i64DiffInms <= 3000))
{
++m_i64_2500To3000;
}
else
{
++m_i64_3000OrMore;
}
++m_i64TotalSamples;
if
((m_i64TotalSamples % 200000) == 0)
{
FILE *fp = _tfopen(_T("c:\\stats.log"),
_T("a+"));
if
(fp != NULL)
{
TCHAR szTimeBuf[MAX_PATH];
FILETIME LocalFileTime;
SYSTEMTIME LocalTime;
FileTimeToLocalFileTime(&ftNow,
&LocalFileTime);
FileTimeToSystemTime(&LocalFileTime,
&LocalTime);
_stprintf(szTimeBuf, _T("%02d/%02d/%04d
%02d:%02d:%02d.%03d"), LocalTime.wMonth, LocalTime.wDay, LocalTime.wYear,
LocalTime.wHour, LocalTime.wMinute, LocalTime.wSecond, LocalTime.wMilliseconds);
_ftprintf(fp, _T("\n%s\n"),
szTimeBuf);
_ftprintf(fp, _T("\t 500ms
or less : %I64d\n"), m_i64_500OrLess);
_ftprintf(fp, _T("\t 500ms
to 1000ms : %I64d\n"), m_i64_500To1000);
_ftprintf(fp, _T("\t 1000ms
to 1500ms : %I64d\n"), m_i64_1000To1500);
_ftprintf(fp, _T("\t 1500ms
to 2000ms : %I64d\n"), m_i64_1500To2000);
_ftprintf(fp, _T("\t 2000ms
to 2500ms : %I64d\n"), m_i64_2000To2500);
_ftprintf(fp, _T("\t 2500ms
to 3000ms : %I64d\n"), m_i64_2500To3000);
_ftprintf(fp, _T("\t 3000ms
or more : %I64d\n"), m_i64_3000OrMore);
_ftprintf(fp, _T("\t Min
= %I64d, Max = %I64d\n"), m_i64Min, m_i64Max);
fflush(fp);
fclose(fp);
}
}
return;
}