我使用此代码捕获Ehternet数据包:
var snapshotLen int32 = 102400
var promiscuous bool = true
var timeout time.Duration = 1 * time.Second
var handle *pcap.Handle
handle, err = pcap.OpenLive(device, snapshotLen, promiscuous, timeout)
err = handle.SetBPFFilter(filter)
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
for packet := range packetSource.Packets() {
}问题是packetSource.Packets()是阻塞的:如果没有接收到数据包,就会有一个无限循环。我怎样才能设置超时?
发布于 2020-06-23 12:44:41
来自医生们
func (p *PacketSource) Packets() chan Packet数据包返回一个数据包通道,允许对数据包进行轻松的迭代。数据包将从底层PacketDataSource异步读取并写入返回的通道。如果基础PacketDataSource返回io.EOF错误,则通道将关闭。如果遇到任何其他错误,则将忽略此错误。 对于数据包:=范围,packetSource.Packets() {handlePacket(数据包) //对每个数据包进行处理。} 如果多次调用,则返回相同的信道。
因此,由于gopacket.PacketSource.Packets()返回一个通道,所以您可以在两个通道上使用通常的selecting策略--对其中一个通道的操作由超时控制。
在最简单的情况下,这样的事情可以做到:
timer := time.NewTicker(2 * time.Second)
defer timer.Stop()
src := gopacket.NewPacketSource(handle, handle.LinkType())
for {
select {
case pkt := <- src.Packets():
// process a packet in pkt
case <- timer.C:
// timed out waiting for 2 seconds
}
}根据具体的用例,第二个通道可以来自另一个源--比如上下文。
https://stackoverflow.com/questions/62534827
复制相似问题