传输层——UDP协议


负责数据能够从发送端传输接收端

前面提及到应用层协议HTTP,其目的是为了保护数据的安全,而传输层则是为了保证数据能够可靠地传送到目标地址;

端口号

端口号(Port)标识了一个主机上进行通信的不同的应用程序

在主机上往往存在着不同的多种服务,从网络中获取的数据在进行向上交付时,在传输层就会提取出该数据对应的目的端口号,进而确定该数据应该交付给当前主机上的哪一个服务进程
在这里插入图片描述
在TCP/IP协议中, 用 “源IP”, “源端口号”, “目的IP”, “目的端口号”, “协议号” 这样一个五元组来标识一个通信
在这里插入图片描述
可以通过netstat -n命令来查看五元组的信息

端口号范围划分

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

常见的端口号:http(80),https(443),ssh(22),ftp(21),mysql(3306)

一个进程是否可以bind多个端口号?

  • 可以!多个端口唯一标识的是同一个进程,这与端口号用来标识进程的唯一性不冲突。

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

  • 不可以!端口号是用来表示一个唯一的进程,如果绑定一个已经被绑定的端口号,就会绑定失败。

UDP协议

UDP协议端格式

在这里插入图片描述
UDP的报头当中只包含四个字段,每个字段的长度都是16位,总共8字节;
对于UDP的解包直接提取前八个字节就是报头,其他的就是有效载荷;

struct udp_hdr
{
	uint32_t src_port:16;
	uint32_t dst_port:16;
	uint32_t udp_len:16;
	uint32_t udp_check:16;
}

UDP数据封装

  • 当应用层将数据交给传输层后,在传输层就会创建一个UDP报头类型的变量,然后填充报头当中的各个字段,此时就得到了一个UDP报头
  • 此时操作系统再在内核当中开辟一块空间,将UDP报头和有效载荷拷贝到一起,此时就形成了UDP报文

UDP数据分用

  • 当传输层从下层获取到一个报文后,就会读取该报文的钱8个字节,提取出对应的目的端口号。
  • 通过目的端口号找到对应的上层应用层进程,然后将剩下的有效载荷向上交付给该应用层进程。

UDP的传输是无连接的,不可靠的、面相数据报的;(我只管发送收不收的到不归我管)
面向数据报:
应用层交给UDP多长的报文,UDP就原样发送,既不会拆分,也不会合并;
发送端调用一次sendto,发送100字节,那么接收端也必须调用对应的一次recvfrom,接收100个字节;

UDP如何决定将有效载荷交付给上层的哪一个协议?

应用层每个进程都绑定有端口号,UDP就是通过报头当中的目的端口号(dst_port)来找到对应的应用层进程的

UDP的缓冲区

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

为什么UDP要有接收缓冲区?

如果UDP没有接收缓冲区,那么就要求上层及时将UDP获取到的报文读取上去,如果一个报文在UDP没有被读取,那么此时UDP从底层获取上来的报文数据就会被迫丢弃;
网络资源是多次的,如果经常因为没有被上层读取报文而丢弃掉,这样十分浪费资源;
UDP会维护一个接受缓冲区,当有报文来到的时候,直接放入UDP接受缓冲区,UDP接收缓冲区当中没有数据那上层在读取时就会被阻塞;
将接收到的报文暂时的保存起来,供上层读取

UDP传输最大长度

UDP协议首部中有一个16位的最大长度. 也就是说一个UDP能传输的数据最大长度是64K(包含UDP首部);
如果需要传输的数据超过64K,就需要在应用层进行手动分包,多次发送,并在接收端进行手动拼装;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值