网站风格设计原则,长沙做网站公司哪家好,软件定制一般价格,wordpress手机不方便文章目录 #x1f4d6; 前言1. 再谈端口号1.1 端口号划分范围#xff1a;1.2 端口和进程的关系#xff1a;1.2 - 1 netstat1.2 - 2 pidof 1.3 源端口和目的端口#xff1a; 2. UDP协议2.1 UDP协议格式#xff1a; 3. 再谈write/read4. UDP需要接收/发送缓冲区吗5. UDP使用… 文章目录 前言1. 再谈端口号1.1 端口号划分范围1.2 端口和进程的关系1.2 - 1 netstat1.2 - 2 pidof 1.3 源端口和目的端口 2. UDP协议2.1 UDP协议格式 3. 再谈write/read4. UDP需要接收/发送缓冲区吗5. UDP使用注意事项 前言
在我们刚学习网络时我们知道网络是层状的结构前面所有的内容都是围绕着应用层展开的。 接着我们来学习操作系统内部最顶层协议叫做传输层协议。 应用层用应用的功能都是传输层提供的接口。
例如用http通信http协议底层用的是tcp协议。 https在密钥协商之前首先要将客户端和服务端的连接建立好所以在应用层的理解之下还要搞一下传输层协议。
传输层最典型协议有两种一个udp以个tcp对应的就是曾经学到的udp套接字和tcp套接字。 网络层状结构复习 1. 再谈端口号
端口号(Port)标识了一个主机上进行通信的不同的应用程序。
在写套接字的时候无论udp还是tcp在服务器启动时都必须bind得明确服务端的端口号一旦保存端口号底层在收到报文时操作系统在收到数据会根据对应的报文来进行数据处理根据端口号将数据推送到特定的服务中。 这四个概念非常重要在TCP / IP协议中用 “源IP”“源端口号”“目的IP”“目的端口号”。
端口号的位数是16位端口号
为什么在应用层写套接字时对应的端口号是16位呢 因为tcp或udp它的报头当中端口号的字段就是16位的。 也就是说在内核里面端口号就是16位。 所以在应用层使用系统接口时传入的端口号也只需要16位就够了。
1.1 端口号划分范围
端口号和服务是一一对应的。
0 ~ 1023 知名端口号HTTPFTPSSH等这些广为使用的应用层协议它们的端口号都是固定的。1024 ~ 65535 操作系统动态分配的端口号客户端程序的端口号就是由操作系统从这个范围分配的。
有些服务器是非常常用的为了使用方便约定一些常用的服务器都是用以下这些固定的端口号
ssh 服务器使用22端口。ftp 服务器使用21端口。telnet 服务器使用23端口。http 服务器使用80端口。https 服务器使用443。
查看知名端口号
cat /etc/services所以在自己写一个程序使用端口号时要避开这些知名端口号避免不必要的麻烦。
这些端口是被特定的服务所采用的 是因为有这个后端的守护进程sshd一直在后端运行所以在本地打开X-shelI时连接的就是这个服务由这个服务来帮助我们登录Linux。
1.2 端口和进程的关系
端口号是用来标定进程唯一性的。
一个进程是否可以bind多个端口号一个端口号是否可以被多个进程bind?
这是一个经典的问题因为端口号是用来标定进程唯一性的。所以一个端口号只能对应一个进程而一个进程是可以对应多个端口号的
一个进程可以同时监听和处理多个端口号上的网络数据。
1.2 - 1 netstat
netstat是一个用来查看网络状态的重要工具。
netstat是一个用于显示网络连接、路由表和网络接口等信息的常用命令。它可以在命令行界面下运行并提供了多种选项来获取特定类型的网络统计数据。
查看网络状态
netstat [选项]常用选项
-n拒绝显示别名能显示数字的全部转化成数字-l仅列出有在 Listen (监听) 的服务状态-p显示建立相关链接的程序名-t(tcp)仅显示tcp相关选项-u(udp)仅显示udp相关选项-a(all)显示所有选项默认不显示LISTEN相关
1.2 - 2 pidof
在查看服务器的进程id时非常方便。
pidof是一个用于查找指定进程名称所对应的进程ID的命令。在 Linux系统中可以使用这个命令来获取特定进程的PID进程 ID以便进行后续处理。
通过进程名查看进程id
pidof [进程名]常用选项
-s只返回一个进程 ID如果有多个匹配结果。-x同时匹配进程名和命令行参数而不仅仅是进程名。-o仅返回指定用户运行的进程 ID。-c只返回匹配的进程数量而不返回进程 ID。
1.3 源端口和目的端口
源端口Source Port是指发送数据包的应用程序或进程所使用的端口号 在计算机通信中数据从源端发送到目的端时需要通过网络传输源端口用于标识发送方应用程序或进程。 目的端口Destination Port是指接收数据包的应用程序或进程所使用的端口号 当数据包到达目的地后通过目的端口将数据包传递给相应的应用程序或进程。
源端口和目的端口组合在一起形成一个套接字Socket在网络中充当数据交换的门户。通过源端口和目的端口的配对可以确保数据包被正确地发送和接收并且能够正确地路由到目的地。 在传输层协议中如TCP传输控制协议和UDP用户数据报协议源端口和目的端口信息包含在数据包的首部中用于标识通信双方的应用程序或进程。通过源端口和目的端口的匹配网络设备可以将接收到的数据包正确地路由和交付给相应的应用程序或进程。 2. UDP协议
我们之前用UDP协议写过一个简单的聊天程序 UDP的服务端 客户端。 我们再来回顾一下UDP的一组概念
未来学习的所有协议必须考虑两个共性问题
如何封装和解包如何分用
在我们之前网络基础中讲到过封装解包和分用的过程 复习传送门。
我们以UDP为例
封装 udp当上层应用调用sendto要发送信息。 在传输层添加udp报头时就是给原始数据前面再写上8字节数据就可以了报头一加。 udp采用的是定长报文。 解包 收到消息之后只需要提取前8个字书就是报头。 剩下的就是报文的有效载荷了。 分用 udp上面还有应用服务那么udp收到报文之后它如何知道要将报文转发给上层的哪一个应用呢 源端口和目的端口
UDP的特点
UDP传输的过程类似于寄信。
无连接 知道对放的ip地址和端口号就能直接进行传输不需要建立连接。不可靠 没有确认机制没有重传机制如果因为网络故障该段无法发到对方UDP协议层也不会给应用层返回任何错误信息。面向数据报 不能够灵活的控制读写数据的次数和数量。
udp一定不会是为了可靠性而做过多的设计 udp不可靠报文丢了就是真的丢了。丟包了不重要因为允许丢包。 面向数据报
应用层交给UDP多长的报文UDP原样发送既不会拆分也不会合并。
udp要么不收报文要么收到的就是一个完整的报文。因为有udp长度和校验和保证。报文有自己的报头长度和总长度。当收到了一批二进制可以正常的去提取一个一个的完整的udp报文。面相数据报的通信方式有点像寄信寄了十封信就能够收到十封信信和信用信封分开来。
假设用UDP传输100个字节的数据 如果发送端调用一次sendto发送100个字节那么接收端也必须调用对应的一次recvfrom接收100个字节而不能循环调用10次recvfrom每次接收10个字节。 2.1 UDP协议格式 UDPUser Datagram Protocol的报头长度固定为8个字节。
网络协议栈的tcp/ip协议是内核中实现的内核是用C语言实现的报头本质上也是一个对象。
假设报头代码是如下并非源码实现
struct udp_hdr
{unsigned int src_port : 16;unsigned int dst_port : 16;unsigned int udp_len : 16;unsigned int udp_check : 16;
};udp报头类型C语言中称之为位段。
添加报头的本质其实就是拷贝对象
这些字段全都是位段给数据添加报头就是把对应的位段的对象一定义属性一填然后把对象拷贝到属性的前面最后就形成一个报文。
16位UDP长度是UDP报文整体的长度单位Byte
16位UDP长度表示整个数据报UDP首部 UDP数据的最大长度。16位UDP检验和主要是为了防止报文当中有些字段出现一些偏差需要进行校验。如果校验和出错就会直接丢弃
UDP叫做面向数据报体现在它不是流式的报文和报文有明显边界。
16位UDP检验和
如果UDP校验和失败了说明数据是有问题的。如果校验和出错就会直接丢弃报文数据。 3. 再谈write/read
之前我们学习过操作系统的文件操作的write/read接口我们在使用者的身份来看只看到了最后的结果但是详细的过程我们真的清楚吗下面我们看看下面过程。 文件中我们把数据通过文件描述符写到文件当中
其实并不是把数据写到了磁盘当中的特定文件。而是把数据写给了操作系统的缓冲区里然后操作系统再根据它自己的策略将数据刷新到外设比如磁盘上。所以之前学习文件时的write函数不能叫做将数据写入到磁盘而应该叫做拷贝函数。先将应用层数据拷贝到内核再由操作系统定向的根据自己的策略进行IO更新到磁盘上。 调用write和sendto这样的系统接口并没有把数据发送到网络里而是把数据交给了操作系统
真正发送数据不是我们发的而是我们将数据交给操作系统让操作系统帮我们发的。所以我们之前写的所有的网络或者文件的接口根本就不能叫做发送和写入接口而应该叫做拷贝函数。所以我们在学习网络中大部分用套接字发送的数据其实根本就没有发送数据而只是将数据拷贝到了一个叫tcp或udp所对应的缓冲区中
数据什么时候发怎么发这个工作就由操作系统来决定了。
4. UDP需要接收/发送缓冲区吗 UDP没有也不需要发送缓冲区
因为数据太简单了上层拷贝的数据到了内核。内核添加八个字节的报头三四个字段一填。填完之后操作系统直接将报文交给了网络协议栈。到了网络层后续就是ip的任务了。不需要维护可靠性不需要将数据暂存起来。只需要将数据交给内核这个工作就完了。
发送的时候直接交给操作系统操作系统直接向上交付速度很快不需要缓冲区。所以就不需要真正的发送缓冲区。 UDP 在发送端不一定需要显式的发送缓冲区但通常会由操作系统提供一个临时的缓冲区来保存待发送的数据。 UDP需要接收缓冲区吗需要
作为udp在进行数据接收的时候当底层数据没就绪时在应用层的表现就是recvfrom接口是阻塞的。一直卡在那里当底层数据就绪时recvfrom接口才会返回并将数据拷贝到提前设置到recvfrom的缓冲区里面。
如果udp收到了数据操作系统压力很大收到了数据还没来得及调度这个进程应用层进程来不及接收数据如果内核不存在接收缓冲区一定会出现数据的丢失问题。
udp是不保证可靠性但是并不代表它可以在可靠性这件事上肆意妄为重点
如果没有接收缓冲区一旦应用层进程来不及接收数据这个数据直接就丢了所以udp是具备接收缓冲区的数据收到之后如果上层来不及处理。会暂时保存在缓冲区里等到应用层来得及读取了再把数据从缓冲区里拷过去。 然尽管UDP协议本身没有应用层缓冲区但在实际应用中很多基于UDP的应用程序会在应用层上实现自己的缓冲机制。这是为了解决数据传输中可能出现的丢包、乱序等问题。应用层缓冲区可以用来存储接收到的数据包以便应用程序按照自己的需求进行处理、重组或重发等操作。 需要注意的是应用层缓冲区是由应用程序自己实现和管理的不同的应用程序可能有不同的缓冲策略和机制。使用UDP协议时开发者需要在应用程序中自行管理缓冲区确保数据的完整性和正确性。 UDP报文乱序到达
udp不保证可靠性就导致了数据不能够按序到达。虽然有接收缓冲区但是接收缓冲区里数据的顺序性upd和操作系统不关心。应用层用户若是关心接收数据的顺序就要采取响应措施如应用层用户对数据报文编号重排序。如果接收缓冲区满了的话再来数据再到达的udp数据就会被丢弃了。 UDP协议本身并没有提供应用层缓冲区。UDP是一种无连接的、不可靠的传输协议它将数据封装成数据包通过网络进行传输不需要建立像TCP那样的连接。 在UDP通信中数据包从发送方直接发送到目的地如果发生丢包或乱序等情况UDP协议本身不提供任何机制来处理这些问题。因此UDP不具备对数据包的重组、重发和流量控制等功能。 UDP的socket既能读也能写UDP报文出的路径和报文进的路径是两条路径互相不干扰所以是全双工。 5. UDP使用注意事项
UDP协议首部是一个16位的最大长度单位Byte也就是说一个UDP能传输的数据最大长度是64K包含UDP首部2^16 个 Byte 8 Byte )。
然而64K在当今的互联网环境下是一个非常小的数字。如果我们需要传输的数据超过64K就需要在应用层手动的分包多次发送并在接收端手动拼装 在应用层没办法发送大数据量。
udp存在的意义
现在的网络环境一般不丢包如果丢包丢掉一些某些场景不影响。因为udp很简单不需要维护复杂连接所以也是需要在各种不同的场景中被采用的。其中最经典的场景就是直播。 观看直播时模糊卡顿掉帧等情况是允许的。 因为观看直播的人太多了每个人都要维护连接服务器扛不住。 如果推送的是udp不用建立连接谁需要就给谁。