如何解决go - 简单的工作池
作为一个 Go 和编程的初学者,我一直在用 gopacket 库编写一个端口扫描器,大部分代码已经完成,但是我遇到了一个问题,即产生过多的 goroutines 并获取'read ip4 0.0.0.0: I/O timeout' 我做了一些研究,看来我需要实现一个工作池我一直在尝试实现这个例子 'https://gobyexample.com/worker-pools'因为我还在学习 goroutines 和渠道,我已经研究了几天,似乎无法弄清楚如何在我的程序中正确实现上述示例,你们能给我一些指示,或者最好是代码修复示例.
package main
import (
"fmt"
"log"
"net"
"time"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
)
// Get preferred outbound ip and port of this machine
func GetoutboundIPPort() (net.IP,int) {
conn,err := net.Dial("udp","1.1.1.1:80")
if err != nil {
log.Fatal(err)
}
defer conn.Close()
localAddr := conn.LocalAddr().(*net.UDPAddr)
return localAddr.IP,localAddr.Port
}
func ipv4_gen(out chan net.IP) {
ip,ipnet,err := net.ParseCIDR("192.168.0.0/24")
if err != nil {
log.Fatal(err)
}
for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); inc(ip) {
time.Sleep(300 * time.Millisecond)
dstaddrs,err := net.LookupIP(ip.String())
if err != nil {
log.Fatal(err)
}
dstip := dstaddrs[0].To4()
out <- dstip
}
close(out)
}
func inc(ip net.IP) {
for j := len(ip) - 1; j >= 0; j-- {
ip[j]++
if ip[j] > 0 {
break
}
}
}
func port_scanner(dstip net.IP) {
dstport := layers.TCPPort(80)
srcip,port := GetoutboundIPPort()
srcport := layers.TCPPort(port)
ip := &layers.IPv4{
SrcIP: srcip,DstIP: dstip,Protocol: layers.IPProtocolTCP,}
tcp := &layers.TCP{
SrcPort: srcport,DstPort: dstport,Seq: 1105024978,SYN: true,Window: 14600,}
tcp.SetNetworkLayerForChecksum(ip)
buf := gopacket.NewSerializeBuffer()
opts := gopacket.SerializeOptions{
ComputeChecksums: true,FixLengths: true,}
if err := gopacket.SerializeLayers(buf,opts,tcp); err != nil {
log.Fatal(err)
}
conn,err := net.ListenPacket("ip4:tcp","0.0.0.0")
if err != nil {
log.Fatal(err)
}
defer conn.Close()
if _,err := conn.Writeto(buf.Bytes(),&net.IPAddr{IP: dstip}); err != nil {
log.Fatal(err)
}
// Set deadline so we don't wait forever.
if err := conn.SetDeadline(time.Now().Add(10 * time.Second)); err != nil {
log.Fatal(err)
}
for {
b := make([]byte,4096)
n,addr,err := conn.ReadFrom(b)
if err != nil {
log.Println("error reading packet: ",err)
return
} else if addr.String() == dstip.String() {
// Decode a packet
packet := gopacket.NewPacket(b[:n],layers.LayerTypeTCP,gopacket.Default)
// Get the TCP layer from this packet
if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
tcp,_ := tcpLayer.(*layers.TCP)
if tcp.DstPort == srcport {
if tcp.SYN && tcp.ACK {
fmt.Printf("discovered open port %d/tcp on %s\n",dstport,dstip)
}
return
}
}
}
}
}
func worker(id int,ips <-chan net.IP) {
for ip := range ips {
go port_scanner(ip)
}
}
func main() {
ips := make(chan net.IP)
go ipv4_gen(ips)
for w := 1; w <= 10; w++ {
go worker(w,ips)
}
}
解决方法
你正在为 worker 内部的每一项工作启动一个新的 goroutine,因此它违背了它的目的。
您需要运行工作而不是在工作器内部启动 goroutine。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。