【Linux网络】Socket编程预备
1. 理解源IP地址和目的IP地址IP在网络中用来标识主机的唯一性注意后面我们会讲IP的分类会详细阐述IP的特点但是这里要思考一个更深层次的问题数据传输到主机真的是最终目的吗其实并不是。因为数据最终都是为人服务的。比如聊天是人在聊天下载是人在下载浏览网页是人在浏览。数据只是载体人才是主体但是人是怎么看到聊天信息的呢怎么执行下载任务呢怎么浏览网页信息呢人是如何与这些数据交互的呢通过启动的 qq迅雷浏览器。而启动的 qq迅雷浏览器都是进程。换句话说进程是人在系统中的代表只要把数据给进程人就相当于是拿到了数据。 所以数据传输到主机不是目的而是手段。到达主机内部在交给主机内的进程才是目的。但是系统中同时会存在非常多的进程当数据到达目标主机之后怎么转发给目标进程在复杂的网络环境中如何确保数据不仅能到达目标主机还能准确送达目标进程显然仅靠IP地址标识了主机是远远不够的。这需要在两个层面建立标识体系网络层通过IP地址等标识主机的唯一性系统层通过端口号等标识进程的唯一性在这里插入图片描述2. 认识端口号端口号( port )是传输层协议的内容。端口号是一个 2 字节 16 位的整数;端口号用来标识一个进程告诉操作系统当前的这个数据要交给哪一个进程来处理;IP地址端口号能够标识网络上的某一台主机的某一个进程;一个端口号只能被一个进程占用在这里插入图片描述2.1 端口号范围划分0 - 1023 : 知名端口号这些端口号由IANA(互联网数字分配机构)统一分配和管理HTTP, FTP, SSH 等这些广为使用的应用层协议, 他们的端口号都是固定的.常见协议及其默认端口HTTP: 80HTTPS: 443FTP: 21(控制端口)/20(数据端口)SSH: 22Telnet: 23SMTP: 251024 - 65535 : 操作系统动态分配的端口号客户端程序的端口号, 就是由操作系统从这个范围分配的就像是我们现实中的电话号码例如那些110、119、120、10086等是固定特殊的号码而我们普通人则是动态分配的随机号码2.2 理解 “端口号” 和 “进程ID”我们之前在学习系统编程的时候, 学习了 pid 表示唯一的一个进程; 此处我们的端口号也是唯一表示一个进程. 那么这两者之间是怎样的关系?一个比喻10086客服热线端口号 (Port)就像是10086这个客服热线号码。这个号码是公开的、稳定的、对外提供服务的入口。任何用户想办理业务都知道要打这个号码。它不关心电话那头是张三、李四还是王五接听了电话。进程PID就像是客服中心里某一个具体的客服人员比如工号12345的张三。这个工号是内部管理的标识。用于公司内部进行考勤、发工资、绩效考核。客服人员可能会离职、换班、休息进程会退出、重启但10086这个热线号码是永远不变的。操作系统内核就像是客服中心的呼叫分配系统ACD。当客户拨打10086请求某个端口时分配系统会找到一个空闲的客服人员一个正在监听该端口的进程比如把电话转接给工号12345的张三PID12345的进程。如果张三今天休息了进程崩溃或退出分配系统会把来电转给工号67890的李四另一个进程PID67890。对于客户来说他始终拨打的是10086完全不知道背后接电话的人是谁也不会受到影响。核心结论目的和上下文不同端口号 (Port Number)是网络协议栈用来在网络通信中标识一个进程的ID。它的作用域是网络连接。 → 就像 10086这个客服热线号码。PID (Process ID)是操作系统内核用来在系统内部唯一标识和管理一个进程的ID。它的作用域是本地主机。 → 就像 客服中心里某一个具体的客服人员的工号比如工号12345的张三。另外:一个进程可以绑定多个端口号就像不能有两个不同的热线号码都叫10086否则客户就不知道该打哪个了。系统内核会保证一个端口在同一时间只能被一个进程监听。但是一个端口号不能被多个进程绑定就像一个超级客服可以同时负责接听10086、10085等多个热线。一个复杂的网络服务如Nginx可以同时监听80端口HTTP和443端口HTTPS。进程 PID 属于系统概念技术上也具有唯一性确实可以用来标识唯一的一个进程但是这样做会让系统进程管理和网络强耦合实际设计的时候并没有选择这样做。2.3 理解源端口号和目的端口号传输层协议( TCP 和 UDP )的数据段中有两个端口号分别叫做源端口号和目的端口号.就是在描述 “数据是谁发的, 要发给谁”。目的端口号回答了 “数据要交给对方主机的哪个进程” 这是通信的目标。源端口号回答了 “数据是来自对方主机的哪个进程” 并更重要的是它提供了 “请将回复发送到我的哪个端口” 的返回地址。2.4 理解socket综上 IP 地址用来标识互联网中唯一的一台主机port 用来标识该主机上唯一的一个网络进程故IPPort 就能表示互联网中唯一的一个进程所以通信的时候本质是两个互联网进程代表人来进行通信{srcIpsrcPortdstIpdstPort}这样的4元组就能标识互联网中唯二的两个进程{源IP源端口目标IP目标端口} 例如{192.168.1.2:54321203.179.25.16:80}表示从内网主机192.168.1.2的54321端口访问公网服务器203.179.25.16的Web服务所以网络通信的本质也就是全网唯二的两个进程在进程间通信。我们把 ipport 叫做套接字 socket注意我们之前学习了System V IPC进程间通信其实POSIX也有一套更标准的通信方式它不仅可以进行进程通信也能进行网络通信。而网络通信的方式就可以通过网络套接字Socket来实现当然也有本地套接字Socket可以实现进程间通信这里就不过多赘述感兴趣可以自行了解3. 传输层的典型代表如果我们了解了系统也了解了网络协议栈我们就会清楚传输层是属于内核的那么我们要通过网络协议栈进行通信必定调用的是传输层提供的系统调用来进行的网络通信。在这里插入图片描述3.1 认识TCP协议此处我们先对 TCP ( Transmission Control Protocol 传输控制协议)有一个直观的认识; 后面我们再详细讨论TCP的一些细节问题.传输层协议有连接可靠传输面向字节流3.2 认识UDP协议此处我们也是对 UDP ( User Datagram Protocol 用户数据报协议)有一个直观的认识; 后面再详细讨论.传输层协议无连接不可靠传输面向数据报因为我们暂时还没有深入了解 tcp 、 udp 协议此处我们下面只需对概念做下了解即可什么是有连接和无连接?指通信双方在交换数据之前是否需要先建立一个专门的通道。可靠和不可靠又是指什么?指协议是否保证数据能够准确无误、完整地送达对方。从字面意思其实就不难看出来但是这里要提一嘴不可靠不一定就不好它其实是一个中性词存在即合理既然不可靠还会留下来说明肯定有它的独到之处就比如有时候我们看直播之类的突然卡了比如数据掉包但是它卡了之后并不会继续刚刚的画面有可能就是在那之后的画面了但是这也并不会有什么影响如果要保证可靠的话实现肯定就要复杂很多有时候我们不追求这种就可以使用UDP那什么又是面向字节流什么又是面向数据报呢面向字节流 (TCP)像用吸管喝水。你喝到的是一个连续的水流你不知道一开始倒进杯子里的是哪几口水。面向数据报 (UDP)像用手递手拿糖果。每次传递都是一颗完整的、独立的糖果。4. 网络字节序我们已经知道内存中的多字节数据相对于内存地址有大端和小端之分。磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分网络数据流同样有大端小端之分那么如何定义网络数据流的地址呢?发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出;接收主机把从网络上接到的字节依次保存在接收缓冲区中也是按内存地址从低到高的顺序保存;因此网络数据流的地址应这样规定先发出的数据是低地址后发出的数据是高地址.TCP/IP协议规定网络数据流应采用大端字节序即低地址高字节.不管这台主机是大端机还是小端机都会按照这个TCP/IP规定的网络字节序来发送/接收数据;如果当前发送主机是小端就需要先将数据转成大端否则就忽略直接发送即可在这里插入图片描述为什么要有“网络字节序”不同主机可能有不同的字节序大端机或小端机。如果它们直接按照自己内存中的格式发送数据就会导致严重的通信问题。网络字节序的提出就是为了给网络通信提供一个统一的、标准化的数据表示格式从而消除不同平台字节序差异带来的歧义实现异构系统之间的可靠通信为使网络程序具有可移植性使同样的C代码在大端和小端计算机上编译后都能正常运行可以调用以下库函数做网络字节序和主机字节序的转换。在这里插入图片描述代码语言javascriptAI代码解释#include arpa/inet.h // 主机字节序 - 网络字节序 (Host to Network) uint32_t htonl(uint32_t hostlong); // 转换32位长整数常用于IP地址 uint16_t htons(uint16_t hostshort); // 转换16位短整数常用于端口号 // 网络字节序 - 主机字节序 (Network to Host) uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort);这些函数名很好记h 表示host, n 表示network, l 表示 32 位长整数, s 表示 16 位短整数。例如htonl表示将 32 位的长整数从主机字节序转换为网络字节序例如将IP地址转换后准备发送。如果主机是小端字节序这些函数将参数做相应的大小端转换然后返回;如果主机是大端字节序这些函数不做转换将参数原封不动地返回。网络规定所有发送到网络上的数据都必须是大端的5. socket编程接口5.1 socket 常见API代码语言javascriptAI代码解释// 创建 socket ⽂件描述符 (TCP/UDP, 客⼾端 服务器) int socket(int domain, int type, int protocol); // 绑定端⼝号 (TCP/UDP, 服务器) int bind(int socket, const struct sockaddr *address, socklen_t address_len); // 开始监听socket (TCP, 服务器) int listen(int socket, int backlog); // 接收请求 (TCP, 服务器) int accept(int socket, struct sockaddr* address, socklen_t* address_len); // 建⽴连接 (TCP, 客户端) int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);这里我们先了解一下这些接口后面Socket编程时会详细介绍这些接口。仔细观察一下我们可以发现大部分接口都有sockaddr结构体5.2 sockaddr结构socket API是一层抽象的网络编程接口适用于各种底层网络协议如IPv4、IPv6以及后面要讲的UNIX Domain Socket.。然而,各种网络协议的地址格式并不相同.在这里插入图片描述IPv4和IPv6的地址格式定义在netinet/in.h中IPv4地址用sockaddr_in结构体表示包括16位地址类型16位端口号和32位IP地址.IPv4、IPv6地址类型分别定义为常数AF_INET、AF_INET6.。这样只要取得某种sockaddr结构体的首地址不需要知道具体是哪种类型的sockaddr结构体就可以根据地址类型字段确定结构体中的内容.socket API可以都用struct sockaddr *类型表示在使用的时候需要强制转化成sockaddr_in; 这样的好处是程序的通用性可以接收IPv4, IPv6以及UNIX Domain Socket各种类型的sockaddr结构体指针做为参数;而上图中sockaddr_in用于网络通信使用IP地址和端口号作为寻址方式。sockaddr_un用于本地进程间通信使用文件系统路径作为寻址方式。socket会有很多的种类来满足不同的应用场景socket未来的接口会有不同的通信接口规范socket的设计者只想提供一种通信接口可以自行区分你到底是网络通信还是本地通信。代码语言javascriptAI代码解释if(address-sin_family AF_INET) else if(address-sin_family AF_UNIX)所以说白了这不就是继承和多态嘛struct sockaddr是基类而struct sockaddr_instruct sockaddr_un以及struct sockaddr_in6IPv6等都是派生类sockaddr 结构在这里插入图片描述sockaddr_in 结构在这里插入图片描述虽然socket api的接口是sockaddr但是我们真正在基于IPv4编程时, 使用的数据结构是sockaddr_in这个结构里主要有三部分信息地址类型、端口号、IP地址。in_addr结构、在这里插入图片描述in_addr用来表示一个IPv4的IP地址. 其实就是一个32位的整数我们现在已经铺垫了一些知识下一篇文章我们就来写代码通过理论代码能更好帮助我们理解网络通信当然关于具体的协议例如传输层的UDP和TCP协议网络层的IP协议等我们后面也会详细探讨

相关新闻

Java SpringBoot+Vue3+MyBatis 大学生创新创业项目管理系统系统源码|前后端分离+MySQL数据库

Java SpringBoot+Vue3+MyBatis 大学生创新创业项目管理系统系统源码|前后端分离+MySQL数据库

摘要 随着高等教育改革的深入推进,大学生创新创业项目的数量逐年增加,传统的项目管理方式已难以满足高效、便捷的管理需求。项目信息分散、审批流程繁琐、团队协作效率低下等问题日益突出,亟需一套科学化、信息化的管理系统来优化项目全生命周…

2026/5/17 11:11:15 阅读更多 →
二十层线路板设计制造,信号完整性与成本控制是关键

二十层线路板设计制造,信号完整性与成本控制是关键

去进行二十层 PCB 板的设计,这就如同于在微观的世界范围之内去构建一座具备精密立体特质的“电子城市”一般。那信号它会在那些层层叠叠的介质当中进行高速的穿行,对于工程师而言,所面临的早就已经不再是那种“能不能连通”的属于初级阶段的问…

2026/5/17 11:11:16 阅读更多 →
如何升级node.js版本

如何升级node.js版本

升级Node.js可以通过多种方式来完成,以下是四种常见的方法: 方法一:使用Node.js官方安装程序 访问Node.js的官方网站,下载对应你操作系统的最新版本安装程序。通常,你可以 https://nodejs.org/en/download 找到你需…

2026/7/4 16:42:58 阅读更多 →

最新新闻

2026视频去水印方法,免费视频去水印实用教程

2026视频去水印方法,免费视频去水印实用教程

在日常浏览短视频、自媒体素材整理、个人作品备份的场景中,视频水印常常会影响画面观感与素材使用效果。很多普通用户都在寻找简单、高效、无门槛的视频去水印方案,尤其是适配手机、电脑多端的免费视频去水印方法。2026年各类去水印工具持续迭代&#xf…

2026/7/4 21:13:56 阅读更多 →
Codex如何为AI代码生成树立质量标杆:从原理到实践

Codex如何为AI代码生成树立质量标杆:从原理到实践

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Qwen 随心用,限时 5 折。 👉 点击领海量免费额度 1. 先搞清楚“最严的父亲”到底在说什么 看到“Codex堪称Claude Code最严的父亲”这个标题,第一反应可能是困惑。这不像一…

2026/7/4 21:13:56 阅读更多 →
VisTR完全指南:从安装到推理,30分钟快速掌握视频实例分割神器

VisTR完全指南:从安装到推理,30分钟快速掌握视频实例分割神器

VisTR完全指南:从安装到推理,30分钟快速掌握视频实例分割神器 【免费下载链接】VisTR [CVPR2021 Oral] End-to-End Video Instance Segmentation with Transformers 项目地址: https://gitcode.com/gh_mirrors/vi/VisTR VisTR(End-to-…

2026/7/4 21:11:55 阅读更多 →
CANN/ge LLM-DataDist C++接口列表

CANN/ge LLM-DataDist C++接口列表

# LLM-DataDist-interface-list 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE…

2026/7/4 21:09:54 阅读更多 →
电流频率转换模块选型要考虑哪些参数?量程匹配、精度等级与封装形式的综合决策

电流频率转换模块选型要考虑哪些参数?量程匹配、精度等级与封装形式的综合决策

I/F(电流-频率)转换模块的选型直接影响测控系统的整体性能。面对不同的应用场景和技术要求,如何从量程、精度、温度范围、封装形式、输出频率等多个维度做出合理选择,是系统设计师需要解决的问题。本文结合智腾微电子JLHIF160的技…

2026/7/4 21:09:54 阅读更多 →
ThinkPHP 6.0.8反序列化漏洞深度剖析:从POP链原理到实战利用

ThinkPHP 6.0.8反序列化漏洞深度剖析:从POP链原理到实战利用

1. 项目概述:一次对ThinkPHP6.0.8反序列化漏洞的深度剖析最近在复盘一些经典的PHP框架漏洞案例,ThinkPHP6.0.8的反序列化漏洞(CVE-2021-36542)绝对是一个绕不开的经典。这个漏洞的利用链(POP Chain)设计得非…

2026/7/4 21:05:52 阅读更多 →

日新闻

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 正式发布,这是一个关键的安全修复版本,修复了多个方面的问题,还对部分功能进行了优化。 安全修复亮点 此次发布在安全修复上表现突出。binprot 避免了项目引用计数溢出,mcmc 因安全问题提升了上游版本号&#xf…

2026/7/4 0:04:29 阅读更多 →
终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL HMCL(Hello Minecraft! Lau…

2026/7/4 0:06:29 阅读更多 →
KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

1. KMX63与PIC18F66K40的硬件协同架构解析KMX63作为一款三轴加速度计和磁力计组合传感器,与PIC18F66K40微控制器的搭配堪称嵌入式HMI开发的黄金组合。这套硬件组合的核心优势在于KMX63提供的高精度运动感知能力与PIC18F66K40强大的信号处理能力形成了完美互补。KMX6…

2026/7/4 0:06:29 阅读更多 →

周新闻

月新闻