当前位置: 首页 > news >正文

计算机网络概要

⽹络相关基础知识

协议

两设备之间使⽤光电信号传输信息数据

要想传递不同信息 那么⼆者ᳵ就需要约定好的数据格式

封装 继承 多态是计算机的性质 它们⽀持了软硬件分层的实现

同层协议可以ᳵ接通信

同层协议ᳵ不直接通信 是各⾃调⽤下层提供的结构能⼒完成通信

分层是解耦的有效⽅式 提⾼了软件的可维护性

⼀段优秀的代码是⾼内聚(class) 低耦合的

OSI(Open System Interconnection) 开放系统互联 七层模型

物理层 数据链路层 ⽹络层 传输层 会话层 表示层 应⽤层

严格来说只实现了2 3 4 7层

因为标准定制者和标准实现者是两码事

TCP/IP协议簇

存在意义 IP地址是⽹络中计某主机唯⼀标识符

计算机F诺伊曼体结构就是⼀个⽹络 只不过是距离问题

TCP/IP是为了给计算机之ᳵ的通信距离问题提供⽅案

通信是⼿段

⽹络和OS之间的关系

即使两台电脑ᳵOS不同 只要⼆者⽹络协议栈相同

它们便可以通信 所以传输层和⽹络层⼀定相同

⽹络层IP和传输层TCP⼀定在OS内核中实现

应⽤层在⽤户层实现 数据᱾路层属于驱动层

所以⽹络是OS的⼀个模块

OS存在⼤协议并以先描述 再组织的⽅式管理 所以协议就是结构体

不同机器需要通信那么协议结构体⽹络代码相同

协议就是双⽅共识的结构化数据类型

TCP/IP五层(四层)模型

TCP/IP是⼀组协议的代名词 它还包含许多协议 组成TCP/IP协议簇

TCP/IP⽤了五层结构 每⼀层都呼叫其下⼀层所组成的⽹络完成其需求

物理层:例如⽹卡 光纤 猫之类 ⽤于和外间1交换光电信号完成数据交互

集线器 ⽤于信号放⼤ 减少物理层数据衰减的影响

数据链路路层:例如交换机 ⽤于局域⽹(短距离)间通信

⽹络层:IP 如路由器 ⽤于短距离⽹络通信

传输层:如传输控制协议TCP ⽤于保证源机将数据传输到⽬标机

应⽤层:如⽂件传输协议 电⼦元件传输 负责程序ᳵ沟通

MAC地址

⽹卡出场⼚时⾃带的⼀串48位的序列号 发送信息是会⾃动带上

其他设备接受到此信号后会⽤⾃⼰的MAC地址与其进⾏⽐较

相同则接收 反之丢弃

MAC地址具有唯⼀性

很多设备都有类似唯⼀值

LAN的碰撞检测和碰撞避免

⼀个主机发送数据后会⼀直不断检测(碰撞检测)

此数据是否会和其他机器发送的数据发⽣碰撞

若发⽣碰撞 则休眠⼀⼩段时ᳵ再发送(碰撞避免)

⼀个以太⽹仅允许⼀段时ᳵ内⼀个主机发送数据 故以太⽹也是公共资源

碰撞检测和碰撞避免也是为了保证以太⽹被使⽤的唯⼀性

故⽽以太⽹也是临界资源 数个主机就是临界区或线程

交换机可以缓解碰撞避免导致的⽹络持续休眠问题

信号⽹络传输基本流程

IP地址

在IP协议中⽤于表示⽹络下的不同主机

IP协议有两个版本 ,分别是IPv4和IPv6,⼀般情况下指IPv4

IP地址是4字节32位整数

这是点分十进制表示方案

IP地址和MAC地址区别

超长距离⽹络传输的本质是 按照指定路径

数据从⼀个局域⽹(⼦⽹)跃迁到下⼀个局域⽹

如此循环最终到达⽬的地

IP地址在⽹络信号传输中扮演⽬的地地址⻆⾊

⽽MAC地址扮演中继局域⽹主机地址⻆⾊

所以MAC地址仅在局域⽹或⼦⽹中有效

IP地址作为⽬的地地址⼏乎不变

主机依托路由器长距离通信简图

以太网

由于⼀开始科学不发达 声⾳传播需要媒介

于是物理学家误以为光传播也需要媒介

因此将传播光的媒介叫做aether

后来科技发展才知道光传播不需要媒介,便抛弃以太的概念

计算机科学中数据远距离传输需要媒介,将此媒介叫做以太

路由器

路由器:⼦⽹ᳵ通信媒介

处于⽹络层,路由器横跨两⽹络

就必须有链接两⽹络的接⼝,和连接两点⼦⽹的驱动程序

路由器可构建⼦⽹ 是⼦⽹出⼝,上⽹主机需要连接路由器

在连接路由器的同时路由器会主机的IP地址和MAC地址记录

主机发现此报⽂不属于⾃⼰便返回给路由器

端⼝号

端⼝号是传输层协议内容 是2字节16位整数

⽤户标识⼀个进程 当前数据要交给哪个进程处理

IP地址+端⼝号可以⽤于标识⽹络上某⼀个主机的某⼀个进程

PID属于进程管理范畴

端⼝号属于⽹络操作进程范畴

使⽤两种类型数据来管理进程是为了解耦

端⼝号范围划分

0-1023:主流端⼝号 HTTP FTS SSH 是⼴为流传的应⽤层协议

它们的端⼝号是固定的

1024-65535:操作系统动态分配的端⼝号 客户端程序的端⼝号

由OS从此范围分配

源端⼝号和⽬的端⼝号

传输层协议(TCP和UDP)的数据段有两个端⼝号 源端⼝号

和⽬的端⼝号

分别描述是谁发的和发给谁的

源IPscrip 源端⼝srcport ⽬的IPdstIP ⽬的端⼝dstprot

四元组便可标识互联⽹唯⼆两个进程

传输层的重要成员TCP和UDP

TCP 传输层协议 有连接 可靠传输 ⾯向字节流(按需收取)

UDP 传输层协议 ⽆连接 不可靠传输 ⾯向数据报(整个收取)

socket

socket分三种 ⽹络socket 本地socket(unix域间socket)

原始socket(和⽹络⼯具有关)

⽹络socket既可以本地通信 也可以远距离⽹络通信

套接字就是⽹络中两个app进通信时各⾃连接通信的端点

struct sockaddr

存在⽬的是为了socket常⽤接⼝参数类型统⼀

先声明⼀个struct sockaddr类型结构体

再强制类型转换成struct sockaddr_in

struct sockaddr_un即可

端口号转大端的函数接口

#include <arpa/inet.h>
字节序转换函数
功能:进⾏⽹络字节序和主机字节序的转换
因此需要使⽤这些函数将将要发送到⽹络中的端⼝号port转换
uint32_t htonl(uint32_t hostlong); 类型是⽆符号32位整数
htonl就是host to network long
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
常⻅IP地址如 192.168.34.45属于字符串⻛格IP地址
点分⼗进制 可读性较好
⽹络通信 char char char char 4字节表示IP地址

IP地址转网络风格接口

in_addr_t inet_addr(const char *cp);对于IPv4:inet_pton,inet_addr对于IPv4和IPv6:inet_pton作⽤:它⽤于将⼀个点分⼗进制格式的 IPv4 地址字符串转换为⼀个32 位的⽆符号整整型(uint32_t)数值也称为⽹络字节序(network byte order) 是⼤端cp:指向⼀个以 null 结尾的字符串该字符串表示⼀个点分⼗进制的IPv4地址返回值:如果函数执⾏成功,它将返回⼀个⽆符号整整数该整数表示输⼊字符串对应的IPv4地址的⽹络字节序如果输⼊字符串不是⼀个合法的IPv4地址,函数将返回INADDR_NONE(通常定义为 -1)

socket相关常⽤API介绍

1. socket()
功能:创建⼀个套接字。
函数原型:SOCKET socket(int domain, int type, int protocol);
参数
domain:指定应⽤程序使⽤的通信协议的协议族 对于TCP/IP协议族 该参数置为AF_INET(IPv4)
type:指定要创建的套接字类型 常⽤的有SOCK_STREAM(流式套接字 对应TCP协议)和SOCK_DGRAM)数据报套接字 对应UDP协议)
protocol:指定套接字使⽤的协议 常⽤的有IPPROTO_TCP(TCP协议)IPPROTO_UDP(UDP协议) ⼀般默认为0即可
返回值:成功时返回新创建的套接字的描述符 所以本质上是创建了⼀个⽂件 失败时返回INVALID_SOCKET
2. bind()
功能:将套接字与特定的IP地址和端⼝号绑定
函数原型:int bind(int sockfd, const struct sockaddr* addr, socklen_t addrlen);
参数
sockfd:套接字描述符 由socket()函数返回
addr:指向包含本地地址(IP+PORT)的套接字地址结构的指针
addrlen:套接字地址结构的⼤⼩ sizeof(addr)
返回值:成功时返回0 失败时返回SOCKET_ERROR
3.recvfrom()
功能:使⽤UDP协议进⾏数据传输时
这个函数主要⽤于从⼀个套接字接收数据,并且能够同时获取发送⽅的地址信息
即收取对象发送的报⽂和地址
函数原型:ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
sockfd:指定要接收数据的套接字描述符
buf:指向⽤于存储接收到的数据的缓冲区
len:指定缓冲区buf的度,即最多能接收多少字节的数据
flags:指定接收数据的选项 通常设置为0 但也可以使⽤⼀些特定的标志来修改接收⾏为(如MSG_PEEK、MSG_WAITALL等)
src_addr:指向⼀个sockaddr结构体 ⽤于存储发送⽅的地址信息 即⽬标主机 如果不需要这个信息 可以设置为NULL
addrlen:是⼀个输⼊/输出参数 在调⽤前 它应该包含src_addr结构体的⼤⼩(通常是sizeof(struct sockaddr_in))
在调⽤后,它会被设置为实际存储在src_addr中的地址信息的⼤⼩。
参数具体含义:从指定的sockfd处以flag(⼀般为0阻塞⽅式)⽅式收取len长度的消息到buf中 成功返回收到的字节数
4.sendto()
功能
函数原型:ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
参数
sockfd:套接字描述符或套接字对象 ⽤于标识要发送数据的⽹络套接字
sockfd既可以向任意⽅发送数据 也可以接受来⾃任意⽅的数据 这种特性叫做---全双⼯
结论 sockfd即可以是接收⽅的套接字 也可以是发送⽅的套接字
buf:指向要发送数据的缓冲区的指针或字节数组
len:要发送的数据的度
flags:发送选项 通常设置为0即可 但也可以设置为其他值以改变发送⾏为,如MSG_DONTWAIT等
dest_addr:指向⽬标地址的指针 通常是⼀个sockaddr结构体 包含IP地址和端⼝号 ⽬标主机和进程
addrlen:⽬标地址的长度 通常为sizeof(struct sockaddr)

5.inet_aton()
功能:将字符串形式的IP地址转换为⼀个32位的⽹络序列(⼆进制)IP地址
函数原型:int inet_aton(const char *string, struct in_addr *addr);
参数
const char *string:这是⼀个指向以空字符结尾的字符串的指针
该字符串表示⼀个点分⼗进制的IPv4地址(如“192.168.1.1”)
struct in_addr *addr:这是⼀个指向in_addr结构的指针 该结构将⽤于存储转换后的32位⽹络序列IP地址
in_addr结构通常包含⼀个名为s_addr的成员 它是⼀个32位⽆符号整数 ⽤于存储IP地址的⼆进制表示
成功返回⼀个string类型的IP地址
struct sockaddr_in ⼀般如何设定
需要对三个成员变量进⾏初始化 分别是协议簇 IP地址与端⼝

服务器视⻆下三次握⼿和TCP常⽤握⼿相关接⼝和SYN ACK等对应

1.listen():开启监听,等待ᬳ接(但不接受ᬳ接)

2.connect():触发 第⼀次握⼿,发送 SYN

3.服务器收到SYN并回复SYN-ACK(第⼆次握⼿)

4.客户端收到SYN-ACK并回复ACK(第三次握⼿)

5.三次握⼿完成后,服务器的accept()取出已建⽴的链接

TCP_socket封装(服务端)

1.蓝图抽象类

2.针对不同平台使⽤的不同代码

3.以生类具体实现

成员变量和构造函数

套接字创建

将已被bind的套接字变为被动套接字

使被动套接字请求与⽤户连接进⾏通信(与⽤户建⽴通信通道)

4.正式开始通信

与⽤户进⾏通信--接受消息接⼝

与⽤户进⾏用信--发送消息接⼝

序列化和反序列化

序列化:将字符串多变⼀的过程(例如将结构体中数据合并为⼀个字符串)

反序列化:将字符串还原成结构体(结构化数据)的过程

序列化的⽬的是⽅便⽹络发送 反序列化是为了⽅便上层处理

协议定制:定制双⽅都能认识,符合通信业务所需的结构化数据,就是struct或class

有关TCP的全双⼯性

UDP发送的报⽂⼀定是完整的 TCP发送报⽂可以不完整

发送数据的本质是将数据拷⻉到缓冲区中

OS中存在⼤量报⽂且⽤先描述后组织的⽅式管理

使⽤链表进⾏组织

JSON实现序列化和反序列化

序列化接⼝

这个序列化步骤⼤致分为三个步骤

1:初始化JSON配置root

2:配置写⼊⾏为

3:将root序列化⼊stringstream

反序列化接⼝

应⽤层HTTP协议

对搜索引擎关键词进行编址

Encode的⽬的是为了避免搜索关Ძ字和URL中的关键字形成冲突进⽽导致URL解析失败

图示代理服务器基本运作方式

状态码

静态数据和交互式数据

静态资源:图⽚ css js 视频等

交互式资源:user上传数据后服务器要对其进⾏处理(例如登录)

PUT 传输⽂件⽅法

DELETE 删除⽂件⽅法

cookie

http基于cookie的会话保持原理

情景:打开B站 此时处于未登录状态 登录 关闭B站

再打开B站 它就保持登录状态

cookie也有内存级和硬盘级

浏览器关闭后要重新登录就是内存级

http是⽆连接 ⽆状态的协议

⽆状态意思是每个HTTP请求独⽴

服务器不记录之前任何请求(每次访问新⽹⻚都要登录)

为了提⾼user体验 所以我们将user相关数据放⼊cookie

PS ⾯向链接!=有链接

Session

如果服务器检测到userのip地址变化异常

服务器会使user的session_id失效

达成冻结账号效果 使hacker⽆法盗取数据

总结:session的主要功能

1 状态管理(有状态) 服务端存储会话数据

2 ⽤户认证 记录登录(记住账号密码)

3 数据持久化 记录会话期ᳵ⽤户数据(收藏)

4 避免重复请求和攻击守护

5 跨⻚⾯传递状态

实现⽅式

客户端 通过cookie存储session ID or URL传递

服务端 通过session ID查找在内存or数据库中会话数据

综上:cookie+session=http会话保持方法

Fiddler

https加密概念简述

加密方式简述

对称加密 什么⽅法加密 对应⽅法解密 常⻅算法AES DES RC4

⾮对称加密 ⼀个公钥 另⼀私钥 公钥加密 私钥解密 算法更复杂

数据摘要&数据指纹 哈希函数对数据运算⽣成固定长度数据摘要

⽤于判断数据有没有被篡改

秒传的原理就是将user的传递⽂件数据摘要进⾏对⽐

有同样的保留⼀份 让这⼀份独⾃上传即可

为了同时保证安全性与效率性 常⽤混合加密⽅式

⾮对称加密⽤于密钥交换(cli和ser)

对称加密⽤于数据传输

中间人攻击原理简述

证书(反中间⼈攻击)

UDP协议

UDP如何做到解包 直接读取UDP报⽂前⼋个字节

UDP是如何做到分⽤ 看哪个进程和16位端⼝号关联

将特定报⽂转给特定进程 进⽽对报⽂进⾏分⽤

UDP添加报头过程
step1:head-=sizeof(struct udphdr)
step2:(struct udphdr*)head->source = 8080;
(struct udphdr*)head->dst = 9090;

UDP⽆法送buffer 只有接收buffer TCP是两者都有

UDP接收到的报⽂未必是发送顺序 但是TCP⼀定是

TCP协议

TCP基本字段

TCP确认应答ACK机制

实际上TCP发送⽅式是⼀次发送N个报⽂

且⼀次返回N个报头确认(有丢包⻛险)

Q 消息太多服务器来不及接收咋办

A 流量控制:服务器(将要)过载减缓cli发送速率直⾄0

Q 发送⽅如何知到对⽅将要过载?

A 16位窗⼝⼤⼩就是接收buffer剩余空ᳵ⼤⼩

传递过来的数据是2000 确认应答序列号是2001

其真正含义是2001及其之前所有的数据都确认收到

什么是连接

⼀个连接⼀定和⼀个⽂件(fd)对应 所以OS对链接 先描述 后组织管理

所以对连接的管理就是增删查改 维护连接需要时间和内存

超时重传 TCP丢包问题

丢包存在两种情况:1 数据未到接收⽅ 2 应答未echo到发送⽅

主机⽆法确认是哪种丢包 只可知到⽆echo

这种情况下只能超时重传 ᳵ隔的时ᳵ较短且不固定

标志位作用

TCP报⽂=报头+有效载荷

标志位⽤于区分不同报⽂类型

ACK(acknowledgment)确认报⽂ 需关注序列号

由于捎带应答 tcp的ACK⼤部分为1

SYN(synchronize)同步标志位 建⽴链接请求

FIN(final) 链接断开标志位

TCP三次握⼿和四次挥⼿

connect是触发三次握⼿ 其本身不直接参与三次握⼿过程

三次握⼿是因为 1.建⽴发接需要双⽅的同意 2验证全双⼯通道通畅性 即⽹络允许

总之需要双⽅和环境的同时许可

第⼀次 客户端发送FIN请求关闭连接

第⼆次 服务器收到FIN后,发ᭆACK确认

第三次 服务器发送FIN请求关闭连接

第四次 客户端收到服务器的FIN后 发送ACK确认

由于TCP的全双⼯性 所以要关闭两个朝上的连接

详解四次挥⼿

int shutdown(int sockfd, int how); 了解 ⽆需会⽤
sockfd:需要关ᳮ的套接字描述符
how:指定关闭的⽅式,表示关闭套接字的哪个部分(发送,接收或两者)
how
SHUT_RD (0):只关ᳮ套接字的接收⽅向(即不再接收数据)
发送数据仍然可以进⾏
SHUT_WR (1):只关闭套接字的发送⽅向(即不再发送数据)
接收数据仍然可以进⾏
SHUT_RDWR (2):关闭套接字的发送和接收⽅向
套接字将完全被关闭
既不能发送也不能接收数据

如果服务器不关闭sockfd 仅完成两次挥⼿

BUG:如果服务器出现⼤量CLOSE_WAIT状态 说明服务器并且真正关闭socket

加上对应的close即可(现象就是服务器很卡)

FIN_WAIT_1:表示主动关闭⽅已经发送了 FIN 包

并等待对⽅的 ACK 确认

此时,主动关闭⽅仍可以接收数据

FIN_WAIT_2:表示主动关闭⽅已经收到对⽅的 ACK 确认

并且处于等待对⽅发送 FIN 包的状态

等待对⽅关闭连接

TIME_WAIT:表示连接的⼀个端点已经完成了连接的关闭

但仍然保持⼀段时间 (这个状态下连接并为真正被关闭)

以确保所有的报⽂都能正确到达并且不会丢失

主动断开闭接⼀端 发送完毕最后⼀次握⼿后

会等待两个MSL(max segment lifetime)时间

BUG:为什么在TCP下第⼀次在客户端连接服务器后再杀进程(关闭连接)

再次ᬳ接服务器会出现“bind error”的错误

A:原因在于端⼝占⽤ 在 TCP 连接关闭时,客户端进⼊ TIME_WAIT 状态,

这个状态会持续⼀段时ᳵ, TIME_WAIT 状态期间,客户端的源端⼝被占

⽤,即使连接已经断开,操作系统也不允许⽴即⽤这个端⼝,因为它需要

确保所有可能的延长报⽂都已经到达并被处理

C:可以等四分或使⽤其他端⼝

也可以使⽤setsockopt减少端⼝被调⽤时间

TCP策略

滑动窗口

窗⼝⼤⼩:TCP 连接中,接收⽅为每个连接设置⼀个接收窗⼝(Receive Window)

表示接收⽅当前可以接收的最⼤字节数。接收⽅会在每个 ACK 包中向发送⽅告它的窗⼝⼤⼩

每个窗⼝最⼤64k

为什么不将滑动窗⼝里的数据达成⼀整块报⽂⽽是分成数个数据段?

数据链路层规定单次发送的数据帧有效载荷长度

(IP报⽂进⼊数据链路层会被封装成数据帧)不可超过mtu长度(⼀般是1500)

由⽹络层⾃⼰分⽚和组装

滑动窗口简图示意

滑动窗⼝数据结构上就是个⼀位数组

滑动窗⼝⼤⼩=接收⽅窗⼝⼤⼩

滑动窗⼝⼯作模式是⼀边向右移⼀边将范围内数据发送,所以流量控制是通过滑动窗⼝实现的

发送buffer可以看成⼀个环形顺序表 不会越界

已发送确认数据区域本质是数据被释放

所以这就是“环形产消模型”

滑动窗⼝丢包问题

1 最左侧丢失

滑动窗⼝不会右移 因为后续数据会阻塞

直到丢包数据被重传并确认

(ps被发出数据不会被⽴即删除

⽽是暂存在滑动窗⼝左侧

收到应答后才可删除)

2 中间丢失 同1

3 最右侧丢包 同1

确认数据报定义是之前所有数据都收到

哪里开始丢失就在哪里停滞然后重传

超重传

快速传的⼯作原理

丢包检测:当 TCP 发送⽅发送的数据包到达接收⽅时

接收⽅会对每个正确接收的数据包发送⼀个确认(ACK)

如果接收⽅发现⼀个数据包丢失,它会继续重复确认最后⼀个成功接收的数据包

这些重复的 ACK 就是快速传机制的信号

重复 ACK:当发送⽅收到多个重复的 ACK 时(通常是三个重复的 ACK)

就意味着某个数据包丢失了

此时,发送⽅不需要等待超时,⽽是⽴即认为丢失的数据包需要重传

触发重传:在收到三个重复 ACK 后,发送⽅会⽴即重传丢失的数据包

⽽不是继续等待重传超时

PSH标志位:PUSH=1 请尽快将你的buffer数据交给上层

RST标志位:三次握⼿建⽴链接异常时 双⽅皆可reset(ᬳ接重置)

URG标志位:值为1时处理紧急数据

例如:

1 发送⽅发送的数据包 1, 2, 3, 4, 5;

接收⽅收到 1, 2, ,4, 5(假设包 3 丢失)

2 接收⽅会重复发ᭆ ACK 3 次

3 确认数据包 2(即重复 ACK)

4 发送⽅收到三个重复的 ACK 后

⽴即重传丢失的包 3

⽹路拥塞

⽹路拥塞⼤量数据丢包会发⽣⽹络拥塞ᳯ题

解决ᳯ题不是重传 ⽽是慢启动

先发送少量数据测试当前⽹络压⼒

如果每次都会得到对⽅的ACK 则多次加倍发送数据

这是⼀个指数算法

拥塞窗口

为了衡量接收主机接收能⼒问题 使⽤滑动窗⼝解决

为了衡量传输数据能⼒ᳯ题 可以使⽤拥塞窗⼝

每次发送数据包 将拥塞窗⼝和接受端主机反馈窗⼝进⾏⽐较 取⼩的

拥塞窗⼝增加已开始是指数 到达⼀定阈值(慢启动阈值)后呈线形增加

拥塞控制算法:慢启动+加法增⼤+乘法减少

拥塞窗⼝本质是对⽹络健康拥堵状态的评估

延时应答

⼯作原理:

TCP协议在收到数据段时

通常会⽴即发送⼀个ACK报⽂来确认收到数据

但是在某些情况下,TCP可以延迟这个确认

(每收到固定数量的报⽂就应答⼀次)

以便在⼀定时间内合并多个确认应答

减少⽹络上的ACK报⽂数量

不同层下协议及数据单位

⽹络层结构浅析

路径选择

⽬标决定路径

凭借什么交给下⼀个route(⽹络层IP问题)

根据⽬的IP和⾃身路由表&从⽽确定⽹络号

然后不停在⼦⽹间转发直⾄到公⽹

为何将数据交给路由器F(局域⽹通信问题)

⽬的IP地址=⽬标⽹络+⽬标主机

TCP和IP的关系

IP核⼼作⽤是将数据报跨⽹络传输给⽬标主机

如果丢包不需要关⼼ 由TCP协议的超时重传机制解决

所以滑动窗⼝ 超时重传 拥塞窗⼝ ⽹络拥塞都是TCP的策略

IP报头简述

IP=⽬标(⼦)⽹络地址+主机地址

⼦⽹

路由器拥有构建⼦⽹能⼒

⼀个IP地址 被转发:

1 根据⽬标⽹络 转发报⽂到⽬标(内)⽹络

2 转发到⽬标⽹络后 再在内⽹进⾏转发

⼦⽹划分

⼦⽹划分就是调整⼦⽹掩码,把⼀个⼤⽹络分成多个⼩⽹络

⼦⽹掩码越长(如 /26, /27),⼦⽹数量越多,但每个⼦⽹可⽤主机越少

合理划分⼦⽹可以提⾼⽹络性能,管理效率和安全性

为什么要划分⼦⽹?

提⾼⽹络性能:减少⼴播域,降低⽹络拥塞

增强安全性:不同⼦⽹可以隔离,提⾼安全管理能⼒

优化IP地址使⽤:避免IP浪费,提⾼IP地址利⽤率

⽅便管理

如何进⾏⼦⽹划分

IP地址 = ⽹络号 + 主机号

⽹络号:确定IP地址属于哪个⽹路(⼦⽹地址)

主机号:区分具体设备

⼦⽹IP是⽤⼀个IP地址块(A/B/C类⽹络)划分出来的

⼦⽹掩码

⼦⽹掩码作⽤于区分IP地址中⽹络号(⼦⽹)和主机号的⼀个32位数
⼦⽹掩码的1表示⽹络号 0表示主机号
⼦⽹掩码的格式
A类默认⼦⽹掩码:255.0.0.0
(11111111.00000000.00000000.00000000)
B类默认⼦⽹掩码:255.255.0.0
(11111111.11111111.00000000.00000000)
C类默认⼦⽹掩码:255.255.255.0
(11111111.11111111.11111111.00000000)
⼦⽹掩码的作⽤
⽤于区分⽹络号和主机号
计算公式: IP地址^⼦⽹掩码=⽹络号

⼦⽹掩码计算示例

设备A:192.168.1.10

设备B:192.168.1.20

⼦⽹掩码:255.255.255.0

⽹络号计算:

A 的⽹络号:192.168.1.0

B 的⽹络号:192.168.1.0

相同,A和B在同⼀⼦⽹

可直接通信

如果设备C的 IP 是 192.168.2.5

C 的⽹络号:192.168.2.0

不同⽹络,必须通过路由器通信

⼦⽹掩码决定了此⼦⽹⼤⼩(多少个IP可⽤于主机)

(⼦⽹)

IP地址=⽹络号(⽬标⼦⽹)+主机号(⽬标主机)

⼦⽹掩码⽤来区分⽹络号和主机号的界限

网段划分具体运算概述

⼦⽹划分的主要步骤就是使⽤⼦⽹掩码和 IP 地址进⾏计算

1.确定原始 IP 地址和⼦⽹掩码

先确定要划分的 ⽹络地址 和 默认⼦⽹掩码。

例如:

IP地址:192.168.1.0/24

(其中/24表示前24位是⽹络号,后8位是主机号 24+8=32)

默认⼦⽹掩码:255.255.255.0(/24)

2.确定要划分的⼦⽹数量

如果要划分成 N 个⼦⽹,需要借⽤主机位来创建更多的⽹络号

计算需要的额外⽹络位数:(N:需要的⼦⽹数)

计算 2^X = N,求出X值(X 是额外增加的⼦⽹位数)

新的⼦⽹掩码就是 原⼦⽹掩码 + X。

3.计算新的⼦⽹掩码

默认/24(255.255.255.0)的主机位是8位,如果要划分4个⼦⽹2^3 = 8(所以借⽤ 3 位主机位)

新的⼦⽹掩码变为 /27(255.255.255.192)

旧的默认⼦⽹掩码

11111111.11111111.11111111.00000000

( 255 . 255 . 255 . 0 )

现有新的⼦⽹掩码

11111111.11111111.11111111.11100000

( 255 . 255 . 255 . 224 )

转换成⼗进制:255.255.255.224

4.计算每个⼦⽹的 IP 范围

⼦⽹的增ᰁ(步长):256 - ⼦⽹掩码的最后⼀᮱分

256 - 192 = 64

私有IP和公⽹IP

WAN和LAN

运营商

基本⽹络状况

1:普通路由器不会存储所有公⽹IP的路径

只存"如何到达下⼀跳"的信息

2:家庭/公司路由器只存本地⽹络和默认路由

它们根本不知到具体的公⽹服务器IP地址如何到达

3:ISP和⻣⼲⽹路由器存储全球BGP路由表

但它们存的是⼤块IP前缀的路由信息

⽽不会存单个主机的路径

4:IP数据包的转发是逐跳(Hop-by-Hop)进⾏的

每个路由器只负责找到下⼀跳,⽽不是提前计算整个路径

1.互联⽹的路径是预先规划好的吗?

不是完全规划好的,⽽是动态学习的!

2.路由器是如何知道其"下⼀跳"是有效的

(1).路由器主要通过路由协议来学习和维护可达的路径

这些协议可以分为内联⽹关协议(IGP)和外部⽹关协议(EGP)

常⻅协议有:

RIP(路由信息协议):⽼旧,基于"跳数"选择路径

OSPF(开放最短路径优先):基于Dijkstra算法,计算最优路径

IS-IS(中ᳵ系统-中ᳵ系统):ISP内部⼴泛使⽤

(2).如何⼯作

邻居发现:路由器会定期向周围的路由器发送Hello消息,确保对⽅在线(爬⾍)

路径计算:每个路由器会计算从⾃⼰到所有⽬标的最佳路径

动态更新:如果某条路径故障,路由表会⾃动更新

公⽹(全球⽹络)

本质就是对全球IP进⾏划分的过程

⽹络通信必须经过带有公⽹ip的服务器

这就是为什么我们需要qq微信

登录同⼀台公⽹IP服务器

ps:申请公⽹IP以组织为单位(如落云宗公⽹IP)

由IANA统⼀进⾏分部 管理

如果路由表中没有⽬标怎么办

缺省路由(Default Route)是⽹络路由中的⼀种特殊路由

⽤于在路由表中找不到匹选项时提供默认的去向

它们常⽤于处理⾮本地或未知⽬的地址的流量

指向⼀个默认的下⼀跳⽹关

数据链路层和以太⽹协议

数据链路层作用

数据᱾路层解决相邻主机直接通信问题

「⽹络层」和「数据链路层」间关系

就是唐僧和⽩⻰⻢

以太⽹

不是具体⽹络 ⽽是⼀种技术标准

是⼀种软硬件结合的协议

以太⽹的⽹线必须是双绞线

它是当前最⼴泛使⽤的局域⽹技术协议

以太⽹帧格式

1.Preamble(前导码)和SFD(起始定界符)在以太⽹帧的最前⾯,主要⽤于同步和标识帧的开始

Preamble使⽤0xAA字节来标记数据流的开始,SFD字段标识帧的开始(固定值 0xAB)

2.Destination MAC Address和Source MAC Address

⽤于标识⽹络中接收⽅和发送⽅的硬件地址(MAC地址)

每个MAC地址是⼀个48位(6 字节)地址

3.Type/Length字段表示数据的类型或长度,常⻅的类型值有:

0x0800:IPv4

0x0806:ARP

0x86DD:IPv6

0x8847:MPLS

...⽤于确定将报⽂传递给上层哪个协议

4.Data 字段是实际承载的数据,长度可以变化,通常包含上层协议数据(如IP数据包)

5.FCS(帧校验序列)是⼀个4字节的CRC校验码,⽤于检查数据传输中的错误

MAC地址:mac地址是当前地址或下⼀跳地址

作⽤:位于⽹卡层⽤于识别数据᱾路层中相ᬳ的节点 仅可⽤于局域⽹通信

MTU对UDP影响

MTU对UDP影响设MTU=20

⼀旦UDP携带的数据超过1472(1500-20(IP⾸᮱)-8(UDP⾸部)),那么⽹络层会分成多个IP数据报

但此IP数据报有任意⼀个丢失,那会引起⽹络层重组失败,所以UDP的数据报分⽚使重传的概率增⼤

MTU对TCP影响

TCP数据报⼤⼩受制于MTU TCP单个数据报最⼤消息长度,成为MSS(Max Segment Size)

TCP建⽴时,送信双⽅会进⾏MSS协商

双⽅发送SYN时会进⾏协商在TCP头部写⼊⽀持的MSS值

得知双⽅的MSS后,会取较⼩的MSS位最终值

IP地址和MAC地址的区别和联系

由于⽹络是临界资源 所以任何时刻仅容许⼀台主机发送的信号

涉及和别的主机发⽣碰撞 那么碰撞的主机会进⾏休眠 让数据链路层重发

整个局域⽹ 我们可称其为碰撞域 所以⼀个碰撞域中主机越少越好

单主机发送数据帧应尽量短[45,1500]

如何骇⼀个局域⽹?不断向局域⽹发送垃圾数据,⽆条件触发碰撞

映射关系:

局域⽹中,IP地址通过ARP(地址解析协议)映射到MAC地址

设备需要知到⽬标MAC地址才能正确发送数据包

传输过程:

发送端根据⽬标IP查找⽬标MAC(ARP请求)

数据包在局域⽹内根据MAC地址传输

如果数据包要跨⽹传输,会经过路由器,路由器使⽤IP地址决定下⼀跳

但每⼀跳的MAC地址那可能改变

收到的报⽂会在数据链路层进行MAC地址核实 如果不是就直接丢弃

如何缓解碰撞问题?交换机划分交换域

ABD组成⼀个碰撞域,CE组成⼀个碰撞域

如果A要发送数据给D,数据会先交给交换机

交换机发现AD在⼀个碰撞域,就将数据转发给主机D

这样就避免了和CD所形成的碰撞域发⽣碰撞

ARP协议(地址解析协议)

数据报发送主要依靠IP路由

但实际转发依赖于⽹卡层MAC地址

先看op 是请求还是应答

ARP 过程

发送ARP请求(ARP Request):

发送⽅(主机A)想要知道⽬标IP地址(主机B)的MAC地址

发送⽅会构成⼀个ARP请求数据包

并使⽤⼴播(MAC地址FF:FF:FF:FF:FF:FF)在局域⽹内发送该数据包

接收并响应ARP 请求(ARP Reply):

⽬标设备(主机B)收到ARP请求后,检查其中的⽬标IP地址是否与⾃⼰的IP地址匹配

如果匹配,主机B构成⼀个ARP应答包(ARP Reply)

其中包含⾃⼰的MAC地址,并以单播(unicast)⽅式发送回给主机A

缓存 ARP 信息并送信:

发送⽅(主机A)收到ARP应答后,会将⽬标的MAC地址缓存到⾃⼰ARP表中

以便后续送信时⽆需再次发送ARP请求

NAPT转换表

内网穿透

内⽹穿透(NAT穿透)是⼀种技术,⽤于突破 NAT(⽹络地址转换)或放⽕墙的机制

使得位于私有⽹络(内⽹)中的设备能够直接与外部⽹络进⾏通信

由于⼤多数家庭或企业⽹络都使⽤路由器进⾏ NAT,这会导致外⽹⽆法直接访问内⽹设备

内⽹穿透技术通过各种⽅式解决了这个ᳯ题,常⻅的应⽤场景包括远程访问,视频监控,即时通讯等

内⽹打洞

1 上传各⾃IP到云服务器

2 交换各⾃路由器IP

3 仅通过各⾃路由器进⾏通信 完成内⽹打洞

P2P模式概述 Peer-to-Peer

如果甲要在某视频⽹站下载电影A

且⼄正好在看此电影

⽹络打洞会将甲⼄的路由器连接形成通道

使⼄看电影的同时也将数据推送给甲下载

此时⼄即是客户端 也是服务器

代理服务器

NAT和代理服务器区别和联系

NAT位于路由器中 属于⽹络层

代理服务器属于应⽤层

代理服务器通过充当客户端和⽬标服务器之间的中介

提供多种功能,包括匿名访问,内容过滤,缓存加速,安全性增强等

相当于⼀个⽤于路由器和主机之间传递数据的中间⼈

可以对资源进⾏缓存 优化上⽹体验

客户端发出请求会互联⽹会将此请求给反向代理

反向代理再分配给服务器

防⽕墙突破—欺骗运营商路由器

由于威权管控愈加严格

运营商路由器发现异常报⽂会直接丢弃

所以开发商会买复数台代理服务器

打开clash,会有HongKong代理1,新加坡代理2…

⼀台被封死换另⼀台,针对防⽕墙GFW,IP封锁

提供更多流量⼊⼝,增加访问成功率

DNS

Domain Name System

域名会被DNS转换成IP地址

com:⼀级域名,表示机构性质

baidu:⼆级域名,表示具体机构

根域名服务器(Root Name Servers)是 DNS(域名系统)的核⼼组成部分

负责将域名解析为IP地址的最顶层的服务器

它们在全球范围内提供域名解析服务

确保整个互联⽹的域名解析体系能够正常运作

ICMP

ICMP是⽹络层协议

会通知出错原因

⽤于在⽹络设备(如路由器主机)之间传递控制信息

帮助诊断和管理 IP ⽹络的通信状况

它主要⽤于报告⽹络错误,测试联通性和提供调试信息

ping ww.baidu.com 测试是否能进⼊此⽹址 若不能 返回错误

IO的简介和阻塞⽅式的介绍以及对IO阻塞⽅式的控制⽅法介绍

I/O操作中,通常可以分解为两个主要阶段:

I/O 操作的时ᳵ = 等待数据的时ᳵ + 复制数据的时间

等待数据 (Wait)

例如,读取⽂件时,操作系统需要从磁盘加载数据到内核缓冲区,这个过程可能涉及等待(例如磁盘I/O,⽹络I/O)

这个ᴤ段可能会导致线程阻塞,特别是在同步I/O模型下

拷⻉数据 (Copy)

数据从内核缓冲区复制到⽤户态缓冲区(例如 read()系统调⽤)

这个数据拷⻉过程也需要时间,尤其是在⼤量数据传输时会影响性能。

其中,等待时间占主要⽐重,

⾼效IO就是单位时间内⼤⼤减少等待时间

建⽴链接后进程需要⼀直阻塞等待

等待<--->不等待 有条件变化

1阻塞和⾮阻塞

1.1阻塞是⽆论buffer有⽆数据都会等待

1.2⾮阻塞是buffer⽆数据就⽴即返回,有数据才拷⻉

#include <fcntl.h>

int fcntl(int fd, int cmd, ... /* 可变参数 */);

⽂件描述符控制函数,可以修改I/O⾏为,设置⽂件锁,管理进程信号...

 fd:要操作的⽂件描述符

 cmd:控制命令,决定 fcntl 执⾏什么操作

 F_GETFL:获取 fd 的⽂件状态标志(如 O_NONBLOCK)

 F_SETFL:设置 fd 的⽂件状态标志

 ...:根据cmd可能需要提供额外的参数

2信号驱使

通过信号(signal)来通知进程I/O事件的发⽣,⽐如某个⽂件描述符(socket⽂件等)变得可读或可写

3多路转接/复⽤

⼀个监测者同时监测多个IO进程,谁有数据就拷⻉谁

4异步I/O

异步I/O的核⼼就是先让进程先提交I/O请求,OS负责执⾏I/O操作,进程则继续执⾏其他任务,不会被I/O阻塞

当 I/O完成后,OS会通知进程,进程再回来处理数据

异步IO效率最⾼,但也是最受ᴴ于平台的

同步I/O vs 异步I/O

 同步I/O:进程在发起I/O请求后,必须等待I/O完成后才能继续执⾏后续操作

 异步I/O:进程在发起I/O请求后,⽴即返回并继续执⾏其他任务,I/O由OS负责处理,完成后通知进程

控制IO⾏为

阻塞和⾮阻塞

#include <fcntl.h>

int fcntl(int fd, int cmd, ... /* 可变参数 */);

⽂件描述符控制函数,可以修改I/O⾏为,设置⽂件锁,管理进程信号...

 fd:要操作的⽂件描述符

 cmd:控制命令,决定 fcntl 执⾏什么操作

 F_GETFL:获取 fd 的⽂件状态标志(如 O_NONBLOCK)

 F_SETFL:设置 fd 的⽂件状态标志

 ...:根据cmd可能需要提供额外的参数

select系统调用

#include <sys/select.h>

#include <sys/time.h>

int select(int nfds, fd_set *readfds,fd_set *writefds, fd_set *exceptfds,struct timeval *timeout);

作⽤:允许进程同时监听多个⽂件描述符(如socket,pipe,⽂件)

并在其中任意⼀个变为可读/可写时返回,从⽽避免阻塞等待单个I/O事件

fe_set:是使⽤bitmap实现的集合数据类型,OS给⽤户提供的数据类型,可以添加多个⽂件描述符

 其每⼀个fd对应⼀个⼆进制位

使⽤位图这⼀数据结构来保存0,1,2,3...,向select传递这些数据

nfds:输⼊输出型参数,⽂件描述符的最⼤值 +1(即max_fd+1)

 输⼊时:⽤户告诉内核,哪些fd被设置成可读

 ⽐特位位置:fd具体编号

 ⽐特位内容:是否关⼼

 输出时:内核通知⽤户,在⽤户关⼼的readfds中,谁已就绪

 fd :0123 4567

 状态:0000 0010:fd=7的读事件已就绪

 总结,在admin要关⼼的fd中,fd=max{fd},且nfds=max{fd}+1

readfds:这是⼀个指针,监听可读事件的fd_set指指针(若不关⼼填NULL)->buffer是否有数据

writefds:监听可写事件的fd_set 指针(若不关⼼填 NULL)->buffer是否有space

 ⽐特位位置:fd具体编号

 ⽐特位内容:是否就绪 对已就绪的fd进⾏IO读取 读取⼀次⼀定不会被阻塞

exceptfds:监听异常事件的fd_set 指针(通常⽤于OOB数据(带外数据))⼀般填 NULL->fd是否正确

这三个参数意义是将指定fd设置进⼊某个集合

timeout:

 NULL:阻塞等待(直到某个 fd 发⽣事件)。

 {0, 0}:⽴即返回(⾮阻塞模式)。

 {sec, usec}:等待指定时间,超时后返回。

就绪:

 读就绪:底层有数据

 写就绪:底层有空间

select的优缺点

 每次调⽤select之前都要进⾏参数重置,接⼝使⽤不⽅便

 每次调⽤select都要在内核遍历所有的fd,开销较⼤

 ⽀持的fd数量较少

返回值

 > 0:有I/O事件发⽣,返回就绪的fd数量

 = 0:超时,⽆事件发⽣

 -1:出错,errno记录错误原因

注意:每次调⽤select之前,我们都需要将位图重新设置

因为我们给了select⼀张位图之后它会将位图进⾏更改给我们⼀张全新的位图

也正因如此,我们也需要⼀个辅助数组将历史的所有⽂件描述(fd)保存起来

说⽩了select就是使⽤位图readfds来表示哪些fd上的哪些数据已经就绪

ps:常辅助select函数⼀起使⽤的接⼝

FD_ZERO(&fd_set):清空⽂件描述符集合fd_set,即将集合中的所有位设置为0

FD_SET(fd, &fd_set):将⽂件描述符fd加⼊到fd_set集合中,表示该⽂件描述符在select函数检查时应该被关注

FD_CLR(fd, &fd_set):从fd_set集合中移除⽂件描述符fd,即表示该⽂件描述符不再被select关注

FD_ISSET(fd, &fd_set):检查⽂件描述符 fd 是否在 fd_set 集合中

位图bitmap简介

位图的核⼼思想是使⽤**位数组(bit array)**来表示数据,每⼀位(bit)只有两种状态:

0:通常表示"不存在"或"关闭"

1:通常表示"存在"或"开启"

所以,具体关⼼两个⽅⾯,1:⽐特位位置表示(⽂件描述符)fd具体编号 2:⽐特位内容表示是否关⼼

例如,假设要存储0~15这16个整数,并且只存储其中的{1, 3, 4, 8, 12, 15}:

索引: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

位图: 0 1 0 1 1 0 0 0 1 0 0 0 1 0 0 1

// 位图结构体
typedef struct {unsigned char *bits; // 存储位的数组size_t size; // 位的总数
} Bitmap;
为什么使⽤结构体对数组封装?为了防⽌数组传参可能发⽣的降维问题

fd_set

代码⼤致如下
typedef struct {unsigned long fds_bits[__FD_SETSIZE / (8 * sizeof(long))];
} fd_set;

fd_set:就是⼀个struct+数组的位图

fd_set:就是⼀个具体数据类型,其⼤⼩固定,表示其可包含的fd个数有上ᴴ(可管理⽂件描述符(fd)为1024个)

fd_set 是 select() 的⽂件描述符集合,主要⽤于监视多个⽂件描述符的状态(可读,可写,异常)

需要配合 FD_ZERO、FD_SET、FD_CLR、FD_ISSET 进⾏操作。

受 FD_SETSIZE ᴴ制,不ᭇ合⾼并发场景,᭗常在现代开发中被 poll() 和 epoll() 取代。

所以说select可管理的fd有上ᴴ

得出结论--->poll,epoll

 --->上限是多少

epoll多路转接简介与常⽤接⼝

poll⽤于检查多个⽂件描述符(通常是⽤于 I/O 操作的)是否就绪

是否可以执⾏某些操作(如读,写,异常处理等)它᭗常在事件驱动的程序设计中使⽤

尤其是在需要处理多个I/O流(如⽹络ᬳ接)的情况下

所以说poll就是"select+"

poll是为了select存在的fatalᳯ题

 1.输⼊输出参数是⼀个bitmap,导致参数每次都需要重置

 2.等待的fd个数有上ᴴ

所以poll可以做到将输⼊输出参数进⾏分离同时其可等待的fd没有上ᴴ

#include <poll.h>

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

fds:指向⼀个 pollfd 结构体数组的指ᰒ.每个pollfd结构体表示⼀个待监控的⽂件描述符及其相关事件

 struct pollfd {int fd; // ⽂件描述符short events; // 表示此fd是否就绪的标记short revents; // 发⽣的事件类型};

 events:指定感兴趣的事件类型,可以是以下之⼀或多个的组合(按位或):

 (ps:这些事件都是宏,short类型可以⽤来表示bitmap)

 POLLIN:⽂件描述符可读(数据可⽤)//#define POLLIN

0x001

 POLLOUT:⽂件描述符可写(可以写⼊数据)

 POLLERR:⽂件描述符发⽣Კ误

 POLLHUP:⽂件描述符被挂起

 POLLNVAL:⽂件描述符⽆效

 events:表示期望的⽂件描述符功能或状态(如⽂件描述符是否可读,可写等)

 它是你对⽂件描述符的"需求"

 revents:返回的事件类型,表示实际发⽣的事件.这个字段会由poll()填充

 综上所述

 revents:表示⽂件描述符是否就绪,也就是实ᴬ发⽣的事件类型

 它反映了⽂件描述符的当前状态,即是否满⾜你在events中设置的条件(如是否可读,是否可写等)

nfds:fds 数组中的元素个数,也就是需要监控的⽂件描述符数量

timeout:等待事件发⽣的时间,单位为毫秒.timeout 的值可以有三种情况:

 正数:表示等待的最⼤时间(ms),如果在此时ᳵ内没有事件发⽣,则返回

 0:表示⾮阻塞模式,即⽴即返回,检查是否有事件

 -1:表示阻塞模式,poll()将会⼀直等待直到有事件发⽣或被信号中断

返回值:

 n>0:有n个fd就绪

 n=0:timeout

 n<0:error

EpollServer常⻅接⼝简介

epoll和poll select⼀样,都是就绪事件通知机制

int epoll_create(int size);

功能:创建⼀个epoll模型

size:已废弃,但是必须>0

成功返回值:fd

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

功能:向epoll中添加要关⼼的事件,admin告诉内核想要关⼼的fd的事件

作⽤说明:向指定的epoll模型epfd(epoll_create返回值)中"增删改(op)"指定fd上的指定事件event

epfd:通过epoll_create或epoll_create1 创建的epoll⽂件描述符

op:操作类型,以下是常⽤的操作:

 EPOLL_CTL_ADD:将⽂件描述符fd加⼊到epoll实例中进⾏监听

 EPOLL_CTL_MOD:修改已经添加的⽂件描述符fd的监听事件

 EPOLL_CTL_DEL:从epoll实例中删除⽂件描述符fd

fd:需要添加,修改或删除的⽂件描述符

event:描述⽂件描述符的事件类型,struct epoll_event 类型,定义如下:

输⼊输出型参数 

struct epoll_event {__uint32_t events; // 表示输⼊输出时代表的事件epoll_data_t data; // 关联的数据(᭗常是⽂件描述符)};

 events=:宏(marco)

 EPOLLIN:有数据可读

 EPOLLOUT:可以写数据

 EPOLLERR:发⽣错误

 EPOLLHUP:挂起状态

 EPOLLRDHUP:远程挂起(即远程关链接)

 EPOLLET:边缘触发模式(Edge-Triggered)在此模式下,事件只会在⽂件描述符的状态发⽣变化时通知⼀次

 typedef union epoll_data {void *ptr; // ⽤户⾃定义的指ᰒint fd; // ⽂件描述符uint32_t u32; // ⽆符号 32 位整数uint64_t u64; // ⽆符号 64 位整数} epoll_data_t;

※MAIN POINT:事件中,admin应重点关注的是

epoll_event.events(事件类型)

epoll_data_t.fd(⽂件描述符)

综上:_epfd是epoll_create的返回值,这个函数需要重点关注的是struct epoll_event *event

返回值:成功返回0,失败-1

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

功能:⽤于等待事件的发⽣,并返回已就绪的⽂件描述符

作⽤说明:

epfd:由epoll_create或epoll_create1创建的epoll实例的⽂件描述符

events:输出型参数,告诉admin所关⼼的fd上哪些事件已就绪

maxevents:events数组的最⼤容量,epoll_wait最多返回maxevents个事件

timeout:等待时间

相关文章:

  • 牛客网NC276055:三根木棒能否组成三角形问题详解(ACM中的A题)
  • 【从基础到模型网络】深度学习-语义分割-ROI
  • OceanBase数据库-租户
  • 小米汽车:新能源赛道的破局者与变革者
  • UE5无法编译问题解决
  • 抖音视频下载工具 v1.1 自用分享
  • 【Python 算法零基础 4.排序 ① 选择排序】
  • 为何选择Python:全面解析其优势与发展前景
  • Linux下载国外软件镜像的加速方法(以下载Python-3.8.0.tgz为例)
  • Java可变参数与Collections工具类详解
  • 系统架构设计师考前冲刺笔记-第1章-系统工程与信息系统基础
  • 深入解析Java事件监听机制与应用
  • GOP模式调节画面质量讲解
  • 【ROS2】 核心概念6——通信接口语法(Interfaces)
  • 【QGIS二次开发】地图编辑-07
  • LWIP的NETCONN接口
  • 生产级编排AI工作流套件:Flyte全面使用指南 — Data input/output
  • 【常用算法:查找篇】9.AVL树深度解析:动态平衡二叉树的原理、实现与应用
  • USB传输速率 和 RS-232/RS-485串口协议速率 的倍数关系
  • 备忘录模式
  • 三人在共享单车上印小广告被拘,北京警方专项打击非法小广告
  • 无人机企业从科技园区搬到乡村后,村子里变得不一样了
  • 家庭医生可提前5天预约三甲医院号源,上海常住人口签约率达45%,
  • 浙江理工大学传播系原系主任刘曦逝世,年仅44岁
  • 解放日报:“感觉全世界人都在上海买买买”
  • 魔都眼|邮轮港国际帆船赛启动,120名中外选手展开角逐