TCP UDP详解

TCP:面向连接的、可靠的、基于字节流的传输层通信协议。
UDP:无连接、不可靠的、面向报文的。
在这里插入图片描述

TCP报文格式

TCP传输控制协议,面向连接的,可靠的,基于字节流的传输层协议。
TCP报文封装在IP数据部分中。
在这里插入图片描述
① URG:当URG=1时,注解此报文应尽快传送,而不要按本来的列队次序来传送。与“紧急指针”字段共同应用,紧急指针指出在本报文段中的紧急数据的最后一个字节的序号。
② ACK:只有当ACK=1时,确认序号字段才有效。
③ PSH:当PSH=1时,接收方应该尽快将本报文段立即传送给其应用层。
④ RST:当RST=1时,表示出现连接错误,必须释放连接,然后再重建传输连接。复位比特还用来拒绝一个不法的报文段或拒绝打开一个连接。
⑤ SYN:SYN=1,ACK=0时表示请求建立一个连接,携带SYN标志的TCP报文段为同步报文段。
⑥ FIN:发端完成发送任务。

TCP三次握手

在这里插入图片描述

  1. server的socket经历bind→listening状态等待连接,这时client 的socket的connect主动打开并发出syn=1,seq=x,ACK=0的报文请求建立连接,发送完后处于syn_sent的状态。
  2. server收到后,响应一个SYN=1,ACK=1,seq=y,ack=x+1的报文,表示我已经收到截止seq到x+1的报文,然后进入syn_received状态。
  3. client收到后发送ACK=1,seq=x+1,ack=y+1的报文,然后进入established,回应ack报文,server收到后也进入established状态,若server一直没有收到ack就会重传syn+ack报文。

过程详解:其中seq会根据上次发送的tcp segment len来增加,比如第一次发送时len为0 seq为1 第二次len为30 seq为1 第三次len为0 seq为31,而ack就是表示到seq+1的都已经收到。
client的第一次syn:seq为0 len为0 ------------1
在这里插入图片描述
server回应:ack=0+1 seq=0 ------------------2
在这里插入图片描述
client :seq=1 ack=0+1 len=0 ----------------3
在这里插入图片描述

队列与三次握手

当服务端调用listen函数监听端口的时候,内核会为每个监听的socket创建两个队列
半连接队列(syn queue):客户端发送SYN包,服务端收到后回复SYN+ACK,服务端进入SYN_RECVD状态,这个时候的socket会放到半连接队列。
全连接队列(accept queue):当服务端收到客户端的ACK后,socket会从半连接队列移出到全连接队列。当调用accpet()函数的时候,会从全连接队列的头部返回可用socket给用户进程。
linux:ss -lnt 查看全连接队列。
在这里插入图片描述
Recv-Q:目前全连接队列的大小
Send-Q:目前全连接最大队列长度
TCP 全连接队列最大值取决于min(somaxconn, backlog):
somaxconn:可通过内核参数/proc/sys/net/core/somaxconn设置,默认值是128。
backlog:listen(int sockfd, int backlog) 函数中的 backlog 大小,Nginx 默认值是 511,可以通过修改配置文件设置其长度。

参数:
Backlog:表示未连接队列的最大容纳数目。
tcp_abort_on_overflow:如果全连接队列已满,内核的行为取决于内核参数
tcp_abort_on_overflow=0,server会丢弃client的ack。
tcp_abort_on_overflow=1,server 会发送 reset 包给 client。
具体过程:
  当连接状态变为SYN_RCVD时,连接信息存储到syns queue;当连接状态变为ESTABLISHED时,连接信息从syns queue移动到accept queue;当accept()函数从accept queue获取连接后,连接信息从队列中移除:

● 客户端发送SYN请求,请求建立连接,客户端连接状态变为SYN_SENT;
● 服务端接受到SYN请求,连接状态变为SYN_RCVD,同时将连接信息存放到syns队列中,如果存放成功,则回复SYN+ACK给客户端;
● 当客户端接收到SYN+ACK后,连接状态变为ESTABLISHED,发送ACK到服务端,此时客户端可以发送数据;
● 服务端接收到ACK后,连接的状态变为ESTABLISHED,内核将连接信息从syns队列移动到accept队列;
● 服务端应用进程通过accept()函数从accept队列中获取已建立好的连接进行读写,此时连接被移除accept队列;

在这里插入图片描述
TCP编程的服务器端一般步骤是:
  1、创建一个socket,用函数socket();
  2、设置socket属性,用函数setsockopt(); * 可选
  3、绑定IP地址、端口等信息到socket上,用函数bind();
  4、开启监听,用函数listen();
  5、接收客户端上来的连接,用函数accept();
  6、收发数据,用函数send()和recv(),或者read()和write();
  7、关闭网络连接;
  8、关闭监听;
TCP编程的客户端一般步骤是:
  1、创建一个socket,用函数socket();
  2、设置socket属性,用函数setsockopt();* 可选
  3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
  4、设置要连接的对方的IP地址和端口等属性;
  5、连接服务器,用函数connect();
  6、收发数据,用函数send()和recv(),或者read()和write();
  7、关闭网络连接;

TCP四次挥手

在这里插入图片描述

  1. client发送fin=1,seq=u的报文告知server结束,发送后处于fin-wait-1状态,这时client就不会发送数据了,但是任然可以接收数据。
  2. server收到后回应ACK=1,seq=v,ack=u+1,然后处于close-wait。client收到后处于fin-wait-2状态,这时server端任然在发送剩余的数据。
  3. 这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间,经过close-wait后server发送fin,server就不再发送数据了,client收到后发送ack并进入time-wait为2msl的时间。
  4. 当server收到后就closed,server经过2msl后也进入closed。

TIME_WAIT:主动要求关闭的机器表示收到了对方的FIN报文,并发送出了ACK报文,进入TIME_WAIT状态,等2MSL后即可进入到CLOSED状态。如果FIN_WAIT_1状态下,同时收到待FIN标识和ACK标识的报文时,可以直接进入TIME_WAIT状态,而无需经过 FIN_WAIT_2状态。

MSL(Maximum Segment Lifetime)这个2MSL等待状态会更新的,每发出一次第4个包,都会重置2MSL。

CLOSE_WAIT:被动关闭的机器收到对方请求关闭连接的FIN报文,在第一次ACK应答后,马上进入CLOSE_WAIT状态。这种状态其实标识在等待关闭,并且通知应用发送剩余数据,处理现场信息,关闭相关资源。
在这里插入图片描述

TIME WAIT

在高并发的短链接情况下,比如请求一个html页面,只需要1秒,然后断开连接,但是2msl远远大于2秒,也就是说在整个2msl期间,这个端口的资源就被浪费掉了,如果出现很多这种短链接的话就会造成大量的浪费。
proc/sys/net/ipv4:
在这里插入图片描述

TCP拥塞控制

造成原因:网络中某一资源的需求超过了该资源所能提供的可用部分。
拥塞控制:防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。拥塞控制所要做的都有一个前提:网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程,涉及到所有的主机、路由器,以及与降低网络传输性能有关的所有因素。
在这里插入图片描述
cwnd(congestion window)根据网络拥塞的程度动态变化。
ssthresh(slow start threshold)慢开始门限。
TCP提供4种方法

  1. 慢开始:主机开始发送数据时,如果立即将大量数据字节注入到网络,那么就有可能因为不清楚当前网络的负荷情况而引起网络阻塞。所以,最好的方法是先探测一下,即由小到大逐渐增大发送窗口,由小到大逐渐增大拥塞窗口数值。通常在刚刚发送报文段时,先把拥塞窗口cwnd设置为一个最大报文段MSS的数值。而在每收到一个新的报文段的确认后,把拥塞窗口增加至多一个MSS的数值。用这样的方法逐步增大发送方的拥塞窗口cwnd,可以使分组注入到网络的速率更加合理。(慢开始当中的“慢”并不是指cwnd的增长速率慢,而是在TCP开始发送报文段时先设置cwnd = 1,使得发送方在开始时只发送一一个报文段)。
  2. 拥塞控制/避免:拥塞避免算法让拥塞窗口缓慢增长,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍,这样拥塞窗口按线性规律缓慢增长。出现拥塞时就就把慢开始门限设置为出现拥塞时的发送窗口大小的一半。然后把拥塞窗口设置为1,执行慢开始算法。
  3. 快重传:快重传算法要求首先接收方收到一个失序的报文段后立刻发出重复确认,而不要等待自己发送数据时才进行捎带确认。
    在这里插入图片描述
  4. 快恢复:
    1.当发送方连续收到三个重复确认,执行乘法减小,ssthresh减半。
    2.由于发送方可能认为网络现在没有拥塞,因此与慢开始不同,把cwnd值设置为ssthresh减半之后的值,然后执行拥塞避免算法,线性增大cwnd。
    在这里插入图片描述

TCP流量控制

所谓的流量控制就是让发送方的发送速率不要太快,让接收方来得及接受。利用滑动窗口机制可以很方便的在TCP连接上实现对发送方的流量控制。TCP的窗口单位是字节,不是报文段,发送方的发送窗口不能超过接收方给出的接收窗口的数值。

当发送方收到接受窗口 win = 0 时,这时发送方停止发送报文,并且同时开启一个定时器,每隔一段时间就发个测试报文去询问接收方,打听是否可以继续发送数据了,如果可以,接收方就告诉他此时接受窗口的大小;如果接受窗口大小还是为0,则发送方再次刷新启动定时器。

TCP报文段发送时机的选择

TCP报文发送时机主要有以下几种选择途径:

  • TCP维持一个变量,它等于最大报文段长度MSS,只要缓存中存放的数据达到MSS字节就组装成一个TCP报文段发送出去。
  • 由发送方的应用程序指明要求发送报文段,即TCP支持的推送操作
  • 是发送方的一个计时器期限到了,这时就把当前已有的缓存数据装入报文段发送出去。

TCP安全

SYN攻击:SYN攻击属于DOS攻击的一种,针对半连接队列的,服务器的资源在二次握手时进行分配(进入SYN_REC),而客户端的资源在第三次分配,SYN攻击通过不断向listening状态的服务器发送SYN请求,来占满半连接队列,从而使得服务器无法和其它客户端建立连接,最后导致服务器死机。

防御方法:SYN cookie,在TCP服务器收到TCP SYN包并返回TCP SYN+ACK包时,不分配一个专门的数据区,而是根据这个SYN包计算出一个cookie值。在收到TCP ACK包时,TCP服务器在根据那个cookie值检查这个TCP ACK包的合法性。如果合法,再分配专门的数据区进行处理未来的TCP连接。

Note:
TCP虽然理论上说是可靠的,但是在实际中并非可靠,在很多网络情况下TCP都不能实现可靠服务。

UDP报文格式

用户数据报协议(User Datagram Protocol),面向报文的,无连接,不可靠的。
UDP没有拥塞控制,同时支持一对一,一对多,多对一,多对多的交互通信,而TCP只支持一对一,UDP的头部开销也比TCP小,只有8字节
在这里插入图片描述

面试题

1.TCP的可靠体现在?

  1. 超时重传:接收端在接收数据时检测出了差错,直接丢弃该包,然后什么都不做,一直等,直到发送端超过一段时间后任然没有收到确认,重传这个数据。或者是接收端收到了,但是发送的确认,发送端没有收到,发送端任然会执行超时重传。为了实现这个功能在发送前就需要暂时保留已发送分组的副本。
  2. 确认丢失或者迟到:第一种当是在接收端发送的确认没有被接受端收到时,接收端收到重传后就会丢弃该报,然后重新发送ack。第二种当是检测错误而收到的重传就会收下并发送ack。还有一种是整个传输都没有差错,只是确认包迟到了,处理任然按第一种处理。
  3. TCP还有拥塞控制和流量控制。

2.TCP四次挥手原因
第一次握手时,client是告知server端我的数据已经发送完了,准备关闭连接了,server要准备将还没发送完的数据发送完,没开始发送的就不要发送了,第二次握手就是返回ack,第三次就是通知client我已经发送完了可以关闭了,然后第四次就返回ack,server关闭,client经过2msl关闭。

3.TCP三次握手原因
三次握手本质目的是同步连接双方的序列号(seq)和确认号(ack)并交换 TCP窗口大小信息。
(计算机网络:如果只使用两次握手会造成资源浪费)

4.2MSL
● 确保最后一个确认报文能够到达。如果 B 没收到 A 发送来的确认报文,那么就会重新发送连接释放请求报文,A 等待一段时间就是为了处理这种情况的发生。
● 等待一段时间是为了让本连接持续时间内所产生的所有报文都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文。

5.tcp和 udp 有什么区别
在这里插入图片描述
6. 三次握手和四次握手的缺点

  1. syn flood攻击
    SYN- Flood攻击是当前网络上最为常见的DDoS攻击,也是最为经典的拒绝服务攻击,它就是利用了TCP协议实现上的一个缺陷,通过向网络服务所在端口发送大量 的伪造源地址的攻击报文,就可能造成目标服务器中的半连接队列被占满,从而阻止其他合法用户进行访问。
  2. Time-wait
    如果在tcp建立了许多短链接,这些短链接都会等待2msl,致其无法与下游模块建立新HTTP连接。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值