【Linux】网络基础概念

张开发
2026/4/20 2:57:23 15 分钟阅读

分享文章

【Linux】网络基础概念
1. 网络基础总结来说计算机不能独立使用必须进行协作注定了计算机之间要进行连接通信就产生了网络网络是局部产生的是从局部到整体的网络互联 ---- 局域网 ---- 广域网 ---- 更大的网2. 初识协议计算机之间的传输媒介是光信号和电信号达成数据格式协议就可以减少通信成本一般具有定制协议或者标准的资格的组织或者公司都必须是业界公认的组织或公司比如ISO国际标准化组织ISO是由多个国家的标准化团体组成的国际组织它在开放系统互连 OSI模型方面尤为著名。OSI模型定义了网络通信的七层协议结构尽管在实际应用中TCP/IP协议族更为普遍但OSI模型仍然在学术和理论研究中占有重要地位2.1 协议分层协议本质也是软件在设计上为了更好的进行模块化解耦合分层之后可以替换掉任意一层2.2 OSI七层模型在网络角度OSI定的协议7层模型其实非常完善但是在实际操作的过程中会话层、表示层是不可能接入到操作系统中的所以在工程实践中最终落地的是5层协议2.3 TCP/IP五层(或四层)模型TCP/IP是一组协议的代名词它还包括许多协议组成了TCP/IP协议簇TCP/IP通讯协议采用了5层的层级结构物理层传光电信号用网线、光纤、电磁波决定传输速度与距离集线器工作在此层。数据链路层在设备间传数据帧做差错校验、冲突检测交换机工作在此层。网络层负责 IP 寻址与路由选择规划数据传输路径路由器工作在此层。传输层实现端到端可靠传输代表协议 TCP/UDP。应用层面向具体应用服务如 FTP、SMTP 等网络编程主要针对这一层物理层考虑的比较少只考虑软件相关的内容。因此很多时候直接称为 TCP/IP四层模型.一般而言对于一台主机它的操作系统内核实现了从传输层到物理层的内容对于一台路由器它实现了从网络层到物理层对于一台交换机它实现了从数据链路层到物理层对于集线器它只实现了物理层但是并不绝对很多交换机也实现了网络层的转发很多路由器也实现了部分传输层的内容(⽐如端口转发3. 再识协议3.1 为什么要有协议本机通信 VS 网络通信区别就是通信距离变长了通信距离变长会带来一系列问题处理数据数据丢失定位目标主机下一跳问题上述问题就需要分层处理注定了层状结构3.2 什么是TCP/IP协议TCP/IP协议的本质是一种解决方案TCP/IP协议能分层前提是因为问题们本身能分层3.3 TCP/IP协议与操作系统的关系3.4 协议本质是什么如上图即使os不一样主机b还是可以识别传来的数据并提取为什么因为双方都有同样的结构体类型因为用同样的代码实现协议就用了同样的数据类型这就是一种协议/约定所谓协议就是通信双方都认识的结构化的数据类型因为协议栈是分层的所以每层都有双方都有协议同层之间互相可以认识对方的协议4. 网络传输基本流程4.1 局域网络传输流程图1局域网通信原理(以太网为例)当两台主机在一个局域网就可以直接通信每台主机在局域网上要有唯一的标识来保证主机的唯一性mac地址2认识MAC地址MAC地址用来识别数据链路层中相连的节点长度为 48比特位即 6 个字节。一般用16 进制数字加上冒号的形式来表示(例如 08:00:27:03:fb:19)在网卡出厂时就确定了不能修改。mac地址通常是唯一的虚拟机中的mac地址不是真实的mac地址可能会冲突.windowsipconfig /all局域网通信的过程中主机对收到的报文确认是否是发给自己的是通过目标mac地址判定可以试着从系统角度来理解局域网通信原理以下是同一个网段内的两台主机进行发送消息的过程所以进行上述传输流程的时候要进行封装和解包报头部分就是对应协议层的结构体字段一般叫做报头除了报头剩下的叫做有效载荷故报文 报头 有效载荷不同的协议层对数据包有不同的称谓在传输层叫做段(segment) ,在网络层叫做数据报(datagram)在链路层叫做帧(frame)应用层数据通过协议栈发到网络上时每层协议都要加上一个数据首部(header),称为封装首部信息中包含了一些类似于首部有多长载荷(payload)有多长上层协议是什么等信息数据封装成帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部根据首部中的上层 协议字段将数据交给对应的上层协议处理每层都有协议总结在网络传输的过程中数据不是直接发送给对方主机的而是先要自定向下将数据交付给下层协议 最后由底层发送然后由对方主机的底层来进行接受在自底向上进行向上交付从而实现看似是用户层的通信3数据包封装和分用所以学习协议就是学习如何做到解包封包以及如何将有效载荷交给上层4认识IP地址IP 协议分IPv4、IPv6IP 地址用于唯一标识网络中的主机日常采用点分十进制书写四段数字各占 1 字节例如192.168.0.1取值 0~255目的IP的意义然后结合封装与解包体现路由器解包和重新封装的特点对比IP地址和Mac地址的区别IP 地址传输全程保持不变MAC 地址每经过一跳路由转发不断变化目的 IP全局层面代表最终长远目标用于跨网段路由选路MAC 地址仅局域网内代表下一跳设备负责局域网内部数据转发IP决定数据走哪条路跨网路由MAC决定数据下一站给谁局域网直连转发IP网络层存在的意义提供网络虚拟层让世界的所有网络都是 IP 网络屏蔽最底层网络的差异TCP和UCP二、核心区别对比特性TCPUDP连接性面向连接三次握手 / 四次挥手无连接直接发送可靠性可靠确认、重传、排序、校验不可靠尽力而为可能丢包 / 乱序传输模式字节流无边界像水管流水数据报有边界独立数据包流量 / 拥塞控制有滑动窗口、慢启动等无通信方式一对一点对点支持一对一、一对多、多对多广播 / 组播首部开销大最小20 字节小固定8 字节传输效率低延迟高、开销大高延迟低、速度快典型应用HTTP/HTTPS, FTP, SMTP, 邮件文件传输视频通话、直播、游戏、DNS、实时音视频5. Socket编程预备5.1 端口号1什么是端口号端口号属于传输层协议内容大小为2 字节、16 位整数作用标识主机内进程让系统区分数据交由哪个程序处理IP 地址 端口号可唯一确定网络中一台主机的某个进程同一时刻一个端口号仅能被一个进程占用2端口号范围划分0~1023知名端口固定分配给 HTTP、FTP、SSH 等常用应用层协议1024~65535动态端口由操作系统分配多用于客户端程序3端口号 与 PID 的区别 关系PID操作系统全局唯一标识所有进程是系统层级标识。端口号专门用于网络通信的进程标识属于网络层级。设计分离不用 PID 做网络标识避免网络与系统进程管理强耦合。绑定规则一个进程可绑定多个端口一个端口同一时刻只能被一个进程占用4源端口 目的端口源端口标识数据发送方进程目的端口标识数据接收方进程5理解socketIP 地址用来标识互联网中唯一的一台主机 port 用来标识该主机上唯一的一个网络进程IPPort 就能表示互联网中唯一的一个进程四元组源IP源端口目的IP目的端口唯一标识两端通信进程网络通信本质跨主机的进程间通信Socket套接字 IP 端口6. 传输层的典型代表6.1 认识TCP协议传输层协议有连接通信前需要建立连接可靠传输数据保证完整、有序、不丢失面向字节流数据以字节流形式传输6.2 认识UDP协议传输层协议无连接无需提前建立连接直接发送数据不可靠传输不保证数据一定送达、有序面向数据报以独立数据报为单位收发6.3 总结与选择选 TCP数据完整性 速度。适合文件、网页、邮件等不能出错的场景。选 UDP速度 / 实时性 完整性。适合视频、语音、游戏等可容忍少量丢包的场景7. 网络字节序送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节如果当前发送主机是小端就需要先将数据转成大端否则就忽略大端如何发送:先发低地址 →0x12数据高位再发0x34再发0xab最后发高地址 →0xcd数据低位为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换h 表示 host , n 表示 network , l (long)表示 32 位长整数, s (short)表示 16 位短整数例如htonl 表示将 32 位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送所有发送到网络上的数据都必须是大端的8. socket 编程接口8.1 常见函数创建 socket ⽂件描述符 (TCP/UDP, 客户端 服务器) #include sys/socket.h int socket(int domain, int type, int protocol); 第一个参数domain /af地址族 / 协议族 AF_INET IPv4 协议最常用 AF_UNIX / AF_LOCAL 本地进程通信 第二个参数type套接字类型 SOCK_DGRAM UDP 数据报套接字最常用 SOCK_STREAM TCP 流式套接字最常用 SOCK_RAW 原始套接字 第三个参数protocol具体协议号 0 自动匹配推荐 返回值 成功返回一个非负整数称为套接字描述符 失败返回 -1绑定端⼝号 (TCP/UDP, 服务器) int bind(int socket, const struct sockaddr *address, socklen_t address_len); 第二个参数 必须强制类型转换(struct sockaddr*) 返回值 成功返回 0 失败返回 -1 区分std::bind() C 标准库的函数工具用来绑定函数、固定参数、修改函数调用方式套接字数据接收函数 #include sys/types.h #include sys/socket.h ssize_t recvfrom( int sockfd, // 套接字文件描述符 void *buf, // 接收缓冲区 size_t len, // 缓冲区最大长度 int flags, // 控制标志 struct sockaddr *src_addr, // 输出发送方地址 socklen_t *addrlen // 输入输出地址缓冲区大小 ); flags 0 默认阻塞模式无特殊行为 返回值 成功返回实际读到的字节数 出错返回 -1UDP协议发送数据 #include sys/socket.h ssize_t sendto( int sockfd, // 套接字文件描述符 const void *buf, // 要发送的数据缓冲区 size_t len, // 数据长度 int flags, // 标志位一般填 0 const struct sockaddr *dest_addr, // 目标地址IP端口 socklen_t addrlen // 地址结构体长度 ); 成功返回 实际发送的字节数 失败返回 -1启动服务器并监听连接 int listen(int sockfd, int backlog); 第二个参数 含义TCP 连接队列的最大长度 作用控制还没被服务器 accept () 处理的连接最多能排队多少个用于客户端向服务器发起网络连接 int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);8.2 sockaddr结构IPv4 使用sockaddr_in存储 IP 端口Socket API 统一用struct sockaddr*接收靠AF_INET/AF_INET6区分地址类型实现一套接口兼容所有协议网络编程 4 件套 #include sys/types.h 系统基础类型必加 #include sys/socket.h 套接字函数socket/connect/bind #include netinet/in.h sockaddr_in 结构体核心 #include arpa/inet.h IP转换inet_addr/inet_ptonsockaddr_in 结构虽然socket api的接口是sockaddr但是在基于IPv4编程时使用的数据结构是sockaddr_in这个结构里主要有三部分信息地址类型端口号IP地址// 来自头文件 netinet/in.h struct sockaddr_in { sa_family_t sin_family; // 1. 地址族必须填 AF_INET in_port_t sin_port; // 2. 端口号必须用 htons() 转换 struct in_addr sin_addr; // 3. IP地址结构体需要强转 char sin_zero[8]; // 4. 填充字节全填0为了对齐内存 }; // 里面嵌套的 IP 地址结构体 struct in_addr { uint32_t s_addr; // 真正存IPv4地址32位整数 }; 参数 1.sin_family地址族必须填 AF_INET 2. sin_port端口号 必须用 htons () 转换 因为端口号本身就只有16位长 3. sin_addr.s_addrIP 地址 4. 0

更多文章