私は現在、学習の流れにあります。そのために、私は比較的シンプルなポートスキャナーを作っています。ゴルーチンのスキャンポート
私が直面している問題は、これらのポートをスキャンするのにかなりの時間がかかることです。私が行っている動作は、もし私がポートをスキャンすると(intro32の配列として定義されています(protobuf doesntのサポートint16)、goroutinesは動作しませんが、想像できるように5ポート以上をスキャンするとかなり遅くなります。 。並列処理を実現するために、並列に
を実行している、私は(解説+問題はコードの後に来る)コードの次のビットを思い付いた:
://entry point for port scanning
var results []*portscan.ScanResult
//len(splitPorts) is the given string (see benchmark below) chopped up in an int32 slice
ch := make(chan *portscan.ScanResult, len(splitPorts))
var wg sync.WaitGroup
for _, port := range splitPorts {
connect(ip, port, req.Timeout, ch, &wg)
}
wg.Wait()
for elem := range ch {
results = append(results, elem)
}
// go routine
func connect(ip string, port, timeout int32, ch chan *portscan.ScanResult, wg *sync.WaitGroup) {
wg.Add(1)
go func() {
res := &portscan.ScanResult{
Port: port,
IsOpen: false,
}
conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", ip, port), time.Duration(timeout)*time.Millisecond)
if err == nil {
conn.Close()
res.IsOpen = true
}
ch <- res
wg.Done()
}()
}
だからいるProtobuf私に次のように見える構造体を準備しました
type ScanResult struct {
Port int32 `protobuf:"varint,1,opt,name=port" json:"port,omitempty"`
IsOpen bool `protobuf:"varint,2,opt,name=isOpen" json:"isOpen,omitempty"`
}
コードスニップの最初の行に見られるように私はすべての結果を保持するためにスライスを定義しました。私のアプリケーションはポートを並行してスキャンし、それが完了したら興味のある人に結果を送信します。
ただし、このコードを使用すると、プログラムが停止します。
私はその性能をテストする場合は、このベンチマークを実行します。
func BenchmarkPortScan(b *testing.B) {
request := &portscan.ScanPortsRequest{
Ip: "62.129.139.214",
PortRange: "20,21,22,23",
Timeout: 500,
}
svc := newService()
for i := 0; i < b.N; i++ {
svc.ScanPorts(nil, request)
}
}
それが立ち往生するの原因は何ですか。このコードを見れば、何も分からないのですか?
要するに私の最終的な結果は、それぞれのポートが別の実行ルーチンでスキャンされ、それらがすべて終了したときに、結果がすべてScanResultの結果スライスに集まるということです。
私はあなたが私を助けるために十分な情報を提供してくれたことを願っています。
ああ、私は特にポインタを探していて、学習ビットではなく、コードサンプルを実行しています。
あなたは、英雄です!チャンネルを閉じる必要があるとは思っていませんでした。今は理にかなっている。説明ありがとう。ポートスキャンのパフォーマンスは今よりもはるかに優れています。 –