go - 无阻塞以太网捕获

标签 go pcap gopacket

我使用以下代码捕获以太网数据包:

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 an io.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/

相关文章:

go - 使用 go build(或 go install)的增量构建不起作用

rest - 如何使用证书 golang 发送 https 请求

Go DynamoDB Expression Add无法添加到列表

c - 了解 pcap 包头

c - pcap_compile() 表达式

rust - 将 pcap 数据包写入没有文件头的文件

go - 如何将修改后的Go Packet数据包序列化为真实IP数据包

go - 如何使用 gopacket 获取 header 字节/长度

go - gopacket中的tcp assembly包如何使用?

pointers - 如何设计具有可修改字段的结构?