深入研究TCP&三次握手四次挥手
Wireshark捕获的TCP报文字段说明
Wireshark捕获字段 | 对应TCP报文头部 | 说明 |
---|---|---|
Source Port | 16位源端口号 | TCP连接客户端的端口号 |
Destination Port | 16位目标端口号 | TCP连接服务端的端口号 |
Sequence number | 32位序列号 | 客户端的数据组的第一个字节的序号 |
Acknowledgment number | 32位确认序号 | 服务端期望客户端的下一个报文段的序号 |
Header Length | 首部长度 | 数据区在报文段中的起始偏移值 |
Flags:Urgent | URG | 表示紧急指针是否有效,URG=1表示紧急,应该尽快传输 |
Flags:Acknowledgment | ACK | 表示确认序号是否有效,ACK=1确认序号有效,ACK=0确认序号无效则不是一个确认包 |
Flags:Push | PSH | 表示是否确认推送有效,当PSH=1时,表示服务端应尽快把数据交给应用层 |
Flags:Reset | RST | 表示是否确认复位有效,当RST=1时,表示TCP连接出现严重差错,需要重连 |
Flags:Syn | SYN | 表示同步是否有效,当SYN=1时表明这是一个连接请求或连接接收报文 |
Flags:Fin | FIN | 表示终止是否有效,FIN=1时,表明此报文段的客户端的数据已经全部传输完毕 |
Window size value | 16位窗口大小 | 服务端希望一次接收的字节数 |
Checksum | 16位校验和 | 由客户端计算和存储,并由服务端验证,对整个TCP报文段进行奇偶校验 |
Urgent pointer | 16位紧急指针 | 指出本报文段中紧急数据共有多少字节 |
使用python3编写TCP客户端和服务端
客户端
import socket
ip_port=('123.56.133.245',10086)
client = socket.socket()
client.connect(ip_port)
while True:
info = str(input("Please input you infomation:")).strip()
if not info:
continue
client.sendall(info.encode())
if info =="exit":
print("EXIT...")
break
server_reply= client.recv(1024).decode()
print(server_reply)
client.close()
服务端
import socket
import threading
def link_handler(link,client):
print("Server start receiving requests from the Client[%s:%s]."%(client[0],client[1]))
while True:
client_data = link.recv(1024).decode()
if client_data == "exit":
print("End connections to [%s:%s]"%(client[0],client[1]))
break
print("From Client [%s:%s] send a message: %s"%(client[0],client[1],client_data))
link.sendall("Server has already received the Client message".encode())
link.close()
ip_port = ('0.0.0.0', 10086)
server = socket.socket()
server.bind(ip_port)
server.listen(5)
print("Open TCP Server and wait for Client to connect!")
while True:
conn, address = server.accept()
thread001 = threading.Thread(target=link_handler, args=(conn,address))
thread001.start()
Wireshark抓包分析TCP三次握手和四次挥手
三次握手

第一次
首先客户端和服务端都处于CLOSED状态,在服务端执行python脚本之后服务端主动监听本机的10086端口,进入LISTEN状态,在本地执行客户端脚本之后,客户端主动发起建立连接请求SYN,然后客户端进入SYN-SENT状态。

根据Wireshark抓包情况来看,此时客户端30.26.223.21向服务端123.56.133.245的10086端口发送建立连接的SYN请求,标志位Flags中SYN=1,序列号Sequence number=0。
第二次
服务端收到客户端想要建立连接的请求后,返回SYN,并且ACK客户的SYN请求,之后服务端进入SYN-RCVD状态。

根据Wireshark抓包情况来看,服务端此时向客户端返回SYN和ACK都是1的报文,回应报文中Sequence number=0,Acknowledgment=1,作为服务端随机产生初始序号为0,确认序号等于客户端的请求序号+1。
第三次
客户端在收到服务端发来的SYN和ACK,检查确认后发送ACK的ACK,之后进入ESTABLISHED状态。服务端收到ACK的ACK后检查确认没毛病也进入ESTABLISHED状态。

根据Wireshark抓包情况来看,客户端此时回应了ACK为1的报文,其中Sequence number=1,Acknowledgment=1,作为客户端,序号等于服务端发来的确认序号,确认序号等于服务端的请求序号+1。
四次挥手

第一次

作为客户端,通过脚本主动发送EXIT之后,再次给服务器发送TCP包用来关闭客户端到服务器的数据传输。根据Wireshark抓包情况来看,此时客户端的请求中,将标志位FIN和ACK都设置成了1,序号等于11,确认序号等于35.
第二次

根据Wireshark抓包情况来看,作为服务端,收到客户端的请求之后,也发TCP包准备关闭与客户端之间的连接,此包中将标志位FIN和ACK都设置成了1,序号等于11,确认序号等于35.
第三次

根据Wireshark抓包情况来看,作为客户端,收到服务端的请求之后,发送ACK包回应,将标志位ACK设置成了1,序号等于收到的确认序号+1,确认序号等于收到的序号+1.
第四次

根据Wireshark抓包情况来看,作为服务端,收到客户端的请求之后,发送ACK包回应,将标志位ACK设置成了1,序号等于接收到确认序号+1,确认序号等于接收到的序号+1.
总结
三次握手状态时序图

四次挥手状态时序图

状态机
