UDP是属于传输层,逻辑上同层是直接通信,物理上仍旧要走协议栈。

端口号

端口号(Port)标识了一个主机上进行通信的不同的应用程序在这里插入图片描述
在 TCP/IP 协议中, 用 “源 IP”, “源端口号”, “目的 IP”, “目的端口号”, “协议号” 这样一个五元组来标识一个通信(可以通过 netstat -n 查看)
在这里插入图片描述
在这里插入图片描述

端口号范围划分

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

认识知名端口号(Well-Know Port Number)

有些服务器是非常常用的, 为了使用方便, 人们约定一些常用的服务器, 都是用以下这些固定的端口号:
• ssh 服务器, 使用 22 端口
• ftp 服务器, 使用 21 端口
• telnet 服务器, 使用 23 端口
• http 服务器, 使用 80 端口
• https 服务器, 使用 443
执行下面的命令, 可以看到知名端口号

cat /etc/services

我们自己写一个程序使用端口号时, 要避开这些知名端口号.

两个问题

  1. 一个进程是否可以 bind 多个端口号?
  2. 一个端口号是否可以被多个进程 bind?

在这里插入图片描述

前者可以的,因为可以通过一个端口找到唯一的一个进程。
后者不可以。
在OS中对于进程与端口的关系有可能是以哈希表来进行管理的
在这里插入图片描述
若是真的一个端口号指向多个PCB,那么就会造成严重的哈希冲突,当然这只是其中一小部分原因。
其他的例如OS不能很好的找到对应进程导致通信混乱,还有协议规定等等。

UDP 协议

UDP 协议端格式

我们很早就说过协议的本质就是一个结构体,今天我们正式的见一见结构体长什么样子
在这里插入图片描述

在这里插入图片描述
UDP是我们学的最简单的一个协议了。
而我们每研究一个协议时总要先分析两个共性问题

  1. 如何解包?
  2. 如何分用?

解包就需要16位UDP长度了,表示整个数据报(UDP 首部+UDP 数据)的最大长度;
而UDP上层那么多进程,该如何准确的知道给那个进程?就在于port了。

关于16位UDP检验和:如果校验和出错, 就会直接丢弃;

UDP 的特点

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

面向数据报

应用层交给 UDP 多长的报文, UDP 原样发送, 既不会拆分, 也不会合并;
用 UDP 传输 100 个字节的数据:

如果发送端调用一次 sendto, 发送 100 个字节, 那么接收端也必须调用对应的一次 recvfrom, 接收 100 个字节;
而不能循环调用 10 次 recvfrom, 每次接收 10 个字节;

UDP 的缓冲区

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

为什么不需要发送缓冲区?
不需要保证可靠性
为什么需要发送缓冲区?
大概保证收到的报文不会太离谱,另外,上层在处理数据时我们还可以继续接受,进而提高效率。

UDP 的 socket 既能读, 也能写, 这个概念叫做 全双工在这里插入图片描述
结论:

  1. UDP协议是结构体
  2. 无法送缓冲区
  3. 无连接,不可靠,面向数据报

深刻理解UDP

报头

我们在应用层时还需要序列化反序列化,为什么UDP这啥都不需要?
我们在传输层直接发送结构体,也就是二进制
在这里插入图片描述
我们使用一个指针接收后直接解引用即可得到。

为什么应用层不推荐这样做?
其一是技术原因(不方便移植,双方OS不一样,语言不一样,结构体位段不一样…)
其二是业务原因(需要频繁更改需求导致好不容易解决的技术原因白搭)

而传输层适合是因为协议规定好了字段,不需要担心。

报文

在这里插入图片描述
每一层都可能有各种各样的报文,有的在向上交付,有的向下交付,所以OS要对报文进行管理,所以需要先描述在组织!

其中描述报文的结构体叫做struct sk_buff,其中我们只需关注char* head与data指针

在传输层会给每个报文生成一块缓冲区
在这里插入图片描述
刚开始时head与data都指向同一个位置,那么如何添加报头?
将head指针-=时就是封包,+=就是解包
在这里插入图片描述
完~

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部