Linux网络编程:传输层协议|UDP|TCP

目录

知识引入:

1.UDP协议

1.1.UDP协议端格式

1.2.UDP的特点

2.TCP协议

2.1.TCP协议格式

 2.2.不同类型报文和TCP通信

2.3.确认应答机制

2.4.流量控制

2.5.超时重传机制

2.6.TCP链接管理机制|三次握手|四次挥手

2.7.滑动窗口

2.8.拥塞控制

2.9.延迟应答|捎带应答

3.TCP的其他知识

3.1.面向字节流

3.2.粘包问题

3.3.TCP异常问题

3.4.全连接队列 

3.5.TCP总结

4.TCP与UDP

4.1.UDP如何实现可靠传输

4.2.TCP与UDP比较

基本概念

连接与数据传输

可靠性

头部开销

使用场景


知识引入:

端口号:

当应用层获得一个传输过来的报文时,这时数据包需要知道,自己应该送往哪一个应用层的服务,这时就引入了“端口号”,通过区分同一台主机不同应用程序的端口号,来保证数据传输的可靠性!

而我们在之前的学习知道,ip地址是唯一的地址标识,那么我们借助ip地址和端口号是不是就能找到网络中唯一的一台主机?答案是肯定的,这也就是传输层协议存在的意义之一!

 在TCP/IP协议中, 用 "源IP", "源端口号", "目的IP", "目的端口号", "协议号" 这样一个五元组来标识一个通信 

如图我们通过源ip和源端口号,就知道信息是从哪来的,知道了目的ip和目的端口号就知道信息是去往哪里的。那么就能够实现网络中唯二的两个进程通过网络进行进程间通信了!!!


端口号划分:

  • 0 - 1023: 知名端口号, HTTP, FTP, SSH等这些广为使用的应用层协议, 他们的端口号都是固定的.
  • 1024 - 65535: 操作系统动态分配的端口号. 客户端程序的端口号, 就是由操作系统从这个范围分配的.

查看网络连接状态命令:

// -ntpl n-带数字 t-TCP协议 p-服务名称 l-只查看listen服务
sudo netstat -ntpl
// ss命令也可以查网络服务
ss -nltp

常用选项:

  • n 拒绝显示别名,能显示数字的全部转化成数字l 仅列出有在 Listen (监听) 的服務状态
  • p 显示建立相关链接的程序名
  • t (tcp)仅显示tcp相关选项
  • u (udp)仅显示udp相关选项
  • a (all)显示所有选项默认不显示LISTEN相关

1.UDP协议

1.1.UDP协议端格式

如图:UDP协议报文前8字节为UDP协议的报头,后面的即为有效载荷。

我们知道网络传输需要解决的四个问题:

  • 报文如何将报头和有效载荷分离
  • 有效载荷如何向上交付给对应应用层程序
  • 报文内容是否完整
  • 报文内容是否有误

联系UDP协议格式,我们发现以上四个问题对应:

  • 解析固定报头长度来分开报头和有效载荷
  • 再通过目的端口号将有效载荷交付给应用层服务
  • 16位UDP长度对应着报文的长度(当长度不符时,直接丢包)
  • 而16位UDP检验和检测是否在传输过程中出现0变成1、1变成0

通过UDP协议报头的设计,那么我们就解决了网络传输的4个问题,而在这里我们也能理解报头(协议)是一个结构化字段。

struct UdpHeader
{
    uint32_t src_port:16;
    uint32_t dest_port:16;
    uint32_t length:16;
    uint32_t check_sum:16;
}

又因为传输层是实现在操作系统中,也就是操作系统需要维护获得的UDP报文,需要对UDP报文实现“先描述再组织”

如图为:发送端如何形成UDP报文结构示意

  1.  首先应用层需要存在报头的结构化对象和管理报文信息的sk_buff结构化对象
  2. 当用户准备通过sendto进行发送时,通过bind函数将对应端口号写入进报头信息中,另外有效载荷写入sk_buff指向的缓冲区中,这时有tail执行有效载荷的尾,_data指向有效载荷的头部(_data-_tail即为有效载荷的长度)
  3. 传输层首先将_data向左移动8个字节,给UDP的报头放入,接着完善报头中的报文长度信息和check_num(通过二进制位运算)
  4. 最终就形成了一段UDP报文

因为系统中可能存在多份待发送的UDP报文,所以我们需要通过数据结构来管理这些报文。最终UDP协议就实现了!!!

当接收端接收到UDP报文时:

  1. 先分开报头和有效载荷(通过分离前8个字节数据),然后读取报头中的报文长度,就能找到有效载荷
  2. 通过对有效载荷进行二进制位运算,判断前后的check_num和为0,不为0就丢弃报文。
  3. 获取到报文后就可以通过对应端口,找到接受端的应用层服务

最终我们就完成了UDP通信!!!

1.2.UDP的特点

UDP传输的过程类似于寄信,为什么这么说呢,这和UDP的特点有关

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

 我们在传输报文时,只要知道对端的地址就可以进行传输,不需要事先通知对方才能够寄信。另外,当我们写信出去后我们就无法获得这封信的状态,除非他被对方收到,并且返回收到信息给你。最终,信的寄和读都是一次的行为,跟你信里面写了多少内容无关,是一个整体。


值得注意的是:UDP协议允许报文最长为16位,也就是64k的大小,当我们传输的内容大于64k时,我们就需要多次将数据分为64kb的报文,接着不断传输。

2.TCP协议

TCP协议的学习任务十分繁重,建议慢慢品。

2.1.TCP协议格式

 如图TCP协议格式明显复杂于UDP协议,接下来我们学习一下TCP协议中的重要字段。

ps:如果发现这些重要字段的学习过于抽象,可以大概记忆一下概念,结合下面的TCP机制学习!


选项

表示TCP协议标准报头携带的额外信息,用于增强TCP协议的功能和灵活性,大小为0-40字节(与4位首部长度有关)。


4位首部长度(4位TCP报头长度)

4位首部长度对应着0000-1111,即【0,15】,并且1单位对应着4个字节,所以最终4为首部长度对应着【0,60】字节。

在实际应用中4位首部长度是用来分离协议报头和有效载荷的!

  1. 首先当应用层获取到报文时,截取前20字节的标准报头,访问到4位首部地长度
  2. 获取到4位首部长度,如果4位首部长度为20(表示选项为空),那么后续数据就是有效载荷。如果大于20字节,说明需要截取大于部分之后为有效载荷 

6位标志位

  • URG: 紧急指针是否有效(紧急任务报文)
  • ACK: 确认号是否有效(确认报文)

  • PSH: 提示接收端应用程序立刻从TCP缓冲区把数据读走(询问报文段)

  • RST: 对方要求重新建立连接; 我们把携带RST标识的称为复位报文段

  • SYN: 请求建立连接; 我们把携带SYN标识的称为同步报文段 

  • FIN: 通知对方, 本端要关闭了我们称携带FIN标识的为结束报文段

一个标志位对应着一个比特位!而6位标志位是为了定义报文的类型,因为服务器一般只有一个,而获取服务的客户端有无数个,那么服务器在通信时就需要标识不同的报文类型 


 16位窗口大小

窗口大小字段用于告诉接收端,发送端目前还有多少数据没有收到确认,还可以发送多少数据。用于实现流量控制!!!


 32位序号和32位确认序号

32位序号用来保证数据的按序到达,32位确认序号用来保证发送端发送的哪些数据已经被接受到了(该序号之前的数据,全部收到)。


16位紧急指针

表示紧急数据在有效载荷中的偏移量。但是大小只有一字节

需要结合6位标志位中的URG标志


 2.2.不同类型报文和TCP通信

我们知道在TCP协议字段中存在6位的标志位,而这6位的标志位对应着6种类型的报文,分别在TCP通信的不同场景中发挥着各自的作用。

 因为一个服务器会处理大量客户端的报文请求,所以我们也需要学习不同类型的报文请求!!!在这部分内容中我们主要讲解URG、RSH、RST标志位对应字段的报文,其他标志位都是比较常见的我们会在TCP整个模块或多或少会有提及……


处理紧急任务报文---URG

在接收端,报文的维护是通过链表式的队列,也就是处理任务时需要遵守先进先出原则,当出现一些紧急任务时(比如:客户端发现传输的大文件数据传错了,这时取消传输),就需要将这个任务及时的关闭,那么就需要将该报文插入

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值