计算机网络 - 传输层(TCP/UDP层)

3,520 阅读7分钟

一、简介

TCP/IP协议中,传输层给应用层提供服务
TCP/IP协议栈中,传输层只包含两个协议:

  • TCP协议:可靠性传输,面向连接,提供差错检测
  • UDP协议:不可靠传输,无连接

  • 一般约定用传输层协议 + 端口号来标识上面应用层使用了什么协议。

  • 数据在网络上传输,通过网络层的IP地址找到目标主机,通过传输层的端口号定位目标主机上的服务(应用程序)。所以传输层为相互通信的应用进程提供了逻辑通信

  • 端口号:16位,本地唯一即可,只有本地意义。

二、UDP协议

主要特点

  • 无连接,发送之前不需要建立连接,一般一个数据包就能完成的通信使用UDP。例如,请求CDN解析网址。
  • 最大努力交付。不保证可靠交付,不使用拥塞控制。
  • 面向报文的。适合多媒体通信的要求。适合于多播通信。
  • 支持一对一、一对多、多对一和多对多的交互通信。
  • 首部开销小,只有8字节。

UDP数据报结构

  • 伪首部:2个字节。为了计算检验和,取网络层首部的一部分信息参与计算。

三、 TCP协议

TCP协议的特点

  • 面向连接
  • 只能是点对点的通信
  • 提供可靠交付的服务
  • 实现拥塞控制功能
  • 实现流量控制功能
  • 面向字节流传输

流式传输

应用层发送数据是把数据放到了操作系统的TCP发送缓存中。操作系统发送时,去TCP发送缓存中取数据组成TCP数据包。应用层一次发送了8个字节的数据,操作系统第一次从发送缓存取出5个字节发送是可以的。或者应用层分别发送了一个8字节和一个10字节的包,操作系统从缓存中取出18个字节一次发送也是完全可以的。接收端解析后,把字节流按顺序放入TCP接收缓存,每次从缓存中取一定的字节(跟发送端应用程序一次发送多少个字节没有关系)数递交给应用层。

由于应用层一次发送数据的大小和传输层一次递交给接收端应用层的数据的大小不一定完全一样,所以应用层需要处理TCP粘包问题。

套接字(Socket)

IP+端口可以表达TCP传输中的一个端点。IP+Port称为套接字。

如何实现可靠传输
(后面我会更新一篇专栏更加详细的阐述可靠性传输的实现)

  • 自动重传协议(ARQ)

    发送端发送一个数据之后等待接收端响应成功接收的确认后,再发送下一个数据包(停止等待协议)。
    一定时间内没有收到确认,发送端重传这个数据包(超时重传),最大等待时间略大于往返时延(RTT)。所以重传是自动进行的。

    如果接收端发送的确认丢失,或者确认迟到即确认没有在最大等待时间内到达发送端,这两种情况也都会导致发送端进行超时重传。这种情况下,接收端会丢弃重复的数据。所以TCP协议还支持去重的功能。

    通俗来说,ARQ协议就是,只要你没在一定时间内告诉我收到了,我就认为你没收到。

    停止等待协议实现简单,但是信道利用率低。因为发送数据的时间要远小于等待的时间。

  • 流水线传输

上面提到的ARQ传输协议的信道利用率非常低,已经被淘汰。目前TCP协议中采用流水线传输。即发送端发送一个数据包后,不等待接收端的ACK就立即发送下一个准备好的数据包。当一个包发送了时间x之后,还没收到收到这个包的ACK,就会重传这个包。x的取值略大于网络的往返时延TTL。假设在时间x内,可以发送n个数据包,那么发送端必须要缓存n个还没有收到ack的数据包。即发送端维护一个发送窗口。

发送窗口内是发送了还没有收到ACK的数据包,当发送窗口内有数据收到ACK之后,就可以被移出窗口,并且窗口左边沿向前推进。当窗口内的数据大于窗口的最大长度时,就不能继续发送数据了,需要等待ACK或者进行重传。

举个例子,上图中假如滑动窗口的大小是5,此时窗口已经被占满。有两种情况,如果收到了数据包1的ACK那么数据包1被溢出窗口,窗口向前推进继续发送第6个包。如果没收到ACK,会重传数据包1,其实窗口也会向前推进,次数数据包6的内容跟数据包1的内容相同,即数据包1的重传。

累计确认是对上述机制的进一步优化,即接收端如果收到了连续的数据包1、2、3,只需要在ACK里回复收到了3,发送端就可以隐式的知道1、2、3都发送成功了。

TCP报文段格式:

  • 源端口、目标端口:用于标识TCP链接两端进行通信的两个应用程序。
  • 序号:应用层下发的数据在传输层可能被分段传输。序号指的是。TCP数据包数据部分的第一个字节是应用层下发的数据的第几个字节。
  • 确认号:TCP数据包中数据部分的最后一个字节是应用层下发的数据中的第几个字节再加上1。接收端发送ACK时携带的是这个确认号,实际上接收发送端下一个发送数据的序号。
  • 数据偏移:数据部分起始位置相对于整个数据包的偏移字节数。由于首部有长度可变的部分,所以需要数据偏移。
  • URG:如果为1,优先传输,不管发送缓存中还有多少多少数据在排队。
  • ACK:如果是0,确认号无效,否则有效。
  • SYN:SYN=1,表示是建立会话的控制包。此时发送端序号=0,确认号=0,ACK=0(确认号无效)。接收端序号=0,确认号=1,ACK=1(发送端知道连接建立成功了,可以开始发送第一个数据包了)。
    SYN攻击:利用建立会话的机制进行攻击,给主机发送大量建立连接的请求,请求数据包中填写一个不存在的源IP地址。造成主机一直在等待建立连接。或者目标IP和源IP都填写主机自己的IP,让主机跟自己建立大量的TCP连接。占用大量的主机资源,造成主机不能继续响应正常的连接建立请求。
  • PSH: 如果是1。接收端缓存优先把这个数据包递交给应用层,不管接收缓存里是否还有未向上递交的数据。
  • RST:如果是1,代表异常中断,告诉对端立即断开连接。
  • FIN:如果是1。通信正常结束,释放连接。
  • 窗口:TCP通信中,需要告诉对端自己的接收缓存最多能存放多少字节的数据。对端获知后设置自己的发送缓存为同样的大小。在建立连接的SYN数据包中通知对端。
  • 校验和:与上面提到的UDP协议中的校验和的计算方式一致。
  • 紧急指针:URG为1时设置的紧急指针才会生效。指示URG包中前多少个字节是需要紧急处理的。
  • 选择(可变长度):可以用于通知对端自己能够处理的最大的TCP数据报的长度。可以用于通知对端自己是否支持选择性确认。