zoukankan      html  css  js  c++  java
  • TCP三次握手,四次挥手

    参考文章,感谢原博主的分享与总结;
    
    https://blog.csdn.net/qzcsu/article/details/72861891
    
    https://www.cnblogs.com/Andya/p/7272462.html
    
    https://blog.csdn.net/hacker00011000/article/details/52319111

    为什么客户端还要发送一次确认呢?可以二次握手吗?

    1. 主要为了防止已经失效的链接请求报文突然又传送到了服务端
    2. 假设A是客户端,B是服务端,如果A发出请求,但是因链接请求报文丢失而未收到确认,于是A会再重传一次请求;
    3. A在整个过程中,一共发了两次链接请求,其中第一个可能因为网络等其他因素导致当时B端未收到请求;但是再A,B端均释放链接以后,此时那个我们认为已经丢失的A链接请求达到了B端,那么B可能会误认为A发出的是一个新的请求,于是向A发出确认报文段,同意链接
    4. 此时因为A已经关闭,A对于B的统一链接请求不予响应,导致B一直等待响应,浪费资源

    解释四次挥手?

    1. 假设A是客户端,B是服务端
    2. A发送中断请求,即FIN报文,即A告诉B:我这边没有数据要发送给你了,但是如果你还有没有发送完的数据,可以不必关闭SOCKET,可以继续发送数据
    3. B在收到A的请求后,ACK告诉A,你的请求我收到了,但是我还没准备好,请你继续等待我的消息
    4. 此时A进入FIN_WAIT状态,等待B的FIN报文
    5. 当B数据确认发送完成,向A发送FIN报文,告诉A,我这边数据发送完了,准备关闭连接;
    6. A在收到FIN报文后,知道可以关闭连接了,但是A不相信网络,怕server段不知道要关闭,所以发送ACK后进入TIME_WAIT阶段
    7. 如果B端没有收到ACK则可以重传
    8. B端收到ACK后,知道可以关闭连接了
    9. A端等待2MSL后依然没收到回复,则证明B端已正常关闭,进而A端关闭连接

    为什么建立连接是三次,关闭连接是四次

    假设A是客户端,B是服务端

    1. 当B收到SYN链接请求时,可以直接发送SYN+ACK报文给A,其中ACK是应答,Syn报文是用来同步的
    2. 当关闭链接时,当B收到FIN请求时,很可能不立即关闭SOCKET,所以只能先回复ACK,告诉A,中断链接请求已收到;
    3. 只有当B端的数据发送完毕后,B才能发送FIN+ACK给A端;
    4. A端收到响应,发送ACK至B端,响应中断,2MSL后,A端关闭

    为什么客户端最后还要等待2MSL(最大报文段生存时间)

    假设A是客户端,B是服务端,A等待2MSL有如下原因,一般2-4分钟

    1. 保证客户端发送的最后一个ACK报文能到到服务器
    • 针对B端,已经发送了FIN+ACK报文给A端,但是A可能因为网络等其他原因没有未收到请求,未能及时回复B
    • 此时,B可能会再发一段FIN+ACK报文给A端,
    • 此时如果A在2msl时间段内收到这个重传的FIN+ACK报文段,接着A重传一段确认,重新启动2MSL计时器,最终A,B进入close状态
    • 如果A不等待,即发送完ACK报文立即释放,则无法收到B重传的FIN+ACK报文,所以A也就不会重发一段ACK报文,则B无法正常进入close状态
    1. 防止“已失效的连接请求报文段”出现在本连接中
    • A在发送完最后一个ACK报文段后,再经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段
    • 当某个连接的一端处于TIME_WAIT状态时,该连接将不能再被使用

    如果已经建立了连接,但是客户端突然出现故障了怎么办?

    1. TCP设有一个保活计时器;服务器每收到一个客户端的请求,都会重新复位这个计时器;通常设置是2小时;
    2. 若2小时内,还没有收到客户端的回复,服务器会发送一个探测报文段,以后每隔75分钟发送一次;
    3. 若一连发送10个探测报文仍然无反应,则终止链接

    Server端易受到SYN攻击?

    1. 服务端的资源分配是在二次握手时分配的,而客户端的资源是在三次握手时分配的;
    2. SYN攻击,即客户端在短时间内伪造大量不存在的IP地址,并向SERVER端不断的发送SYN包,SERVER收到请求即回复确认,并等待客户端的确认,由于源地址不存在,因此SERVER需要不断的重发直到超时;
    3. 这些伪造的SYN包长时间占用未连接队列,导致正常的SYN请求因为队列满而丢弃,因为网络拥塞
    4. 一般服务端会重试5次

    SYN Flood 防护措施

    1. 无效链接释放,监视系统中的半开链接和不活动的链接,达到阈值,释放资源,但是这样可能也会将正常的链接释放掉;
    2. 延缓TCB分配
    • 正常情况下,当SYN报文收到的时候,系统即分批资源,那么可以在收到SYN时,不着急分配TCB,而是先回应一个ACK报文,并在一个专用的HASH表中,保存这种半开链接,等收到ACK再分配
    • Syn Cookie:将第一次收到请求的IP 端口等信息加密生成一字符串,在收到ACK的时候,判断是否一致,一致则分配
    • ======================================================================================
      越努力,越幸运,加油
  • 相关阅读:
    【mysql】关于binlog格式
    【linux】关于TCP三次握手和四次挥手
    【nginx】负载均衡和proxy的配置
    【PHP】$_POST, $HTTP_RAW_POST_DATA, and php://input
    【nginx】关于gzip压缩
    【nginx】配置文件的优化
    【集合框架】JDK1.8源码分析之TreeMap(五)
    【集合框架】JDK1.8源码分析之IdentityHashMap(四)
    【集合框架】JDK1.8源码分析之HashMap & LinkedHashMap迭代器(三)
    【集合框架】JDK1.8源码分析之LinkedHashMap(二)
  • 原文地址:https://www.cnblogs.com/qrrlinux/p/9291129.html
Copyright © 2011-2022 走看看