美文网首页
深入研究TCP&三次握手四次挥手

深入研究TCP&三次握手四次挥手

作者: StarDustMrsu | 来源:发表于2019-11-01 15:21 被阅读0次

    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三次握手和四次挥手

    三次握手

    TCP三次握手总过程.jpg
    第一次

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


    三次握手之第1次.jpg

    根据Wireshark抓包情况来看,此时客户端30.26.223.21向服务端123.56.133.245的10086端口发送建立连接的SYN请求,标志位Flags中SYN=1,序列号Sequence number=0。

    第二次

    服务端收到客户端想要建立连接的请求后,返回SYN,并且ACK客户的SYN请求,之后服务端进入SYN-RCVD状态。


    三次握手之第2次.jpg

    根据Wireshark抓包情况来看,服务端此时向客户端返回SYN和ACK都是1的报文,回应报文中Sequence number=0,Acknowledgment=1,作为服务端随机产生初始序号为0,确认序号等于客户端的请求序号+1。

    第三次

    客户端在收到服务端发来的SYN和ACK,检查确认后发送ACK的ACK,之后进入ESTABLISHED状态。服务端收到ACK的ACK后检查确认没毛病也进入ESTABLISHED状态。


    三次握手之第3次.jpg

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

    四次挥手

    TCP四次挥手总过程.jpg
    第一次
    四次挥手之第1次.jpg

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

    第二次
    四次挥手之第2次.jpg

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

    第三次
    四次挥手之第3次.jpg

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

    第四次
    四次挥手之第4次.jpg

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

    总结

    三次握手状态时序图
    TCP三次握手.png
    四次挥手状态时序图
    TCP四次挥手_20191031.jpg
    状态机
    TCP状态机.jpg

    相关文章

      网友评论

          本文标题:深入研究TCP&三次握手四次挥手

          本文链接:https://www.haomeiwen.com/subject/oenfbctx.html