实现Ping和TCP端口扫描功能
This commit is contained in:
+113
-21
@@ -4,11 +4,15 @@ import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/layout"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
|
||||
"ip_scan_go/internal/scan"
|
||||
)
|
||||
|
||||
const appVersion = "V0.0.1"
|
||||
@@ -31,6 +35,7 @@ type scanForm struct {
|
||||
scanBtn *widget.Button
|
||||
pingBtn *widget.Button
|
||||
keypadBtn []*widget.Button
|
||||
dispatcher *scan.Dispatcher
|
||||
scanning bool
|
||||
}
|
||||
|
||||
@@ -108,36 +113,108 @@ func (f *scanForm) buildControlRow() fyne.CanvasObject {
|
||||
|
||||
func (f *scanForm) toggleScan() {
|
||||
if !f.scanning {
|
||||
f.scanning = true
|
||||
f.scanBtn.SetText("停止扫描")
|
||||
f.pingBtn.Disable()
|
||||
f.setInputsEnabled(false)
|
||||
f.progress.SetValue(0)
|
||||
f.output.Append("开始扫描... (TODO: 接入扫描逻辑)\n")
|
||||
ips, err := scan.ParseIPs(f.ipList.Text)
|
||||
if err != nil {
|
||||
f.appendOutput("IP解析错误: " + err.Error() + "\n")
|
||||
return
|
||||
}
|
||||
ports, err := scan.ParsePorts(f.portList.Text)
|
||||
if err != nil {
|
||||
f.appendOutput("端口解析错误: " + err.Error() + "\n")
|
||||
return
|
||||
}
|
||||
if len(ips) == 0 || len(ports) == 0 {
|
||||
f.appendOutput("请输入IP和端口\n")
|
||||
return
|
||||
}
|
||||
f.startScan(false, ips, ports)
|
||||
} else {
|
||||
f.scanning = false
|
||||
f.scanBtn.SetText("开始扫描")
|
||||
f.pingBtn.Enable()
|
||||
f.setInputsEnabled(true)
|
||||
f.output.Append("已停止扫描\n")
|
||||
f.stopScan()
|
||||
}
|
||||
}
|
||||
|
||||
func (f *scanForm) togglePing() {
|
||||
if !f.scanning {
|
||||
f.scanning = true
|
||||
ips, err := scan.ParseIPs(f.ipList.Text)
|
||||
if err != nil {
|
||||
f.appendOutput("IP解析错误: " + err.Error() + "\n")
|
||||
return
|
||||
}
|
||||
if len(ips) == 0 {
|
||||
f.appendOutput("请输入IP\n")
|
||||
return
|
||||
}
|
||||
f.startScan(true, ips, nil)
|
||||
} else {
|
||||
f.stopScan()
|
||||
}
|
||||
}
|
||||
|
||||
func (f *scanForm) startScan(pingOnly bool, ips []string, ports []int) {
|
||||
f.scanning = true
|
||||
if pingOnly {
|
||||
f.pingBtn.SetText("停止Ping")
|
||||
f.scanBtn.Disable()
|
||||
f.setInputsEnabled(false)
|
||||
f.progress.SetValue(0)
|
||||
f.output.Append("开始Ping... (TODO: 接入扫描逻辑)\n")
|
||||
} else {
|
||||
f.scanning = false
|
||||
f.pingBtn.SetText("仅Ping")
|
||||
f.scanBtn.Enable()
|
||||
f.setInputsEnabled(true)
|
||||
f.output.Append("已停止Ping\n")
|
||||
f.scanBtn.SetText("停止扫描")
|
||||
f.pingBtn.Disable()
|
||||
}
|
||||
f.setInputsEnabled(false)
|
||||
f.progress.SetValue(0)
|
||||
|
||||
timeout := time.Duration(parseIntEntry(f.timeout, 100)) * time.Millisecond
|
||||
workers := parseIntEntry(f.threads, 64)
|
||||
mode := "扫描"
|
||||
if pingOnly {
|
||||
mode = "Ping"
|
||||
}
|
||||
f.appendOutput(fmt.Sprintf("开始%s (IP:%d 线程:%d 超时:%s)\n", mode, len(ips), workers, timeout))
|
||||
|
||||
d := &scan.Dispatcher{
|
||||
IPs: ips,
|
||||
Ports: ports,
|
||||
Timeout: timeout,
|
||||
Workers: workers,
|
||||
PingOnly: pingOnly,
|
||||
OnResult: func(r scan.Result) {
|
||||
fyne.Do(func() {
|
||||
f.appendOutput(r.Text + "\n")
|
||||
})
|
||||
},
|
||||
OnProgress: func(p scan.Progress) {
|
||||
pct := float64(p.Done) / float64(p.Total)
|
||||
fyne.Do(func() {
|
||||
f.progress.SetValue(pct)
|
||||
})
|
||||
},
|
||||
OnFinish: func() {
|
||||
fyne.Do(func() {
|
||||
f.resetAfterScan(pingOnly)
|
||||
f.appendOutput(fmt.Sprintf("%s完成\n", mode))
|
||||
})
|
||||
},
|
||||
}
|
||||
f.dispatcher = d
|
||||
go d.Start()
|
||||
}
|
||||
|
||||
func (f *scanForm) stopScan() {
|
||||
if f.dispatcher != nil {
|
||||
f.dispatcher.Stop()
|
||||
}
|
||||
}
|
||||
|
||||
func (f *scanForm) resetAfterScan(pingOnly bool) {
|
||||
f.scanning = false
|
||||
if pingOnly {
|
||||
f.pingBtn.SetText("仅Ping")
|
||||
} else {
|
||||
f.scanBtn.SetText("开始扫描")
|
||||
}
|
||||
f.scanBtn.Enable()
|
||||
f.pingBtn.Enable()
|
||||
f.setInputsEnabled(true)
|
||||
f.dispatcher = nil
|
||||
}
|
||||
|
||||
func (f *scanForm) setInputsEnabled(enabled bool) {
|
||||
@@ -162,7 +239,14 @@ func (f *scanForm) setInputsEnabled(enabled bool) {
|
||||
}
|
||||
|
||||
func (f *scanForm) saveOutput() {
|
||||
f.output.Append("(TODO: 保存输出到文件)\n")
|
||||
f.appendOutput("(TODO: 保存输出到文件)\n")
|
||||
}
|
||||
|
||||
func (f *scanForm) appendOutput(text string) {
|
||||
f.output.Append(text)
|
||||
f.output.CursorRow = strings.Count(f.output.Text, "\n")
|
||||
f.output.CursorColumn = 0
|
||||
f.output.Refresh()
|
||||
}
|
||||
|
||||
func (f *scanForm) openURL(urlStr string) {
|
||||
@@ -185,3 +269,11 @@ func newIntEntry(val, min, max int) *widget.Entry {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
func parseIntEntry(e *widget.Entry, fallback int) int {
|
||||
n, err := strconv.Atoi(e.Text)
|
||||
if err != nil || n <= 0 {
|
||||
return fallback
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user