tcp_2020-3-14

TCP

1 传输控制协议TCP简介

1.1 tcp 功能

  • tcp是面向连接的、可靠的、基于字节流的的传输层通信协议

  • 数据传输时应用层向传输层发送数据流,然后TCP把数据流分割成长度适当的报文段,报文段的长度通常受该计算机连接的网络的数据链路层的最大传输单位即AMPU所限制。之后TCP把结果包传输给IP层(网络层)。

  • 将应用层的数据分割成报文段,并发送给目标节点的传输层。

  • 数据的包都是有序的,对方收到则发送ACK确认包,未收到则重传。TCP为了保证不丢包,就给每个包一个Sequence Number,同时序列号也保证了传输到目标节点后包的按序处理。接收端对成功收到的包发回下一个响应的确认即ACK确认。如果发送端在实体在合理的的往返时延即RTT内没有收到ACK,那么对应的数据包会被认为已丢失,并对其进行重传。

  • TCP使用奇偶校验和来检验数据在传输的过程中是否有误,在发送和接收端都要计算校验和

1.2 tcp 报文段的结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7NVMNNDj-1584184876679)(.\img\tcp报文段结构.png)]

1.2.1 源端口、目标端口

用来标识发送端的端口和接收端的端口

1.2.2 序号、确认号

  • 序号:32位字段。指派给本报文段第一个数据字节的编号,TCP传输保证连接性,发送的每个字节都要编上号。序号就是告诉终点,报文段中的第一个字节是序列中的哪个。建立连接时,发收双发使用各自的随机数产生器产生一个初始序号(ISN),通常,两个方向的ISN是不同的
  • 确认号:32位字段定义了接收方期望从对方接受的字节编号。如果报文段的接收方成功的接受了对方发过来的编号x的字节,那么返回x+1作为确认号,确认号可以和数据捎带一起发送。

1.2.3 数据偏移

也叫首部长度,占4个bit,它指出TCP报文段的数据起始处距离TCP报文段的起始处有多远。

1.2.4 保留(reserve)

占6位,保留为今后使用,但目前应置为0。

1.2.5 控制位

1.2.5.1 紧急URG(urgent)

当URG=1时,表明紧急指针字段有效。

它告诉系统此报文段中有紧急数据,应尽快发送(相当于高优先级的数据),而不要按原来的排队顺序来传送。

例如,已经发送了很长的一个程序要在远地的主机上运行。但后来发现了一些问题,需要取消该程序的运行,因此用户从键盘发出中断命令。如果不使用紧急数据,那么这两个字符将存储在接收TCP的缓存末尾。只有在所有的数据被处理完毕后这两个字符才被交付接收方的应用进程。这样做就浪费了很多时间。

当URG置为1时,应用进程就告诉TCP有紧急数据要传送。于是TCP就把紧急数据插入到本报文段数据的最前面,而在紧急数据后面的数据仍然是普通数据。这时要与首部中紧急指针(Urgent Pointer)字段配合使用。

1.2.5.2 确认ACK(acknowledgment)

仅当ACK = 1时确认号字段才有效,当ACK = 0时确认号无效。TCP规定,在连接建立后所有的传送的报文段都必须把ACK置为1。

1.2.5.3 推送 PSH(push)

当两个应用进程进行交互式的通信时,有时在一端的应用进程希望在键入一个命令后立即就能收到对方的响应。在这种情况下,TCP就可以使用推送(push)操作。发送方TCP把PSH置为1,并立即创建一个报文段发送出去。接收方TCP收到PSH=1的报文段,就尽快地(即“推送”向前)交付接收应用进程。而不用再等到整个缓存都填满了后再向上交付。

1.2.5.4 复位RST(reset)

当RST=1时,表明TCP连接中出现了严重错误(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立传输连接。RST置为1还用来拒绝一个非法的报文段或拒绝打开一个连接。

1.2.5.4 同步SYN(synchronization)

在连接建立时用来同步序号。当SYN=1ACK=0时,表明这是一个连接请求报文段。对方若同意建立连接,则应在响应的报文段中使SYN=1和ACK=1。

因此SYN=1就表示这是一个连接请求或连接接受报文。

1.2.5.5 终止FIN

用来释放一个连接。当FIN=1时,表明此报文段的发送发的数据已发送完毕,并要求释放运输连接。

1.2.6 窗口

占2字节。窗口值是(0,216 -1)之间的整数。

窗口指的是发送本报文段的一方的接受窗口(而不是自己的发送窗口),窗口大小是给对方用的。

窗口值告诉对方:从本报文段首部中的确认号算起,接收方目前允许对方一次发送的数据量(以字节为单位)。

之所以要有这个限制,是因为接收方的数据缓存空间是有限的。

总之,窗口值作为接收方让发送方设置其发送窗口的依据。

例如,A发送了一个报文段,其确认号是3000,窗口字段是1000.这就是告诉对方B:“从3000算起,A接收缓存空间还可接受1000个字节数据,字节序号是3000-3999”,可以想象到河道的阀门。

总之:窗口字段明确指出了现在允许对方发送的数据量。窗口值经常在动态变化。

1.2.7 检验和

占2字节。检验和字段检验的范围包括首部和数据这两部分。和UDP用户数据报一样,在计算检验和时,要在TCP报文段的前面加上12字节的伪首部。伪首部的格式和UDP用户数据报的伪首部一样。但应把伪首部第4个字段中的17改为6(TCP的协议号是6);把第5字段中的UDP中的长度改为TCP长度。接收方收到此报文段后,仍要加上这个伪首部来计算检验和。若使用TPv6,则相应的伪首部也要改变。

1.2.8 紧急指针

占2字节。紧急指针仅在URG=1时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据) 。因此,在紧急指针指出了紧急数据的末尾在报文段中的位置。当所有紧急数据都处理完时,TCP就告诉应用程序恢复到正常操作。值得注意的是,即使窗口为0时也可以发送紧急数据。

选项

长度可变,最长可达40个字节。当没有使用“选项”时,TCP的首部长度是20字节。

2 三次握手与四次挥手

2.1 三次握手

2.1.1 握手的过程

“握手”是为了建立连接,在TCP协议提供可靠的连接服务,采用三次握手建立一个连接。TCP三次握手流程如下:

  • 第一次握手:建立连接时,客服端发送SYN包到服务器并进入SYN_SEND状态,等待服务确认

  • 第二次握手:服务器收到SYN包,必须确认客服端的SYN,同时自己也发送一个SYN,即SYN+ACK。此时服务器进入SYN_RECV状态

  • 第三次握手:客服端收到SYN+ACK包,并向服务器发送ACK确认包,客服端进入ESTABLISHED状态,完成三次握手

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F4FcEcjx-1584184876680)(.\img\三次握手.jpg)]

2.1.2 一些问题

  • 为什么需要三次握手,才能建立起安全的连接

    主要是为了初始化sequence number 的初始值,通信双方要告诉对方自己的sequence number,也就是seq。这个初始值要作为以后双发通信的序号。以保证应用层收到的数据不会因为网络上的传输问题而乱序,即TCP用这个序号来拼接数据。因为在服务器发回它的sequence number(第二次握手)之后,还要发送确认报文给服务器,以告诉服务器客户端已收到服务器的初始化sequence number。

  • 首次握手的隐患--------SYN超时

    当Server收到client的SYN后,恢复SYN+ACK时client未收到ACK。

    Server会不断重试直至超时,Linux默认等待63S,才会断开连接(Linux 会重试5次,第一次间隔1S,以后每次*2 刚好63S)

    超时可能造成的后果

    • 可能会使服务器遭受SYN FLOOD 攻击。恶意的程序会给服务器发送一个SYN然后下 线,于是服务器需要默认等待63S才会断开连接,这样攻击者既可以把服务器的SYN连接队列耗尽。让正常的的连接请求无法处理。

    针对SYN FLOOD的防护措施

    • linux在SYN队列满后,通过tcp_syncookies参数,回发SYN Cookie。如果是正常连接,这client会回发SYN Cookie直接建立连接,如果是攻击者则不会响应
  • 建立连接后client出现故障怎么办

    向对方发送保活探测报文,如果为未收到响应则继续发送,直到尝试次数达到保活探测次数,如果还未收到响应,则断开连接

2.2 四次挥手

2.2.1挥手的过程

  • 第一次挥手:client发送FIN,用来关闭Client到Server的数据传输,Client进入FIN_WAIT1状态
  • 第二次挥手:Server收到FIN后,发送一个ACK给Client,Server进入CLOSE_WAIT状态
  • 第三次挥手:Server发送一个FIN用来关闭Server到Client的数据传输,Server进入LAST_ACK状态
  • 第四次挥手:Client收到FIN,Client并发送ACK给Server。然后进入TIME_WAIT状态

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tLR9r9Ih-1584184876681)(D:\桌面\太多了\笔记\img\四次挥手.jpg)]

2.2.2一些问题

  • 为什么会有TIME_WAIT状态:

    • 为了确保有足够多的时间让让对方收到ACK包。
    • 避免新旧连接混淆使用。有的路由器会缓存IP数据包,如果连接被重用那么这些延迟有道的包,就有可能跟新的连接混在一起
  • 为什么需要四次挥手才能断开连接:

    因为TCP是全双工,所以Client和Server都需要FIN和ACK报文

  • 服务器的出现大量TIME_WAIT的可能的原因

    对方关闭了socket连接,我方忙于读或者写,没有及时关闭连接

    可能的排查方法

    • 检查代码,特别是释放资源的代码
    • 检查配置,特别是处理请求的线程配置

暂时就先写到这

lient和Server都需要FIN和ACK报文

  • 服务器的出现大量TIME_WAIT的可能的原因

    对方关闭了socket连接,我方忙于读或者写,没有及时关闭连接

    可能的排查方法

    • 检查代码,特别是释放资源的代码
    • 检查配置,特别是处理请求的线程配置

暂时就先写到这

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值