在一个 goroutine 中保持 TCP 连接的活跃,并在连接丢失时检查是否超时。

huangapple go评论85阅读模式
英文:

Keeping a TCP connection alive in a goroutine and check if it timesout if the connection is lost

问题

我有一个正在运行的TCP服务器,监听一个端口,并有一个用于处理连接的Go协程。我想知道是否可以为每个连接运行一个Go协程,通过net.SetKeepAlive(true)保持连接的活跃状态。同时,如果连接超时,是否可以进行错误处理,执行清理函数,比如从列表中移除连接?

处理协程:

func handleConnection(conn net.Conn, rec chan string) {
   var item QueItem
   buf := make([]byte, bufSize)
   l, err := conn.Read(buf)
   if err != nil || l < 0 {
   	fmt.Println("从连接中读取错误:", conn)
   	fmt.Println("读取错误:", err)
   }

   err = json.Unmarshal(buf[:l], &item)
   if err != nil {
   	 fmt.Println("转换为JSON时出错", err)
   }

  fmt.Printf("接收到: %+v\n", item)
  fmt.Println("接收自:", conn.RemoteAddr())
  rec <- item.IP
}

TCP服务器:

for {
	conn, err := ln.Accept()
	if err != nil {
		fmt.Println("无法接受连接", err)
		log.Println("无法接受连接", err)
	}
	go handleConnection(conn, received)
}
英文:

I have a TCP server up and running listetning to a port and a go routine for handeling the connections. I wonder if it's possible to have a go routine running for every connection keeping them alive with net.SetKeepAlive(true). Also with error handling so that if the connection times out it will execute cleanup functions like removing the connection from a list?

Handle routine:

func handleConnection(conn net.Conn, rec chan string) {
   var item QueItem
   buf := make([]byte, bufSize)
   l, err := conn.Read(buf)
   if err != nil || l &lt; 0 {
	fmt.Println(&quot;Error reading from conn: &quot;, conn)
	fmt.Println(&quot;Error reading: &quot;, err)
   }

   err = json.Unmarshal(buf[:l], &amp;item)
   if err != nil {
	 fmt.Println(&quot;Error converting to JSON&quot;, jErr)
   }

  fmt.Printf(&quot;Received : %+v\n&quot;, item)
  fmt.Println(&quot;recived from:&quot;, conn.RemoteAddr())
  rec &lt;- item.IP
}

TCPserver:

for {
	conn, err := ln.Accept()
	if err != nil {
		fmt.Println(&quot;No accept&quot;, err)
		log.Println(&quot;Unable to accept connection&quot;, err)
	}
	go handleConnection(conn, recived)
}

答案1

得分: 4

为了对已建立的TCP连接进行检查,可以通过两种方式进行“保持活动”机制。

在应用层:
在空闲状态下,客户端和服务器都同意使用一种协议向对方发送预定的数据包。如果在一定时间内没有收到对等方的消息,可能表示连接存在问题。

在TCP层:
启用TCP堆栈来检查连接状态。启用此机制的TCP层将定期发送“保持活动”消息。它期望对等的TCP堆栈发送“保持活动确认”。在必要的重传后,如果没有收到确认,表示存在连接问题,应用程序将得到相应的通知。

我认为net.SetKeepAlive(true)是一种通知TCP进行保持活动的Go语言方式。你不需要在Go协程中进行任何特殊的构造。

TCP的“保持活动”机制运行良好。应用程序不需要负担检查连接状态的任务。

英文:

To keep a check on the established TCP connections, one can do keep-alive mechanism in two ways.

At application level:
In idle conditions both client and server agree on a protocol to send pre-determined packets to each other. Lack of a message from peer with in certain time can signal a problem in the connection.

At TCP layer:
Enable the TCP stack to check the connection status. The TCP layer at which this mechanism is enabled will send keep-alive messages at regular determined interval. It would expect that the peer TCP stack send keep-alive-ack. Absence of ACK after needed re-transmission signals connection problem and the application would be duly notified.

I think net.SetKeepAlive(true) is a go way of informing the TCP to do keep-alive. You need not do any thing special constructs in go routine.

TCP keep-alive works well. Application need not be burdened to check for connection status

huangapple
  • 本文由 发表于 2015年4月26日 19:27:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/29877003.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定