首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无阻塞Eternet捕获

无阻塞Eternet捕获
EN

Stack Overflow用户
提问于 2020-06-23 12:32:33
回答 1查看 306关注 0票数 1

我使用此代码捕获Ehternet数据包:

代码语言:javascript
复制
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()是阻塞的:如果没有接收到数据包,就会有一个无限循环。我怎样才能设置超时?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-06-23 12:44:41

来自医生们

func (p *PacketSource) Packets() chan Packet 数据包返回一个数据包通道,允许对数据包进行轻松的迭代。数据包将从底层PacketDataSource异步读取并写入返回的通道。如果基础PacketDataSource返回io.EOF错误,则通道将关闭。如果遇到任何其他错误,则将忽略此错误。 对于数据包:=范围,packetSource.Packets() {handlePacket(数据包) //对每个数据包进行处理。} 如果多次调用,则返回相同的信道。

因此,由于gopacket.PacketSource.Packets()返回一个通道,所以您可以在两个通道上使用通常的selecting策略--对其中一个通道的操作由超时控制。

在最简单的情况下,这样的事情可以做到:

代码语言:javascript
复制
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
    }
}

根据具体的用例,第二个通道可以来自另一个源--比如上下文

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62534827

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档