我正在尝试创建一个 golang 网络应用程序,它正在侦听在我的网络上广播的数据包,然后将广播的数据包整齐地放在前端的 HTML 表中(连续)。这是我到目前为止的代码。我花了几个小时,但无法弄清楚其余的:
下面是我获取数据包的代码,然后将有关数据包的信息放入结构中。
func PacketListener(ch chan PacketStructureslice) {
var (
iface = "en0"
snaplen = int32(1600)
promisc = false
timeout = pcap.BlockForever
filter = "arp" //capture packets only from that protocol
devFound = false
// packetSlice = []gopacket.Packet{}
)
devices, err := pcap.FindAllDevs()
if err != nil {
log.Panicln(err)
}
for _, device := range devices {
if device.Name == iface {
devFound = true
}
}
if !devFound {
log.Panicf("Device named '%s' does not exist\n", iface)
}
handle, err := pcap.OpenLive(iface, snaplen, promisc, timeout)
if err != nil {
log.Panicln(err)
}
defer handle.Close()
if err := handle.SetBPFFilter(filter); err != nil {
log.Panicln(err)
}
source := gopacket.NewPacketSource(handle, handle.LinkType()) //LinkType() is the decoder to use
for packet := range source.Packets() {
view := PacketStructure{
PacketProtocol: "ARP",
Something: time.Now().String(),
Number: y,
}
realdata.Items = append(realdata.Items, view)
ch <- realdata
y++
}
}
此结构稍后将参与附加到另一个包含子结构切片的父结构。这将导致包含有关数据包信息的结构片段,然后在前端,我将遍历此结构片段以创建 HTML 表。你会明白我的意思。
现在这里是前面提到的两个结构。 PacketStructSlice 是 Packetstructs 的一部分,在上面的代码中,我一直将 PacketStructure 结构附加到其中。我也在创建通道,让运行 Packetlistener 函数的 goroutine 发送数据
type PacketStructureslice struct {
Items []PacketStructure
}
type PacketStructure struct {
PacketProtocol string
Something string
Number int
}
var Channels chan PacketStructureslice
下面是在 API 调用上执行的函数。不要担心它是如何调用的,我有一个自定义模板缓存和模板模型来将所有内容发送到前端。我只想关注如何获取信息
func (m *Repository) APIcallForGettingPackets(w http.ResponseWriter, r *http.Request) {
go PacketListener(Channels)
fmt.Println("Got the request")
receiver := <-Channels
fmt.Println(receiver) //just doing this to test
render.RenderTemplate(w, "packets.html", &models.TemplateData{
DataSlice: reciever.Items,
})
}
render.RenderTemplate 只是将 reciever.Items 发送到前端。 reciever.Items 应该包含 PacketStructure 结构的切片。
现在问题来了。由于我的 PacketListener 函数永远运行,我的代码被通道请求阻塞,一切都被阻塞。我将如何创建此代码,以便我的代码获取数据包数据片段,并将其发送到前端。现在,由于我的函数在 goroutine 中永远运行,出于某种原因,当我调用通道时,我的代码也会永远运行。我需要一些方法让 goroutine 侦听数据包以继续将数据包数据附加到数据包数据片段中,并在这样做时将其显示在前端。前端是无关紧要的,但是你去吧:
<table>
<tr>
<th>Type</th>
<th>Something</th>
<th>Packet number</th>
</tr>
{{ range .DataSlice}}
<tr>
<td>{{ .PacketProtocol }}</td>
<td>{{ .Something }}</td>
<td>{{ .Number }}</td>
</tr>
{{ end}}
</table>
我是 go-routines 的新手,你可能会说,但我就是想不通。
谢谢:)
================================================= ====================
我已经尝试在API调用函数中进行通道声明,但仍然没有得到我想要的结果。但是,它确实使我的程序运行,因为它不会阻止 API 调用功能。在函数外声明通道会阻塞一切