我有一个程序,使用原始套接字向主机发送一组TCP SYN数据包,并使用带过滤器的libpcap获取响应。我尝试在异步I/O框架中实现这个程序,但似乎libpcap会丢失一些响应(即当TCP SYN和响应之间的时间少于100微秒时,第一组数据包就丢失了)。 pcap句柄的设置如下:
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).
}
}
如我之前所说,一些数据包会丢失(落入“没有接收”else语句中)。我知道这些数据包存在,因为我可以同步捕获它们(使用 tcpdump
或运行 pcap_loop
的线程)。我在这里缺少一些细节吗?还是这是与 libpcap
有关的问题?
pcap_next_ex
在前几个数据包中返回0,即使它们被另一个线程(和tcpdump)捕获。还有其他可能性吗? - bruno nery