网站首页 > 博客文章 正文
本文主要是想通过抓包工具分析一下TCP三次握手和断开过程:
1、TCP三次握手建立连接和断开连接解释,如下图:
2、通过WireShark抓包查看这个TCP过程,数据如下图和可以结合上图一起看:
3、为什么上图中的客户端在TIME-WAIT状态必须等待2MSL时间呢?
第一,为了保证客户端发送的最后一个ACK报文能够到达服务器。这个ACK报文段有可能丢失,因而使处在LAST-ACK状态的服务器收不到对已发送的FIN+ACK报文段的确认。服务器会超时重传这个FIN+ACK报文段,而客户端就能在2MSL时间内收到这个重传的FIN+ACK报文段。
如果客户端在TIME-WAIT状态不等待一段时间,而是在发送完ACK报文段后就立即释放连接,就无法收到服务器重传的FIN+ACK报文段,因而也不会再发送一次确认报文段。这样,服务器就无法按照正常的步骤进入CLOSED状态。
第二,客户端在发送完ACK报文段后,再经过2MSL时间,就可以使本连接持续的时间所产生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求的报文段。
什么是2MSL
MSL是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。因为tcp报文(segment)是ip数据报(datagram)的数据部分,具体称谓请参见《数据在网络各层中的称呼》一文,而ip头中有一个TTL域,TTL是time to live的缩写,中文可以译为“生存时间”,这个生存时间是由源主机设置初始值但不是存的具体时间,而是存储了一个ip数据报可以经过的最大路由数,每经过一个处理他的路由器此值就减1,当此值为0则数据报将被丢弃,同时发送ICMP报文通知源主机。RFC 793中规定MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等。
2MSL即两倍的MSL,TCP的TIME_WAIT状态也称为2MSL等待状态,当TCP的一端发起主动关闭,在发出最后一个ACK包后,即第3次握手完成后发送了第四次握手的ACK包后就进入了TIME_WAIT状态,必须在此状态上停留两倍的MSL时间,等待2MSL时间主要目的是怕最后一个ACK包对方没收到,那么对方在超时后将重发第三次握手的FIN包,主动关闭端接到重发的FIN包后可以再发一个ACK应答包。在TIME_WAIT状态时两端的端口不能使用,要等到2MSL时间结束才可继续使用。当连接处于2MSL等待阶段时任何迟到的报文段都将被丢弃。不过在实际应用中可以通过设置SO_REUSEADDR选项达到不必等待2MSL时间结束再使用此端口。
TTL与MSL是有关系的但不是简单的相等的关系,MSL要大于等于TTL。
4、Go实现客户端和服务器
TCP服务端代码:
package main
import (
"bufio"
"fmt"
"io"
"net"
)
//tcp server 服务端代码
func main() {
//定义一个tcp断点
var tcpAddr *net.TCPAddr
//通过ResolveTCPAddr实例一个具体的tcp断点
tcpAddr, _ = net.ResolveTCPAddr("tcp", "127.0.0.1:9999")
//打开一个tcp断点监听
tcpListener, _ := net.ListenTCP("tcp", tcpAddr)
defer tcpListener.Close()
fmt.Println("Server ready to read ...")
//循环接收客户端的连接,创建一个协程具体去处理连接
for {
tcpConn, err := tcpListener.AcceptTCP()
if err != nil {
fmt.Println(err)
continue
}
fmt.Println("A client connected :" + tcpConn.RemoteAddr().String())
go tcpPipe(tcpConn)
}
}
//具体处理连接过程方法
func tcpPipe(conn *net.TCPConn) {
//tcp连接的地址
ipStr := conn.RemoteAddr().String()
defer func() {
fmt.Println(" Disconnected : " + ipStr)
conn.Close()
}()
//获取一个连接的reader读取流
reader := bufio.NewReader(conn)
// i := 0
//接收并返回消息
for {
message, err := reader.ReadString('\n')
if err != nil || err == io.EOF {
break
}
fmt.Println(string(message))
}
}
TCP客户端代码:
package main
import (
"bufio"
"fmt"
"io"
"net"
"time"
)
func main() {
var tcpAddr *net.TCPAddr
tcpAddr, _ = net.ResolveTCPAddr("tcp", "127.0.0.1:9999")
conn, err := net.DialTCP("tcp", nil, tcpAddr)
if err != nil {
fmt.Println("Client connect error ! " + err.Error())
return
}
defer conn.Close()
fmt.Println(conn.LocalAddr().String() + " : Client connected!")
// 发送数据断开
b := []byte(conn.LocalAddr().String() + " Say hello to Server... \n")
conn.Write(b)
}
- 上一篇: 工作中的抓包工具:功能、应用场景与常用工具
- 下一篇: 使用Arkime抓包,捕获解密HTTPS流量
猜你喜欢
- 2024-11-05 抓包工具fiddler几个使用技巧(抓包工具fiddler使用方法)
- 2024-11-05 APP不给抓包,看我怎么bypass(抓包如何不被app检测到)
- 2024-11-05 快速锁定Bug!掌握Wireshark等抓包技术,提升测试效率
- 2024-11-05 tcpdump抓包实战(tcpdump抓包命令参数)
- 2024-11-05 分析网络协议利器,使用虚拟网卡实时抓iPhone网络通讯包的方法
- 2024-11-05 Fiddler移动端代理抓包(HTTPS篇)(fiddler抓包https协议)
- 2024-11-05 charles-抓包工具的使用(charles抓包工具详细教程)
- 2024-11-05 手机、电脑网络抓包实战教程(小白教程)!
- 2024-11-05 ibm system x3650 m2 服务器通过局域网抓包获取IP地址
- 2024-11-05 为什么Fiddler等软件能抓包Https网络数据?
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)