• python----网络编程之TCP三次握手四次挥手


    什么是Socket

    Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部。

    TCP三次握手

    三次握手就好比是两个好朋友因为一块钱,两人干了一架。事后又想和好的一个过程:

    1.两人干了一架后,(TCP两端)都是处于一种僵持(CLOSED)状态,A主动打破这种尴尬的局面,主动向B发送了一句话(SYN-SENT)。

    2.其实B一直等A说话(处于LISTEN状态),B收到了A发送的话(SYN-RCVD)。

    3.于是两人和好了,又可以愉快的玩耍了(ESTAB-LISHED)。

    (1)SYN:请求报文

    (2)seq:序列号

    (3)ack:确认状态

    (4)ACK:确认后继续发送

    • 第一次握手:A的TCP进程首先向B发送请求(SYN=1),同时发送一个序列号(seq=x),此时A处于发送(SYN-SENT)状态。
    • 第二次握手:B监听到A的请求(LISTEN),确认收到A的请求(ack=x+1),确认收到并继续给A发去请求(ACK=1, SYN=1),同时发送一个序列号(seq=y),此时B处于同步收到状态。
    • 第三次握手:A确认收到B的请求(ack=y+1),确认收到A的请求(seq=x+1),(第一次seq为x,所以这次要+1),此时A进入已链接状态(ESTAB-LISHED),发状态给B,B收到后也进入已链接状态。

    一:为什么A还要发送一次确认?进行了2次握手?

      主要是为了防止因为各种原因A的请求在传输中断开后又链接上传送到了B,因而产生错误。比如A发出连接请求,但因连接请求报文丢失而未收到确认,于是A再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接,A发出了两个连接请求报文段,其中第一个丢失,第二个到达了B,但是第一个丢失的报文段只是在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达B,此时B误认为A又发出一次新的连接请求,于是就向A发出确认报文段,同意建立连接,不采用三次握手,只要B发出确认,就建立新的连接了,此时A不理睬B的确认且不发送数据,则B一致等待A发送数据,浪费资源。

    二:Server端易受到SYN攻击?

      服务器端的资源分配是在二次握手时分配的,而客户端的资源是在完成三次握手时分配的,所以服务器容易受到SYN洪泛攻击,SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。

    防范SYN攻击措施:降低主机的等待时间使主机尽快的释放半连接的占用,短时间受到某IP的重复SYN则丢弃后续请求。

    TCP四次挥手

    四次挥手好比是一件上厕所的过程:

    1.厕所只有一个坑,B正在占用着坑,戴着耳机听着歌,A内急敲了敲门,问B:"好了吗?哥们,我着急呀~!快拉裤子了!"

    2.B听到了A的喊话,但是还想听会歌。。。。。

    3.回复了A一句话:"我听到了,但是我还没好,请你再稍等一会。"

    4.半个小时过后。。。。A打开了门,B着急的进了厕所。

    (1)FIN:释放报文

    (2)seq:序列号

    (3)ack:确认状态

    (4)ACK:确认后继续发送

    • A的应用进程先向其TCP发出连接释放报文段(FIN=1,seq=u)并停止再发送数据,主动关闭TCP连接,进入FIN-WAIT-1(终止等待1)状态,等待B的确认。
    • B收到连接释放报文段后发出确认报文段,(ACK=1,ack=u+1,seq=v),B进入关闭等待(CLOSE-WAIT)状态,此时的TCP处于半关闭状态,A到B的连接释放,同时A收到B的确认后,进入终止等待2(FIN-WAIT-2)状态,等待B发出的连接释放报文段。
    • B没有要向A发出的数据,B发出连接释放报文段(FIN=1,ACK=1,序号seq=w,确认号ack=u+1),B进入最后确认(LAST-ACK)状态,等待A的确认。
    • A收到B的连接释放报文段后,对此发出确认报文段(ACK=1,seq=u+1,ack=w+1),A进入时间等待(TIME-WAIT)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,A才进入CLOSED状态。

    一:为什么A在TIME-WAIT状态必须等待2MSL的时间?

      MSL最长报文段寿命Maximum Segment Lifetime,MSL=2

    1. 保证A发送的最后一个ACK报文段能够到达B。
    2. 防止“已失效的连接请求报文段”出现在本连接中。
    • 1.这个ACK报文段有可能丢失,使得处于LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认,B超时重传FIN+ACK报文段,而A能在2MSL时间内收到这个重传的FIN+ACK报文段,接着A重传一次确认,重新启动2MSL计时器,最后A和B都进入到CLOSED状态,若A在TIME-WAIT状态不等待一段时间,而是发送完ACK报文段后立即释放连接,则无法收到B重传的FIN+ACK报文段,所以不会再发送一次确认报文段,则B无法正常进入到CLOSED状态。
    • 2.A在发送完最后一个ACK报文段后,再经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段。

    二:为什么连接的时候是三次握手,关闭的时候却是四次握手?

      因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

  • 相关阅读:
    Cocon90.Db调用方法
    Hotmail Smtp邮箱发送的端口
    Nginx+Lua+Redis构建高并发应用
    Linux安装pear包
    Nginx中if语句中的判断条件
    SqlServer判断表、列不存在则创建
    Nginx配置参数详解
    Linux中在线安装Mysql和修改密码设置服务启动
    linux中fuser用法详解
    Java中创建访问HTTPS的自签名证书的方法
  • 原文地址:https://www.cnblogs.com/cnike/p/10726069.html
Copyright © 2020-2023  润新知