tcp rst packet

研究生期间有一段时间就总被connection reset by peer折磨,昨天又遇到这种情况,郁闷,不得不搞清楚了

 

Shutting down a socket connection involves an exchange of protocol messages between the two endpoints, hereafter referred to as a shutdown sequence. Two general classes of shutdown sequences are defined: graceful and abortive (also called hard). In a graceful shutdown sequence, any data that has been queued, but not yet transmitted can be sent prior to the connection being closed. In an abortive shutdown, any unsent data is lost. The occurrence of a shutdown sequence (graceful or abortive) can also be used to provide an FD_CLOSE indication to the associated applications signifying that a shutdown is in progress.

 

意思就是说正常的流程是 data + FIN, 但也有可能是 data + rst + data, 后一种情况就是强制关闭,会导致客户端的connection reset by peer。

 

可以用linger这个选项来控制,setsockopt

 

但是,socket默认的情况就是如此,即会先发送数据,然后发送FIN,不会发送rst

 

所以,我遇到的问题不能用上面的方法来解决

 

我遇到的问题是,server没有读客户端发送的数据,而是直接发送数据,然后close,即在close的时候server的读缓存里还有数据

A                                            B
send( ) data →
data →
data →
recv( ) →ERROR ← RST close( )

 

解决方法包括:

1. 将所有数据读出

2. 调用shutdown,然后调用close

 

相关文章链接:

http://cs.baylor.edu/~donahoo/practical/CSockets/TCPRST.pdf

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用gopacket构建RST包的示例代码,以关闭TCP连接并将浏览器重定向到Google主页: ```go package main import ( "fmt" "net" "time" "github.com/google/gopacket" "github.com/google/gopacket/layers" ) func main() { // 创建一个IP层 ip := &layers.IPv4{ SrcIP: net.ParseIP("10.0.0.1"), DstIP: net.ParseIP("192.168.0.100"), Protocol: layers.IPProtocolTCP, } // 创建一个TCPtcp := &layers.TCP{ SrcPort: layers.TCPPort(12345), DstPort: layers.TCPPort(80), Seq: 123456789, Ack: 987654321, RST: true, Window: 0, } // 创建一个包含IP和TCP层的Packet pkt := gopacket.NewPacket( gopacket.Payload(nil), layers.LayerTypeIPv4, gopacket.Default, ) pkt.Layer(layers.LayerTypeIPv4).(*layers.IPv4) = *ip pkt.Layer(layers.LayerTypeTCP).(*layers.TCP) = *tcp // 打开一个raw socket连接,发送Packet conn, err := net.Dial("ip4:tcp", "192.168.0.100") if err != nil { panic(err) } defer conn.Close() if err := pkt.SerializeTo(conn); err != nil { panic(err) } // 等待一段时间,让浏览器收到RST包 time.Sleep(time.Second) // 发送一个HTTP重定向响应,将浏览器重定向到Google主页 response := "HTTP/1.1 302 Found\r\nLocation: https://www.google.com/\r\n\r\n" if _, err := conn.Write([]byte(response)); err != nil { panic(err) } fmt.Println("TCP连接已关闭并重定向到Google主页") } ``` 注意:这段代码需要在管理员权限下运行,因为它使用了raw socket。另外,它只能在Linux系统上运行,因为Windows和Mac OS X不支持发送RST包。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值