|
@@ -5,6 +5,7 @@ import (
|
|
|
"fmt"
|
|
|
"log"
|
|
|
"net"
|
|
|
+ "os"
|
|
|
"runtime"
|
|
|
"runtime/debug"
|
|
|
"server/dao"
|
|
@@ -13,7 +14,9 @@ import (
|
|
|
"server/service"
|
|
|
"server/utils"
|
|
|
"strconv"
|
|
|
+ "strings"
|
|
|
"sync"
|
|
|
+ "syscall"
|
|
|
"time"
|
|
|
)
|
|
|
|
|
@@ -93,8 +96,19 @@ func (o *ModbusHandler) ReadAndHandle(conn net.Conn, deviceId string) {
|
|
|
for {
|
|
|
buffer := make([]byte, 1024)
|
|
|
n, err := conn.Read(buffer)
|
|
|
+ //if err != nil {
|
|
|
+ // log.Println("Error reading from connection:", err)
|
|
|
+ // return
|
|
|
+ //}
|
|
|
if err != nil {
|
|
|
- log.Println("Error reading from connection:", err)
|
|
|
+ if isConnReset(err) {
|
|
|
+ fmt.Println("连接被远程主机强制关闭")
|
|
|
+ } else if os.IsTimeout(err) {
|
|
|
+ fmt.Println("读取操作超时")
|
|
|
+ } else {
|
|
|
+ // 处理其他类型的错误
|
|
|
+ fmt.Printf("读取错误: %s\n", err)
|
|
|
+ }
|
|
|
return
|
|
|
}
|
|
|
queueData := model.QueueData{
|
|
@@ -111,6 +125,27 @@ func (o *ModbusHandler) ReadAndHandle(conn net.Conn, deviceId string) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+func isConnReset(err error) bool {
|
|
|
+ if opErr, ok := err.(*net.OpError); ok {
|
|
|
+ if opErr.Err == syscall.ECONNRESET {
|
|
|
+ return true // Unix-like 系统上的 ECONNRESET
|
|
|
+ } else if runtime.GOOS == "windows" {
|
|
|
+ // Windows 上的 WSAECONNRESET 通常是通过错误消息识别的
|
|
|
+ if se, ok := opErr.Err.(*os.SyscallError); ok {
|
|
|
+ if errno, ok := se.Err.(syscall.Errno); ok {
|
|
|
+ if errno == 10054 { // 10054 对应 WSAECONNRESET
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if strings.Contains(opErr.Err.Error(), "WSAECONNRESET") {
|
|
|
+ // 如果错误消息包含 WSAECONNRESET,也认为是连接被重置
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
func (o *ModbusHandler) Handler() interface{} {
|
|
|
defer func() {
|
|
|
if err := recover(); err != nil {
|