go - 在golang中两个不同的tcp客户端之间中继数据
问题描述
我正在编写一个 TCP 服务器,它同时接受来自移动设备和一些 WiFi 设备 (IOT) 的多个连接。连接一旦建立就需要保持,如果没有收到心跳,则超时 30 秒。所以它类似于以下内容:
// clientsMap map[string] conn
func 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获取对方的连接并写入它?
解决方案
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
推荐阅读
- python - 如何比较 1 个表中对应于日期的 2 个值并在 dyanmo db 中创建另一列
- react-native - 导航:project.testscreen 注册结果为 'undefined'
- selenium - 使用具有相同 selenium 测试的不同页面对象集
- amazon-web-services - 通过 cloudformation 更新现有角色的 iam 策略
- r - 提取由相对于其他相对定位字符定位定义的子字符串
- c# - 使用 ReadPrinter Winspool.Drv 读取打印机数据
- antlr - 如何使用 antlr4 更改上下文的文本
- windows - 在 Python 中执行命令而不关闭 CMD shell
- c# - ClosedXML 在部署到 aws lambda 时引发异常
- c++ - 何时用指针调用 C++ 类构造函数?