1.我们可以在同一个net.UDPConn或net.TCPConn对象上调用一个线程的发送和另一个线程的recv吗?
2.我们可以从同一网络上的不同线程并行调用多个发送.UDPConn或net.TCPConn对象吗?
我也找不到同样好的文档。 golang socket api是否安全?
我发现很难测试它是否是线程安全的。 任何指示方向都会有所帮助。
我的测试代码如下:
package main
import (
"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()
}
这个测试代码可以吗?
答案 0 :(得分:12)
net.Conn
的文档说:
多个goroutine可以同时调用Conn上的方法。
答案 1 :(得分:2)
多个goroutine可以同时调用Conn上的方法。
我对上述文档的解释是,如果您从多个go例程调用Read
上Write
和net.Conn
,并且调用Write
,则不会发生任何灾难性事件来自多个go例程的net.Conn
将被序列化,以便来自2个单独调用Write
的字节在写入网络时不会交错。
您提供的代码存在的问题是,无法保证Write
将一次性写入提供给它的整个字节切片。您忽略了已写入的字节数的指示。
_, err = socket.WriteToUDP(senddata, remoteAddr)
所以为了确保你写下你需要循环的所有内容并调用Write
直到发送了所有senddata
。但net.Conn
仅确保来自单调用Write的数据不会交错。鉴于您可能会发送一个包含多个写入调用的数据块,因此无法保证单个数据块能够完整地到达目标。
所以例如3&#34;你好客户!&#34;消息可以以下列形式到达。
&#34; hellohellohello客户!客户! !客户&#34;
因此,如果您希望在多个go例程的net.Conn
上编写可靠的消息,则需要同步这些例程以确保单个消息的完整写入。
如果我想这样做,作为第一次尝试,我将从一个或多个消息通道读取一个例行程序并写入net.Conn
,然后多个go例程可以写入这些消息通道。 / p>