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

golang net.UDPConn 和 net.TCPConn 线程安全吗??

golang net.UDPConn 和 net.TCPConn 线程安全吗??

Go
当年话下 2021-09-13 19:36:06
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贡献1777条经验 获得超10个赞

的文档net.Conn说:

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


查看完整回答
反对 回复 2021-09-13
?
摇曳的蔷薇

TA贡献1793条经验 获得超6个赞

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

我上面的文档的解释,是什么灾难会发生,如果你调用Read,并Writenet.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 例程可以写入这些消息通道。


查看完整回答
反对 回复 2021-09-13
  • 2 回答
  • 0 关注
  • 196 浏览
慕课专栏
更多

添加回答

举报

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