我使用以下代码捕获以太网数据包:
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() {
}
问题是数据包Sauce.Packets()正在阻塞:如果没有收到数据包,则存在无限循环。如何设置超时时间?
最佳答案
从the docs:
func (p *PacketSource) Packets() chan Packet
Packets returns a channel of packets, allowing easy iterating over packets. Packets will be asynchronously read in from the underlying PacketDataSource and written to the returned channel. If the underlying
PacketDataSource
returns anio.EOF
error, the channel will be closed. If any other error is encountered, it is ignored.for packet := range packetSource.Packets() { handlePacket(packet) // Do something with each packet. }
If called more than once, returns the same channel.
因此,由于
gopacket.PacketSource.Packets()
返回一个 channel ,因此您可以在两个 channel 上采用select
编码的常用策略-其中一个操作由超时控制。在最简单的情况下,将执行以下操作:
timer := time.NewTimer(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
}
}
根据确切的用例,第二个 channel 可以来自其他来源,例如context。
关于go - 无阻塞以太网捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62534827/