1.我们可以在同一个 net.UDPConn 或 net.TCPConn 对象上从一个线程调用 send 并从另一个线程调用 recv 吗?2.我们可以从同一个net.UDPConn 或net.TCPConn 对象上的不同线程并行调用多个发送吗?我也找不到同样的好文档。golang socket api线程安全吗?我发现很难测试它是否是线程安全的。方向上的任何指示都会有所帮助。我的测试代码如下:package mainimport ( "fmt" "net" "sync")func udp_server() { // create listen conn, err := net.ListenUDP("udp", &net.UDPAddr{ IP: net.IPv4(0, 0, 0, 0), Port: 8080, }) if err != nil { fmt.Println("listen fail", err) return } defer conn.Close() var wg sync.WaitGroup for i := 0; i < 10; i = i + 1 { wg.Add(1) go func(socket *net.UDPConn) { defer wg.Done() for { // read data data := make([]byte, 4096) read, remoteAddr, err := socket.ReadFromUDP(data) if err != nil { fmt.Println("read data fail!", err) continue } fmt.Println(read, remoteAddr) fmt.Printf("%s\n\n", data) // send data senddata := []byte("hello client!") _, err = socket.WriteToUDP(senddata, remoteAddr) if err != nil { return fmt.Println("send data fail!", err) } } }(conn) } wg.Wait()}func main() { udp_server()}这个测试代码可以吗?
2 回答
摇曳的蔷薇
TA贡献1793条经验 获得超6个赞
多个 goroutine 可以同时调用 Conn 上的方法。
我上面的文档的解释,是什么灾难会发生,如果你调用Read
,并Write
在net.Conn
多个走程序,并调用Write
一个net.Conn
从多个走程序会如此系列化,从2个独立的呼叫字节Write
不会交错因为它们被写入网络。
您提供的代码的问题在于,无法保证Write
一次性写入提供给它的整个字节片。您忽略了已写入多少字节的指示。
_, err = socket.WriteToUDP(senddata, remoteAddr)
所以为了确保你写了所有你需要循环和调用的东西,Write
直到所有的都senddata
被发送。但net.Conn
只能确保来自对 Write的单个调用的数据不会交错。鉴于您可以通过多次调用发送单个数据块来写入,因此不能保证单个数据块能够完好无损地到达其目的地。
例如 3“你好客户!” 消息可以以下列形式到达。
“你好你好客户!客户!客户!”
因此,如果您希望net.Conn
从多个 go 例程中可靠地写入消息,则需要同步这些例程以确保单个消息完整写入。
如果我想这样做,作为第一次尝试,我将有一个 go 例程从一个或多个消息通道读取并写入一个net.Conn
,然后多个 go 例程可以写入这些消息通道。
- 2 回答
- 0 关注
- 196 浏览
添加回答
举报
0/150
提交
取消