TCP/IP协议解析

  1. 云栖社区>
  2. 博客>
  3. 正文

TCP/IP协议解析

~信~仰~ 2019-03-13 00:23:24 浏览1440
展开阅读全文

1. TCP-IP四层网络模型

当应用程序用TCP传送数据时,数据被送入协议栈中,然后逐个通过每一层直到被当作一串比特流送入网络。当目的主机收到以太网数据帧时,数据就开始从协议栈中由底向上升,同时去掉各层协议加上的报文首部。每层协议盒都要去检查报文首部中的协议标识,以确定接收数据的上层协议。

tcp_ip_
 
应用层的数据传到传输层,在传输层会加上tcp头信息,其中会携带接收端主机端口信息,到达接收端后将报文交给指定端口的进程处理;

在网络层会增加IP头,其中包含IP地址信息,接收端收到后,会判断IP地址是不是自己,如果不是就转发。

链路层会添加mac头,指定要发送给的主机mac。

2. TCP和UDP

IP 协议

TCP 和 UDP都是使用IP作为网络层协议。IP 协议提供了数据报文处理和分发服务,每个 IP 报文包含一个目的地址的字段;但IP协议可能会发生报文丢失、报文顺序打乱,重复发送的情况,所以 IP 协议是一个不可靠的协议。

IP 协议层之上的传输层,提供了两种可以选择的协议:TCP、UPD。这两种协议都是建立在 IP 层所提供的服务基础上。

TCP/IP

TCP协议能够检测和恢复IP层提供的主机到主机的通信中可能发生的报文丢失、重复及其他错误。TCP 提供了一个可信赖的字节流通道。TCP协议是一种面向连接的协议,在使用 TCP进行通信之前,两个应用程序之间会建立一个TCP连接。

UDP/IP

UDP 协议没有对IP层产生的错误进行修复,而是简单的扩展了IP协议“尽力而为”的数据报文服务,使他能够在应用程序之间工作,而不是在主机之间工作,因此使用 UDP协议必须要考虑到报文丢失,顺序混乱的问题。

那么TCP是如何做到可靠传输的呢?答案是三次握手与四次挥手。

TCP三次握手与四次挥手

1)TCP三次握手

TCP协议在传输之前,需要通过三次握手建立一个连接,所谓的三次握手,就是在建立 TCP 链接时,需要客户端和服务端总共发送 3个包来确认连接的建立。

第一次握手:客户端A将标志位SYN置为1,随机产生一个值为seq=J(J的取值范围为=1234567)的数据包到服务器,客户端A进入SYN_SENT状态,等待服务端B确认;

第二次握手:服务端B收到数据包后由标志位SYN=1知道客户端A请求建立连接,服务端B将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给客户端A以确认连接请求,服务端B进入SYN_REVD状态。

第三次握手:客户端A收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给服务端B,服务端B检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,客户端A和服务端B进入ESTABLISHED状态。

_

完成了三次握手,随后客户端A与服务端B之间可以开始传输数据了。

为什需要三次握手?

三次握手是为了防止对已失效的连接请求报文段信息建立连接。例如client发出的第一个连接请求,但是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。这是一个早已失效的报文段,但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。

如果是二次握手的话,这时候server会建立新的ESTABLISHED的连接,并等待接收数据。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server一直等待client发来数据。这样,server的很多资源就浪费掉了。

采用“三次握手”可以防止上述现象。因为client不会向server的确认发出反馈,所以server就不会建立ESTABLISHED连接。主要目的防止server端一直等待,浪费资源。

SYN攻击

TCP的几个相关概念

未连接队列:在三次握手协议中,服务器维护一个未连接队列,该队列为每个客户端的SYN包(syn=j)开设一个条目,该条目表明服务器已收到SYN包,并向客户发出确认,正在等待客户的确认包。这些条目所标识的连接在服务器处于Syn_RECV状态,当服务器收到客户的确认包时,删除该条目,服务器进入ESTABLISHED状态。

SYN-ACK重传次数:服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传,如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。

半连接存活时间:是指半连接队列的条目存活的最长时间,也即服务从收到SYN包到确认这个报文无效的最长时间,该时间值是所有重传请求包的最长等待时间总和。也称为Timeout时间、SYN_RECV存活时间。

SYN攻击原理

SYN攻击属于DOS攻击的一种,配合IP欺骗,SYN攻击能达到很好的效果,通常,客户端在短时间内伪造大量不存在的IP地址,向服务器发送大量的半连接请求,耗费server端CPU和内存资源,而服务器一直到超时,才将此条目从未连接队列删除。这些伪造的SYN包将长时间占用未连接队列,正常的SYN请求被丢弃,目标系统运行缓慢,严重者引起网络堵塞甚至系统瘫痪。

检测SYN攻击

检测SYN攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。我们使用系统自带的netstat 工具来检测SYN攻击:

root@VM000000587:~# netstat -n -p TCP |grep SYN
tcp        0      0 192.168.163.167:8001    20.3.197.159:48472      SYN_RECV    -               
tcp        0      0 192.168.163.167:8001    20.3.197.159:48474      SYN_RECV    -

2)TCP四次挥手

第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。

第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。

第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。

第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。

_

为什么建立连接是三次握手,而关闭连接却是四次挥手呢?

这是因为在建立连接时,服务端收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给了客户端。

而关闭连接时,当收到客户端的FIN报文时,仅表示客户端不再发送数据了但是还能接收数据,此时服务端可能还有业务数据还要发送给客户端。因此,己方ACK和FIN一般都会分开发送(ack表示确认收到请求,FIN表示结束发送报文)。

滑动窗口

数建立可靠连接以后,就可以进行数据传输了。在通信过程中,最重要的是数据包,即协议传输的数据。为了避免数据拥堵接收方无法全部接收而造成的丢包,需要对发方进行流量控制,而通过滑动窗口机制可以实现流量控制。

滑动窗口协议

发送和接受方都会维护一个数据帧的序列,这个序列被称作窗口。发送方的窗口大小由接受方确定,目的在于控制发送速度,以免接受方的缓存不够大而导致溢出,同时控制流量也可以避免网络拥塞。

1552384183006_1_

上面图中上边为发送方,下边为接收方,窗口大小为5,数据帧共20位,这是数据发送前发送方告诉接收方的数据长度。发送方发送0号数据帧,接受方接受0号后,接收方的窗口向右移动1位,然后给发送方成功反馈,发送方收到反馈后,窗口也向右移动一位。

如果没有收到反馈,发送方窗口不能滑动。如果超过指定时间仍然没有收到反馈,例如0号数据帧,发送方会再次发送0号数据,直至收到反馈,窗口才能向下滑动。

窗口大小代表能同时发送的数据帧数,即发送方可以不等待反馈而连续发送的最大幀数,本例中发送方最多能一次发送5个数据帧。同时发送5个时,例如0,1,2,3,4,如果1,2,3,4号数据帧都收到了成功反馈,但0号未收到,此时接收方窗口不可滑动,直至0号收到成功反馈。

同理,如果接收方收到1,2,3,4,但是没有收到0号数据帧,此时也是不能向下滑动的,直至收到0号。

网友评论

登录后评论
0/500
评论
~信~仰~
+ 关注