Browse Source

连接bug修改

xu 2 months ago
parent
commit
7747eb931d
4 changed files with 32 additions and 19 deletions
  1. 1 1
      build.bat
  2. 2 0
      build1.bat
  3. 0 9
      dao/connection.go
  4. 29 9
      utils/myTool.go

+ 1 - 1
build.bat

@@ -1,2 +1,2 @@
 %此脚本需要在命令窗口执行,不能直接运行%
-go env -w CGO_ENABLED=0 GOOS=linux GOARCH=amd64 && go build -o build/jx_ld_server ./
+go env -w CGO_ENABLED=0 GOOS=windows GOARCH=amd64 && go build -ldflags -H=windowsgui -o build/jx_ld_server.exe ./

+ 2 - 0
build1.bat

@@ -0,0 +1,2 @@
+%此脚本需要在命令窗口执行,不能直接运行%
+go env -w CGO_ENABLED=0 GOOS=linux GOARCH=amd64 && go build -o build/jx_ld_server ./

+ 0 - 9
dao/connection.go

@@ -1,9 +0,0 @@
-package dao
-
-import "github.com/goburrow/modbus"
-
-type Connection struct {
-	Path string        `json:"path"`
-	ID   string        `json:"id"`
-	Tcp  modbus.Client `json:"tcp"`
-}

+ 29 - 9
utils/myTool.go

@@ -9,6 +9,7 @@ import (
 	"path/filepath"
 	"server/dao"
 	"server/logger"
+	"strings"
 	"time"
 )
 
@@ -156,8 +157,9 @@ func SaveData(path string, parameter interface{}) error {
 }
 
 const (
-	maxRetries   = 3               // 最大重试次数
-	writeTimeout = 5 * time.Second // 写入超时时间
+	maxRetries    = 3               // 最大重试次数
+	writeTimeout  = 5 * time.Second // 写入超时时间
+	reconnectWait = 2 * time.Second // 重连等待时间
 )
 
 func WriteDevice(frame []byte, conn net.Conn) error {
@@ -169,13 +171,12 @@ func WriteDevice(frame []byte, conn net.Conn) error {
 
 		_, err := conn.Write(frame)
 		if err == nil {
-			logger.Get().Infof("Successfully wrote frame to device")
 			return nil
 		}
 
-		// 检查是否是 broken pipe 或 connection reset by peer 错误
-		if ne, ok := err.(*net.OpError); ok && (ne.Err.Error() == "broken pipe" || ne.Err.Error() == "connection reset by peer") {
-			logger.Get().Warnf("Connection closed by peer or broken pipe, retrying (%d/%d)", attempts+1, maxRetries)
+		// 检查是否是对端强制关闭连接的错误
+		if ne, ok := err.(*net.OpError); ok && (strings.Contains(ne.Err.Error(), "forcibly closed") || strings.Contains(ne.Err.Error(), "broken pipe") || strings.Contains(ne.Err.Error(), "connection reset")) {
+			logger.Get().Warnf("Connection forcibly closed by peer, retrying (%d/%d)", attempts+1, maxRetries)
 
 			// 关闭旧连接
 			if err := conn.Close(); err != nil {
@@ -184,16 +185,26 @@ func WriteDevice(frame []byte, conn net.Conn) error {
 
 			// 尝试重新建立连接
 			var newConn net.Conn
-			newConn, err = net.Dial("tcp", conn.RemoteAddr().String())
+			remoteAddr := conn.RemoteAddr().String()
+
+			// 解析原始连接的远程地址和网络接口
+			addr, networkInterface, err := parseRemoteAddr(remoteAddr)
 			if err != nil {
-				logger.Get().Errorf("Reconnect failed: %v", err)
+				logger.Get().Errorf("Failed to parse remote address: %v", err)
 				continue // 继续下一次重试
 			}
+
+			newConn, err = net.Dial("tcp", fmt.Sprintf("%s%%%s", addr, networkInterface))
+			if err != nil {
+				logger.Get().Errorf("Reconnect failed: %v", err)
+				time.Sleep(reconnectWait) // 等待一段时间后重试
+				continue                  // 继续下一次重试
+			}
 			conn = newConn
 			continue // 重试写入
 		}
 
-		// 如果不是 broken pipe 或 connection reset by peer,则直接返回错误
+		// 如果不是对端强制关闭连接的错误,则直接返回错误
 		logger.Get().Errorf("Write failed: %v", err)
 		return fmt.Errorf("write failed after %d retries: %v", attempts+1, err)
 	}
@@ -201,6 +212,15 @@ func WriteDevice(frame []byte, conn net.Conn) error {
 	return fmt.Errorf("failed to write after %d retries", maxRetries)
 }
 
+// 解析远程地址,提取 IP 地址和网络接口名称
+func parseRemoteAddr(addr string) (string, string, error) {
+	parts := strings.Split(addr, "%")
+	if len(parts) != 2 {
+		return "", "", fmt.Errorf("invalid remote address format: %s", addr)
+	}
+	return parts[0], parts[1], nil
+}
+
 func WriteAndReadDevice(frame []byte, conn net.Conn, former, after int) (data []byte, err error) {
 	// 发送 Modbus RTU 帧
 	n, err := conn.Write(frame)