• TCP的三次握手和4次挥手


    一、首先讲一下TCP的由来

    最开始,人们考虑到将网络信息的呼唤与回应进行规范,达成一种公认的协议,就好像没有交通规则的路口设定交通规则。
    人们设计出完美的OSI协议,这个协议包含七个层次由下到上分别是:
    物理层,数据链路层,网络层,传输层,会话层,表示层,应用层。
    大家都觉得很完美但是现实总是会打破理想,十分现实。
    人们发现在使用过程中,没有必要这么繁琐,很多层次也分的不必太清晰可以合并,于是在实践过程中,人们逐渐演变出更实用的TCP/IP协议。
    在这里插入图片描述

    二、三次握手连接,四次挥手断开

    画图解释吧更形象
    在这里插入图片描述

    三、总结

    3次握手的过程是双方都在准备资源,4次挥手的过程是让之前准备的资源释放。
    这个时候可能会产生疑问为什么连接是三次挥手就要四次?
    这是因为套接字是全双工的(同时收发数据无影响),所以关的时候要收发都关掉。
    不知道有没有同学会跟我一样产生一个疑惑,为什么要客户端先调用close而不是服务器先调用close?
    我经过查阅资料学习我们先来追溯一下收发信息原理的源头:TCP为了保证数据的可靠性,一般接收方在收到一个数据“请求断开连接”之后才会给发出方回应一个“收到,这边准备妥当不再接收”信息,但如果一直不回应,发送方就会一直等待回应,为了避免陷入这样一个循环,引入了超时时间机制,谁先调用close,发完消息之后等待一定时间,如果没有收到回应,发送方就再发送一次。但这个时候又出现一个问题,如果接收方给的回应迟了,超出了等待期限范畴,一边已经回应“收到,已准备妥当不再接收”,另一边因为等待时间内没有等到这条消息,会继续发送“请求断开连接”-等待(对方已经关闭接收了)-发-等待-发-等待…这就又陷入了一个循环,为了解决这个问题,我们引入了延时机制,也就是接收方接到断开请求,回复“收到,这边准备妥当不再接收”之后,让它等待约2MSL(MSL就是一个数据包在网络上传输的时间),确定收不到发送方再次发来的断开请求,再真正执行关闭接收操作。现实这段过程大概耗时为两分钟左右,在这段时间内接收方是不被允许释放资源的,这也就意味着这段时间内它所占用的端口不可以被其他程序所调用(程序虽然关了但是端口仍被占用,不利于资源的最大化利用)。这个时候,我们再来想,如果是服务器先调用close,这就意味着服务器先发出断开连接请求,也就意味着它要保留两分钟左右的资源的同时占用这个端口,但我们知道,服务端要绑定固定的端口,客户端不用呀,所以如果是客户端先调用close,它在等待保留资源的时候,操作系统再执行其他操作,分配资源时,端口是自由的,可以紧接着继续分配,达到对资源的最大化利用,刚刚好。所以客户端先调用close而不是服务器先调用close。

    上码

    import socket
    
    def service_client(new_socket):
        """为这个客户端返回数据"""
    
        #1.接收浏览器发送过来的请求,即HTTP发送来的请求
        #GET /HTTP/2.0
        #...
        request=new_socket.recv(1024)#一般来说应该空间是够了
        print(request)
        #2.返回HTTP格式的数据给浏览器
        #2.1准备发送给浏览器的数据--head就是HTML那些
        response="http/2.0 200 OK\r\n"#浏览器不能解析换行符/n,必须使用/r/n的方式
        response+="\r\n"#不可或缺的换行符,代表着body即将到来
        #2.2准备一些--body部分内容,准备给浏览器送去
        #response+="

    xixizi

    "
    response+="xixizi" new_socket.send(response.encode("utf-8")) #关闭套接字 new_socket.close() def main(): "用来完成整体的控制" #1.创建套接字 tcp_server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #2.绑定 tcp_server_socket.bind(("",65534)) #3.变为监听套接字 tcp_server_socket.listen(128) while True: #4.等待新客户端的链接 new_socket,client_addr=tcp_server_socket.accept() #5.为这个客户端服务 service_client(new_socket) #关闭监听套接字 tcp_server_socket.close() if __name__=="__main__": main()
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    在这里插入图片描述
    最近很努力在找实习,把尘封已久的知识重新翻出来再温习温习,不问前程,但行脚下

  • 相关阅读:
    C++反向迭代器的封装和模板进阶(个人笔记)
    MSP430F5529库函数定时器A——定时中断
    实际应用效果不佳?来看看提升深度神经网络泛化能力的核心技术(附代码)
    Zebec联合Visa推出实体借记卡持续利好生态,$ZBC表现强劲
    柒微自动发卡系统源码
    Macos必备ps 磨皮滤镜插件
    pip修改为镜像源,window和linux修改方式
    826. 单链表
    互联网干洗店洗鞋店预约收衣下单软件
    python+vue+elementui在线打印系统
  • 原文地址:https://blog.csdn.net/m0_57297999/article/details/136747602