本文介绍3种TCP链接异常的状况。tcp
./client dial failed: dial tcp 127.0.0.1:8080: connect: connection refused
经过tcpdump抓包,能够看到当server没有启动的时候,client向server8080端口发送数据后,client端会收到RST。code
serverserver
server等待链接,若是有client链接过来,链接创建后,会向client发送数据。进程
server代码以下:ip
package main import ( "net" "log" "time" ) func main() { addr := "0.0.0.0:8080" tcpAddr, err := net.ResolveTCPAddr("tcp",addr) if err != nil { log.Fatalf("net.ResovleTCPAddr fail:%s", addr) } listener, err := net.ListenTCP("tcp", tcpAddr) if err != nil { log.Fatalf("listen %s fail: %s", addr, err) } else { log.Println("rpc listening", addr) } for { conn, err := listener.Accept() if err != nil { log.Println("listener.Accept error:", err) continue } go handleConnection(conn) } } func handleConnection(conn net.Conn) { defer conn.Close() var buffer []byte = []byte("You are welcome. I'm server.") for { time.Sleep(3*time.Second) n, err := conn.Write(buffer) if err != nil { log.Println("Write error:", err) break } log.Println("send:", n) } log.Println("connetion end") }
clientrpc
client端链接server,并接收server端数据。string
client代码以下:it
package main import ( "log" "net" "os" ) func main() { conn, err := net.Dial("tcp", "127.0.0.1:8080") if err != nil { log.Println("dial failed:", err) os.Exit(1) } defer conn.Close() buffer := make([]byte, 512) for { n, err := conn.Read(buffer) if err != nil { log.Println("Read failed:", err) return } log.Println("count:", n, "msg:", string(buffer)) } }
(1).client与server创建链接后pip
(2).启动serverio
(3).启动client
(4).client异常退出
client 进程异常退出或者close链接,都会发送FIN。
./client 2019/04/13 19:45:44 count: 28 msg: You are welcome. I'm server. ^C
19:45:44后, Ctrl + C 退出
(5).查看server端报错
./server 2019/04/13 19:45:17 rpc listening 0.0.0.0:8080 2019/04/13 19:45:44 send: 28 2019/04/13 19:45:47 send: 28 2019/04/13 19:45:50 Write error: write tcp 127.0.0.1:8080->127.0.0.1:62785: write: broken pipe 2019/04/13 19:45:50 connetion end
client退出后,server发送了两次数据,第一次没有报错,第二次报错:
2019/04/11 15:49:04 send: 28 2019/04/11 15:49:07 Write error: write tcp 127.0.0.1:8080->127.0.0.1:54631: write: broken pipe
经过tcpdump抓包能够发现,client退出后,server第一次发送给client,client返回给server RST。
第二次在这个RST的链接上,server继续发送,出现broken pipe。
server、client代码同上。
(1).client与server创建链接后
(2).启动server
(3).启动client
(4).server异常退出
server 进程异常退出或者close链接,都会发送FIN。
./server 2019/04/11 15:58:46 rpc listening 0.0.0.0:8080 2019/04/11 15:58:54 send: 28 2019/04/11 15:58:57 send: 28 ^C
(5).查看client报错
./client 2019/04/11 15:58:54 count: 28 msg: You are welcome. I'm server. 2019/04/11 15:58:57 count: 28 msg: You are welcome. I'm server. 2019/04/11 15:58:58 Read failed: EOF
若是server端没有启动,client尝试链接时,会收到RST。
链接创建后,若是读端或者写端关闭链接,具体分两种状况:
broken pipe
EOF