本文介紹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