我在Golang网络包上做了一些实验。
当我使用客户端连接服务器(没有关闭连接)时,我发现服务器有这样的错误: "太多的打开文件" 这是有道理的,因为我的操作系统中设置了文件打开限制。
但是,我发现客户端在连接服务器时从未返回错误,这很奇怪,因为服务器已经拒绝了一些连接请求。
// Server code
package main
import (
"log"
"net"
)
func main() {
listener, err := net.Listen("tcp", "localhost:7070")
if err != nil {
log.Fatalln(err)
}
for {
conn, err := listener.Accept()
if err != nil {
log.Println(err, conn)
continue
}
}
}
// Client code
package main
import (
"log"
"net"
)
func main() {
cnt := 0
for {
conn, err := net.Dial("tcp", "localhost:7070")
if err != nil {
log.Println("!", conn.RemoteAddr())
continue
}
cnt++
n, err := conn.Write([]byte("hello"))
if err != nil {
log.Fatalln(err)
}
log.Println(cnt, n)
}
}
谁能告诉我这里发生了什么?
THX。
答案 0 :(得分:2)
在服务器应用程序接受之前,内核TCP / IP堆栈在服务器上异步执行TCP握手,因此即使您的服务器代码无法接受连接,它也将在TCP级别连接。这就是net.Dial()成功的原因。
当您的服务器代码接受连接失败时,TCP / IP堆栈将关闭连接。
net.Write()只是将数据传递到本地TCP / IP堆栈,这将异步发送数据。如果在服务器代码有机会(未能)接受连接之前完成此操作,则没有错误,因为tcp连接仍然可以运行。如果您的客户端执行2.写入,或者可能稍等一下,net.Write()也应该失败。