我有一个程序向主机发送一组TCP SYN数据包(使用原始套接字),并使用libpcap
(带过滤器)来获取响应。我试图在一个异步I/O框架中实现它,但libpcap
似乎缺少一些响应(即在TCP SYN和响应之间的时间小于100 microseconds
时系列中的第一个数据包)。该PCAP手柄的设置是这样的:异步libpcap:丢失数据包?
pcap_t* pcap = pcap_open_live(NULL, -1, false, -1, errorBuffer);
pcap_setnonblock(pcap, true, errorBuffer);
然后我添加过滤器(包含在filterExpression字符串):
struct bpf_program filter;
pcap_compile(pcap, &filter, filterExpression.c_str(), false, 0);
pcap_setfilter(pcap, &filter);
pcap_freecode(&filter);
而且在环路上,发送每个数据包之后,我使用select知道如果我可以从libpcap的阅读:
int pcapFd = pcap_get_selectable_fd(pcap);
fd_set fdRead;
FD_ZERO(&fdRead);
FD_SET(pcapFd, &fdRead);
select(pcapFd + 1, &fdRead, NULL, NULL, &selectTimeout);
并阅读:
if (FD_ISSET(pcapFd, &fdRead)) {
struct pcap_pkthdr* pktHeader;
const u_char* pktData;
if (pcap_next_ex(pcap, &pktHeader, &pktData) > 0) {
// Process received response.
}
else {
// Nothing to receive (or error).
}
}
正如我之前所说的,一些数据包错过了(落入“无法接收”其他)。我知道这些数据包在那里,因为我可以用同步方式捕获它们(使用tcpdump
或运行pcap_loop
的线程)。我在这里错过了一些细节吗?或者这是libpcap
的问题?
可能出现这种情况,您发送太多请求的速度太快,并且服务器发送的响应速度更快,您可以处理它们,从而过载OS的网络缓冲区并丢弃数据包。或者有可能你的receiver socket没有及时处理最初的响应。你能否证实你假设你收到的所有回应实际上都到达了那里? Todo会同时在与应用程序相同的接口上运行tcpdump。如果你在tcpdump中看到所有的数据包,而不是在应用程序中,你可能会遇到上述问题之一。 – ryanbwork 2012-07-24 19:10:14
我已经做到了(tcpdump在一边,但也是pcap_loop一个不同的线程),并且所有的数据包都在那里。因此,我不相信我发送的回复太快了。我怎么知道我的接收器插座(即libpcap)还没有安装?这是有道理的,因为失落的回应总是第一或第二。 – 2012-07-24 19:16:07
即使您看到tcpdump中的数据包,如果您的应用程序无法处理它们收到的速率,它们仍可能被操作系统丢弃。如果您的应用程序在发送响应之后启动,请尝试在从服务器发送初始响应之前添加一些重要延迟;如果您成功收到所有回复,就会发现您的问题。 – ryanbwork 2012-07-24 19:22:58