本文介绍3种TCP连接异常的情况。

1.server端没有启动,client尝试连接

./client
dial failed: dial tcp 127.0.0.1:8080: connect: connection refused

通过tcpdump抓包,可以看到当server没有启动的时候,client向server8080端口发送数据后,client端会收到RST。

2.client端读数据,突然异常退出或直接close连接

2.1 准备

server

server等待连接,如果有client连接过来,连接建立后,会向client发送数据。

server代码如下:

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") }

client

client端连接server,并接收server端数据。

client代码如下:

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))
} }

2.2 操作步骤如下

(1).client与server建立连接后

(2).启动server

(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。

3.server端写数据,突然异常退出或直接close连接

3.1 准备

server、client代码同上。

3.2 操作步骤

(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

4.总结

  • 如果server端没有启动,client尝试连接时,会收到RST。

  • 连接建立后,如果读端或者写端关闭连接,具体分两种情况:

    • 如果读端关闭连接,写端继续写,第一次写,会收到RST,再写,报错broken pipe
    • 如果写端关闭连接,读端继续读,报错EOF

TCP连接异常:broken pipe 和EOF的更多相关文章

  1. TCP连接异常断开检测(转)

    TCP是一种面向连接的协议,连接的建立和断开需要通过收发相应的分节来实现.某些时候,由于网络的故障或是一方主机的突然崩溃而另一方无法检测到,以致始终保持着不存在的连接.下面介绍一种方法来检测这种异常断 ...

  2. (转)TCP连接异常断开检测

    TCP是一种面向连接的协议,连接的建立和断开需要通过收发相应的分节来实现.某些时候,由于网络的故障或是一方主机的突然崩溃而另一方无法检测到,以致始终保持着不存在的连接.下面介绍一种方法来检测这种异常断 ...

  3. 针对TCP连接异常断开的分析

    我们知道,一个基于TCP/IP的客户端-服务器的程序中,正常情况下,我会是启动服务器使其在一个端口上监听请求,等待客户端的连接:通过TCP的三次握手,客户端能够通过socket建立一个到服务器的连接: ...

  4. 关于心跳ajax请求pending状态(被挂起),stalled时间过长的问题。涉及tcp连接异常。

    环境:景安快云服务器(听说很垃圾,但是公司买的,我也刚来),CentOS-6.8-x86_64,Apache,MySQL5.1,PHP5.3. 问题:现公司有一个php系统,需要重复向后台发送ajax ...

  5. jedis异常Broken pipe (Write failed)

    异常:java.net.SocketException: Broken pipe (Write failed); nested exception is redis.clients.jedis.exc ...

  6. 我为 Netty 贡献源码 | 且看 Netty 如何应对 TCP 连接的正常关闭,异常关闭,半关闭场景

    欢迎关注公众号:bin的技术小屋,本文图片加载不出来的话可查看公众号原文 本系列Netty源码解析文章基于 4.1.56.Final版本 写在前面..... 本文是笔者肉眼盯 Bug 系列的第三弹,前 ...

  7. java.io.IOException 断开的管道 解决方法 ClientAbortException: java.io.IOException: Broken pipe

    今天公司技术支持的童鞋报告一个客户的服务不工作了,紧急求助,于是远程登陆上服务器排查问题. 查看采集数据的tomcat日志,习惯性的先翻到日志的最后去查看有没有异常的打印,果然发现了好几种异常信息,但 ...

  8. tcp连接时,BROKEN PIPE错误的原因以及解决方法

    问题: 写了一个server和一个client,UNIX套接字的,server不断接收消息并打印出来,client是一个交互程序,输入一个消息回车发送,接着又可以输入消息.出问题了:当server监听 ...

  9. 从tcp原理角度理解Broken pipe和Connection reset by peer的区别

    从tcp原理角度理解Broken pipe和Connection reset by peer的区别 http://lovestblog.cn/blog/2014/05/20/tcp-broken-pi ...

随机推荐

  1. redis 脑裂等极端情况分析

    脑裂真的是一个很头疼的问题(ps: 脑袋都裂开了,能不疼吗?),看下面的图: 一.哨兵(sentinel)模式下的脑裂 如上图,1个master与3个slave组成的哨兵模式(哨兵独立部署于其它机器) ...

  2. 2017-10-27模拟赛2-T1 选举(election.*)

    Description 题目描述 C国的总统选举委员会最近遇到了一些麻烦. 他们在统计各省对H先生的支持率(百分比)时,把支持率四舍五入到了整数.等他们公布结果后,该国媒体发现这些省份的支持率之和不等 ...

  3. pycharm环境下用Python+Django开发web搭建

    1.安装pycharm: 2.安装Python: 3.安装mysql: 4.安装Django; pip3 install django 5.创建Django工程命令方式: # 创建Django程序 d ...

  4. oracle数据库实例启动与关闭

    区分数据库与实例:实例是指各种内存结构和服务进程,数据库是指基于磁盘存储的数据文件.控制文件.参数文件.日志文件和归档日志文件组成的物里文件集合. 数据库实例启动: startup [nomount ...

  5. HashMap(1.8)理解

    先放一个流程图了解一下HashMap的put()操作: 1.HashMap底层采用数组.链表.红黑树来实现. 2.表的长度一定是2^n(便于快速计算hash值和扩展),若初始化时指定容量不满足,则Ha ...

  6. Win32线程——等待另一个线程结束

    转载: https://blog.csdn.net/yss28/article/details/53646627 <Win32多线程程序设计>–Jim Beveridge & Ro ...

  7. 已经在Git Server服务器上导入了SSH公钥,可用TortoiseGit同步代码时,还是提示输入密码?

    GitHub虽好,但毕竟在国内访问不是很稳定,速度也不快,而且推送到上面的源码等资料必须公开,除非你给他交了保护费:所以有条件的话,建议大家搭建自己的Git Server.本地和局域网服务器都好,不信 ...

  8. 增长java中数组的长度

    package month_201711; import java.util.Arrays;/** * 数组长度+1 * @author watchfree * */public class Main ...

  9. 解决 Unknown action buyram in contract eosio 错误

  10. 如何在运行时(Runtime)获得泛型的真正类型

    前言 由于Java 的类型擦除机制,在编译时泛型都被转为了Object,例如List<String>经过编译之后将变为类型 List.可以通过以下的方式再运行时获得泛型的真正类型 泛型如何 ...