传输层两大协议—TCP&UDP

UDP协议

  1. UDP协议端格式:

2. UDP协议的特点:

  • 无连接: 知道对端的IP和端口号就直接进行传输, 不需要建立连接;
  • 不可靠: 没有确认机制, 没有重传机制; 如果因为网络故障该段无法发到对方, UDP协议层也不会给应用层返回任何错误信息;
  • 面向数据报: 不能够灵活的控制读写数据的次数和数量;

3. UDP的缓冲区:
UDP没有真正意义上的发送缓冲区. 调用sendto会直接交给内核, 由内核将数据传给网络层协议进行后续的传输动作;
UDP具有接收缓冲区. 但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致; 如果缓冲区满了, 再到达的UDP数据就会被丢弃;

4. 全双工:UDP的端点socket 既能读也能写

5. UDP协议的一些注意事项:

  • UDP的源端口号,目的端口号等占2个字节,16个bit位;
  • UDP的最大传输数据量为64K(16个字节);
  • 需要传输更多的数据只能分包传递,多次发送,由接收端进行拼接;

TCP协议

TCP全称为 “传输控制协议(Transmission Control Protocol”). 人如其名, 要对数据的传输进行一个详细的控制;

1. TCP协议端格式:
在这里插入图片描述

  • ACK: 确认号是否有效
  • PSH: 提示接收端应用程序立刻从TCP缓冲区把数据读走
  • RST: 对方要求重新建立连接; 我们把携带RST标识的称为复位报文段
  • SYN: 请求建立连接; 我们把携带SYN标识的称为同步报文段
  • FIN: 通知对方, 本端要关闭了, 我们称携带FIN标识的为结束报文段

2. 确认应答机制:
每一个ACK都带有对应的确认序列号, 意思是告诉发送者, 我已经收到了哪些数据; 下一次你从哪里开始发.

举个例子:毛毛要和女神吃饭,就要先给女神发送消息“我们去吃饭吧~~”;女神回复说“好的~”;这时毛毛约吃饭这件事就结束了并宣告成功!之后就可以进行一些准备,以一个良好状态去面对自己的女神.

3. 超时重传机制:

  • 主机A发送数据给B之后, 可能因为网络拥堵等原因, 数据无法到达主机B;
  • 如果主机A在一个特定时间间隔内没有收到B发来的确认应答, 就会进行重发;

还是接着上面的列子:若是毛毛发送的消息,女神没有收到怎么办,重传机制(舔)就起作用了,毛毛就会安慰自己说“女神网卡了,可能没收到”,于是乎隔一段时间再给女神重复发消息。(下面是linux中的超时重传机理:每次重传时间间隔以指数级增加,也挺符合人性谁tm不会累~)

TCP为了保证无论在任何环境下都能比较高性能的通信, 因此会动态计算这个最大超时时间:

  • Linux中(BSD Unix和Windows也是如此), 超时以500ms为一个单位进行控 制, 每次判定超时重发的超时时间都是500ms的整数倍.
  • 如果重发一次之后, 仍然得不到应答, 等待 2*500ms 后再进行重传.
  • 如果仍然得不到应答, 等待 4*500ms 进行重传. 依次类推, 以指数形式递增.
  • 累计到一定的重传次数, TCP认为网络或者对端主机出现异常, 强制关闭连接.

5. 连接管理机制(三次握手,四次挥手):

服务端状态转化:

  • [CLOSED -> LISTEN] 服务器端调用listen后进入LISTEN状态, 等待客户端连接;
  • [LISTEN -> SYN_RCVD] 一旦监听到连接请求(同步报文段), 就将该连接放入内核等待队列中, 并向客户端发送SYN确认报文.
  • [SYN_RCVD -> ESTABLISHED] 服务端一旦收到客户端的确认报文, 就进入ESTABLISHED状态, 可以进行读写数据了.
  • [ESTABLISHED -> CLOSE_WAIT] 当客户端主动关闭连接(调用close), 服务器会收到结束报文段, 服务器返回确认报文段并进入CLOSE_WAIT;
  • [CLOSE_WAIT -> LAST_ACK] 进入CLOSE_WAIT后说明服务器准备关闭连接(需要处理完之前的数据); 当服务器真正调用close关闭连接时, 会向客户端发送FIN, 此时服务器进入LAST_ACK 状态, 等待最后一个ACK到来(这个ACK是客户端确认收到了FIN)
  • [LAST_ACK -> CLOSED] 服务器收到了对FIN的ACK, 彻底关闭连接.

客户端状态转化:

  • [CLOSED -> SYN_SENT] 客户端调用connect, 发送同步报文段;
  • [SYN_SENT -> ESTABLISHED] connect调用成功, 则进入ESTABLISHED状态, 开始读写数据;
  • [ESTABLISHED -> FIN_WAIT_1] 客户端主动调用close时, 向服务器发送结束报文段, 同时进入FIN_WAIT_1;
  • [FIN_WAIT_1 -> FIN_WAIT_2] 客户端收到服务器对结束报文段的确认, 则进入FIN_WAIT_2, 开始等待服务器的结束报文段;
  • [FIN_WAIT_2 -> TIME_WAIT] 客户端收到服务器发来的结束报文段, 进入TIME_WAIT, 并发出LAST_ACK;
  • [TIME_WAIT -> CLOSED] 客户端要等待一个2MSL(Max Segment Life, 报文最大生存时间)的时间, 才会进入CLOSED状态.

三次握手:
在这里插入图片描述

还是例子:
对于毛毛要和女神打电话这件事如果成功的话就需要双方的耳麦的没问题
第一次握手:毛毛说“你能听到吗?”
第二次握手:女神说:“我可以,你呢?”(确认毛毛的麦没问题,女神的耳机没问题)
第三次握手:毛毛回复道:“俺也一样~~” (确认女神的麦没问题,毛毛的耳机没问题)
历经三次握手,两人正常进入“童话”模式~

四次挥手:
在这里插入图片描述
总是例子:此刻毛毛要和女神挂电话了(四次挥手)
第一次挥手:女神说“我睡觉了,先挂了!”
第二次挥手:毛毛说:“好的~”
第三次挥手:但毛毛对女神的祝福还没说,毛毛就说“晚安,好梦~”
第四次挥手:女神说“好哒~”

注意事项: 为什么是TIME_WAIT的时间是2MSL?

  • MSL是TCP报文的最大生存时间, 因此TIME_WAIT持续存在2MSL的话
    就能保证在两个传输方向上的尚未被接收或迟到的报文段都已经消失(否则服务器立刻重启, 可能会收到来自上一个进程的迟到的数据, 但是这种数据很可能是错误的);
  • 同时也是在理论上保证最后一个报文可靠到达(假设最后一个ACK丢失, 那么服务器会再重发一个FIN. 这时虽然客户端的进程不在了, 但是TCP连接还在, 仍然可以重发LAST_ACK);

和超时重传概念差不多(内核终止条件不同)
”栗子“:上面毛毛说了”晚安“到通话结束需要两个步骤
1.传输消息到女神那边
2.毛毛等待女神回应的时间
2MSL = 1MSL(消息报文(晚安)的传递时间)+1MSL(等待回复的时间,毕竟也不能一直舔吧~~)

over~~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值