From 3de2668286bec3aeb2188b2de7aab8a2650acd2b Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 25 Apr 2026 23:00:23 +0800 Subject: [PATCH] =?UTF-8?q?Fix:=20=E5=A2=9E=E5=BC=BASSH=E4=BC=9A=E8=AF=9D?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=92=8C=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加会话创建重试机制(最多3次) - 允许部分命令失败而不中断整个扫描 - 改进错误提示和日志输出 - 解决H3C设备LLDP命令会话拒绝问题 --- internal/device/parser.go | 18 ++++++++++++------ internal/ssh/client.go | 20 ++++++++++++++++++-- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/internal/device/parser.go b/internal/device/parser.go index 85d0b5e..5790414 100644 --- a/internal/device/parser.go +++ b/internal/device/parser.go @@ -1,6 +1,7 @@ package device import ( + "fmt" "network-topology-discovery/pkg/models" sshclient "network-topology-discovery/internal/ssh" ) @@ -74,12 +75,17 @@ func DiscoverDevice(ip string, deviceType models.DeviceType, username, password // 获取命令列表 commands := parser.GetCommands() - // 执行命令 - outputs, err := client.ExecuteCommands(commands) - if err != nil { - device.ScanStatus = "failed" - device.ErrorMessage = err.Error() - return device, err + // 执行命令 - 允许部分命令失败 + outputs := make([]string, 0, len(commands)) + for _, cmd := range commands { + output, err := client.ExecuteCommand(cmd) + if err != nil { + // 记录警告但继续执行其他命令 + fmt.Printf("Warning: command '%s' failed: %v\n", cmd, err) + outputs = append(outputs, "") + } else { + outputs = append(outputs, output) + } } // 解析输出 diff --git a/internal/ssh/client.go b/internal/ssh/client.go index f46188e..e3534fb 100644 --- a/internal/ssh/client.go +++ b/internal/ssh/client.go @@ -121,9 +121,25 @@ func (c *Client) ExecuteCommand(command string) (string, error) { return "", fmt.Errorf("not connected") } - session, err := c.client.NewSession() + // 重试机制,处理会话创建失败的情况 + var session *ssh.Session + var err error + maxRetries := 3 + + for i := 0; i < maxRetries; i++ { + session, err = c.client.NewSession() + if err == nil { + break + } + + // 如果是会话拒绝错误,等待后重试 + if i < maxRetries-1 { + time.Sleep(time.Duration(i+1) * 500 * time.Millisecond) + } + } + if err != nil { - return "", fmt.Errorf("failed to create session: %w", err) + return "", fmt.Errorf("failed to create session after %d retries: %w", maxRetries, err) } defer session.Close()