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报文,因此不能一起发送。故需要四步握手。

 

posted on 2019-04-17 20:50  cn_ike  阅读(255)  评论(0编辑  收藏  举报

导航