为了账号安全,请及时绑定邮箱和手机立即绑定

golang中两个不同tcp客户端之间的中继数据

golang中两个不同tcp客户端之间的中继数据

Go
长风秋雁 2023-06-26 18:04:33
我正在编写一个 TCP 服务器,它同时接受来自移动设备和一些 WiFi 设备(IOT)的多个连接。连接一旦建立就需要维持,如果没有收到心跳,则超时 30 秒。所以它类似于以下内容:// clientsMap map[string] connfunc someFunction() {    conn, err := s.listener.Accept()    // I store the conn in clientsMap    // so I can access it, for brevity not     // shown here, then:    go serve(connn)}func serve(conn net.Conn) {    timeoutDuration := 30 * time.Second    conn.SetReadDeadline(time.Now().Add(timeoutDuration))    for {        msgBuffer := make([]byte, 2048)        msgBufferLen, err := conn.Read(msgBuffer)        // do something with the stuff    }}所以每个客户端都有一个 goroutine。每个客户端一旦连接到服务器,就会等待读取。然后服务器处理读取的内容。问题是我有时需要从一个客户端读取数据,然后将数据传递到另一个客户端(在移动设备和 WiFi 设备之间)。我已将连接存储在clientsMap. 所以我可以随时访问它。但是由于每个客户端都由一个 goroutine 处理,我是否应该使用通道将数据从一个客户端传递到另一个客户端?但是如果 goroutine 被阻塞等待挂起的读取,我如何让它也等待来自通道的数据?或者我应该从clientsMap中获取对方的连接并写入它?
查看完整描述

1 回答

?
蝴蝶不菲

TA贡献1810条经验 获得超4个赞

net.Conn 的文档明确指出:

多个 goroutine 可以同时调用 Conn 上的方法。

所以是的,只需写入连接就可以了。您应该注意对每条要发送的消息发出一次 Write 调用。如果您多次调用 Write,则可能会面临来自不同移动设备的消息交错的风险。这意味着直接调用 Write,而不是通过其他 API(换句话说,不包装连接)。例如,以下内容是不安全的:

json.NewEncoder(conn).Encode(myValue) // use json.Marshal(myValue) instead
io.Copy(conn, src)                    // use io.ReadAll(src) instead


查看完整回答
反对 回复 2023-06-26
  • 1 回答
  • 0 关注
  • 88 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信