Golang程序运行报错问题排查指南
Golang程序运行报错问题排查指南 大家好,我正在尝试使用 net/http、os、bufio 和 fmt 包在 Go 语言中编写一个目录枚举器。我是 Go 语言的新手,因为学习这门语言的时间还不长。代码如下:
package main
import (
"fmt"
"net/http"
"os"
"bufio"
)
func main() {
// 代码内容...
}
2 回复
$ go vet main.go
./main.go:23:22: Sprint call has possible formatting directive %s
$
Sprint
req,err1:=http.Get(fmt.Sprint("%s/%s",os.Args[1],scanner.Text()))
应该使用 Sprintf
req,err1:=http.Get(fmt.Sprintf("%s/%s",os.Args[1],scanner.Text()))
另外,请处理错误。例如:
req,err1:=http.Get(fmt.Sprintf("%s/%s",os.Args[1],scanner.Text()))
if err1 != nil {
// 处理错误
continue
}
更多关于Golang程序运行报错问题排查指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
以下是一个完整的目录枚举器示例,包含错误处理和常见问题排查方法:
package main
import (
"bufio"
"fmt"
"net/http"
"os"
"strings"
"sync"
"time"
)
func main() {
// 1. 检查命令行参数
if len(os.Args) < 3 {
fmt.Println("用法: go run main.go <目标URL> <字典文件>")
fmt.Println("示例: go run main.go http://example.com wordlist.txt")
os.Exit(1)
}
targetURL := os.Args[1]
wordlistPath := os.Args[2]
// 2. 验证URL格式
if !strings.HasPrefix(targetURL, "http://") && !strings.HasPrefix(targetURL, "https://") {
fmt.Printf("错误: URL必须以http://或https://开头\n")
os.Exit(1)
}
// 3. 打开字典文件
file, err := os.Open(wordlistPath)
if err != nil {
fmt.Printf("打开文件错误: %v\n", err)
os.Exit(1)
}
defer file.Close()
// 4. 创建HTTP客户端(设置超时避免阻塞)
client := &http.Client{
Timeout: 10 * time.Second,
}
// 5. 使用WaitGroup控制并发
var wg sync.WaitGroup
scanner := bufio.NewScanner(file)
semaphore := make(chan struct{}, 10) // 限制并发数为10
fmt.Printf("开始枚举: %s\n", targetURL)
fmt.Println("=" * 50)
for scanner.Scan() {
path := strings.TrimSpace(scanner.Text())
if path == "" {
continue
}
wg.Add(1)
semaphore <- struct{}{}
go func(p string) {
defer wg.Done()
defer func() { <-semaphore }()
url := fmt.Sprintf("%s/%s", targetURL, p)
checkURL(client, url)
}(path)
}
wg.Wait()
fmt.Println("=" * 50)
fmt.Println("枚举完成")
}
func checkURL(client *http.Client, url string) {
resp, err := client.Get(url)
if err != nil {
// 网络错误处理
fmt.Printf("请求失败 %s: %v\n", url, err)
return
}
defer resp.Body.Close()
// 只显示成功响应的URL
if resp.StatusCode >= 200 && resp.StatusCode < 400 {
fmt.Printf("[%d] %s\n", resp.StatusCode, url)
}
}
常见错误排查指南:
- 网络连接错误:
resp, err := http.Get(url)
if err != nil {
// 检查具体错误类型
if os.IsTimeout(err) {
fmt.Println("连接超时")
} else if strings.Contains(err.Error(), "connection refused") {
fmt.Println("连接被拒绝")
} else if strings.Contains(err.Error(), "no such host") {
fmt.Println("域名解析失败")
}
return
}
- 文件读取错误:
file, err := os.Open("wordlist.txt")
if err != nil {
if os.IsNotExist(err) {
fmt.Println("字典文件不存在")
} else if os.IsPermission(err) {
fmt.Println("没有文件读取权限")
}
os.Exit(1)
}
- 并发控制问题:
// 使用带缓冲的channel控制并发数
maxConcurrent := 20
sem := make(chan struct{}, maxConcurrent)
for _, task := range tasks {
sem <- struct{}{}
go func(t string) {
defer func() { <-sem }()
// 执行任务
}(task)
}
- 内存泄漏排查:
// 确保response body被关闭
resp, err := http.Get(url)
if err != nil {
return
}
defer resp.Body.Close() // 必须关闭
// 读取body内容
body, err := io.ReadAll(resp.Body)
if err != nil {
return
}
- 超时设置:
client := &http.Client{
Timeout: 30 * time.Second,
Transport: &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 90 * time.Second,
},
}
运行程序时可能遇到的错误:
# 1. 缺少参数
$ go run main.go
用法: go run main.go <目标URL> <字典文件>
# 2. 文件不存在
$ go run main.go http://example.com notexist.txt
打开文件错误: open notexist.txt: no such file or directory
# 3. 网络超时
请求失败 http://example.com/timeout: Get "http://example.com/timeout": context deadline exceeded
# 4. 连接被拒绝
请求失败 http://localhost:9999: Get "http://localhost:9999": dial tcp 127.0.0.1:9999: connect: connection refused
使用示例:
# 编译程序
go build -o dir_enum main.go
# 运行程序
./dir_enum http://example.com wordlist.txt

