【Linux 学习指南】网络编程基础:从 IP、端口到 Socket 与 TCP/UDP 协议详解

请添加图片描述

文章目录

  • 📝理解源IP地址和目的IP地址
  • 🌠 认识端口号
    • 🌉端口号范围划分
    • 🌉理解"端口号"和"进程ID"
    • 🌉理解源端口号和目的端口号
    • 🌉理解socket
  • 🌠传输层的典型代表
    • 🌉认识TCP协议
    • 🌉 认识UDP协议
  • 🌠网络字节序
  • 🌠Socket 编程接口
    • 🌉Socket 常见API
    • 🌉sockaddr 结构
    • 🌉`in_addr` 结构
  • 🚩总结


📝理解源IP地址和目的IP地址

  • IP在网络中,用来标识主机的唯一性
  • 注意:后面我们会讲IP的分类,后面会详细阐述IP的特点
    但是这里要思考一个问题:数据传输到主机是目的吗?不是的。因为数据是给人用的。比如:聊天是人在聊天,下载是人在下载,浏览网页是人在浏览?

但是人是怎么看到聊天信息的呢?怎么执行下载任务呢?怎么浏览网页信息呢?通过启动的qq,迅雷,浏览器。
而启动的qq,迅雷,浏览器都是进程。换句话说,进程是人在系统中的代表,只要把数据给进程,人就相当于就拿到了数据。

所以:数据传输到主机不是目的,而是手段。到达主机内部,在交给主机内的进程,才是目的。

但是系统中,同时会存在非常多的进程,当数据到达目标主机之后,怎么转发给目标进程?这就要在网络的背景下,在系统中,标识主机的唯一性。

在这里插入图片描述

🌠 认识端口号

端口号(port)是传输层协议的内容

  • 端口号是一个2字节16位的整数;
  • 端口号用来标识一个进程,告诉操作系统,当前的这个数据要交给哪一个进程来处理;
  • IP地址+端口号能够标识网络上的某一台主机的某一个进程;
  • 一个端口号只能被一个进程占用.

在这里插入图片描述

🌉端口号范围划分

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

🌉理解"端口号"和"进程ID"

我们之前在学习系统编程的时候,学习了pid表示唯一一个进程;此处我们的端口号也是唯一表示一个进程.那么这两者之间是怎样的关系?

在Linux系统中,进程ID(PID)和端口号都可用于标识进程,但二者有着不同的概念和用途,它们之间存在一定的关联关系。具体如下:

  • 概念及用途不同
    • 进程ID(PID):是系统为每个运行中的进程分配的唯一标识符,属于系统级的概念。无论进程是否参与网络通信,系统都会为其分配PID,用于在内核中管理和区分各个进程,是操作系统进行进程调度、资源分配等操作的重要依据。
    • 端口号:是传输层协议的内容,是一个16位的整数,用于在网络通信中标识主机中的进程。它是网络概念,主要用于区分同一台主机上不同的网络服务或应用程序,当数据通过网络传输到主机时,操作系统根据端口号将数据交给对应的进程处理。
  • 对应关系
    • 一个进程可以绑定多个端口号。例如,一个Web服务器进程可能同时监听80端口(用于HTTP协议)和443端口(用于HTTPS协议),就像一个人可以有多个身份标识,在不同场景下使用不同标识一样。
    • 一个端口号只能被一个进程占用(特殊情况除外,如支持多进程监听的情况,但也是在特定机制下),以保证标识进程的唯一性,否则会导致网络数据传输混乱。
  • 查询方法
    • 已知PID查询端口号,可以使用netstat -tulnp | grep <PID>lsof -i -P -n | grep <PID>命令。
    • 已知端口号查询PID,可以使用netstat -nap | grep <端口号>lsof -i :<端口号>命令。

以10086为例,如果有一个进程号为10086的进程,你想知道它占用了哪些端口,可以使用sudo netstat -tulnp | grep 10086命令来查看。反之,如果已知某个网络服务使用的端口号是10086,想知道是哪个进程在占用该端口,则可以使用sudo lsof -i :10086命令,命令执行后会显示占用该端口的进程PID及相关信息。

因此:一个进程可以绑定多个端口号;但是一个端口号不能被多个进程绑定;

进程ID属于系统概念,技术上也具有唯一性,确实可以用来标识唯一的一个进程,但是这样做,会让系统进程管理和网络强耦合,实际设计的时候,并没有选择这样做。

🌉理解源端口号和目的端口号

传输层协议(TCPUDP)的数据段中有两个端口号,分别叫做源端口号和目的端口号.就是在描述"数据是谁发的,要发给谁"

🌉理解socket

综上,IP地址用来标识互联网中唯一的一台主机,port用来标识该主机上唯一的
一个网络进程
IP+Port就能表示互联网中唯一的一个进程
• 所以,通信的时候,本质是两个互联网进程代表人来进行通信,{srcIpsrcPortdstIpdstPort}这样的 4元组就能标识互联网中唯二的两个进程
• 所以,网络通信的本质,也是进程间通信
• 我们把ip+port叫做套接字socket

C++
socket
n.
(电源)插座;(电器上的)插口,插孔,管座;槽;窝;托座;臼;孔穴
vt.
把…装入插座;给…配插座

🌠传输层的典型代表

如果我们了解了系统,也了解了网络协议栈,我们就会清楚,传输层是属于内核的,那么我们要通过网络协议栈进行通信,必定调用的是传输层提供的系统调用,来进行的网络通信。

在这里插入图片描述

🌉认识TCP协议

此处我们先对TCP(Transmission Control Protocol 传输控制协议)有一个直观的认识;后面我们再详细讨论TCP的一些细节问题.

  • 传输层协议
  • 有连接
  • 可靠传输
  • 面向字节流

🌉 认识UDP协议

此处我们也是对UDP(UserDatagramProtocol 用户数据报协议)有一个直观的认识;后面再详细讨论.

  • 传输层协议
  • 无连接
  • 不可靠传输
  • 面向数据报

🌠网络字节序

我们已经知道,内存中的多字节数据相对于内存地址有大端和小端之分,磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分,网络数据流同样有大端小端之分. 那么如何定义网络数据流的地址呢?

  • 发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出;接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存;
  • 因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址.
  • TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节.
  • 不管这台主机是大端机还是小端机,都会按照这个TCP/IP规定的网络字节序来发送/接收数据;
  • 如果当前发送主机是小端,就需要先将数据转成大端;否则就忽略,直接发送即可

在这里插入图片描述
为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换。

在这里插入图片描述
这些函数名很好记,h表示host,n表示network,l表示32位长整数,s表示16位短整数。

  • 例如htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。
  • 如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回;
  • 如果主机是大端字节序,这些函数不做转换,将参数原封不动地返回。

🌠Socket 编程接口

🌉Socket 常见API

C// 创建 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);
  1. socket() - 创建网络端点
int socket(int domain, int type, int protocol);
  • 功能:创建一个网络通信的端点(socket描述符),类似于文件描述符,用于后续的网络操作。
  • 参数
    • domain:协议族(地址族),指定网络通信的地址类型,常见值:
      • AF_INET:IPv4协议
      • AF_INET6:IPv6协议
      • AF_UNIX:本地进程间通信(Unix域socket)
    • type:套接字类型,决定通信方式:
      • SOCK_STREAM:流式套接字,对应TCP协议(可靠、面向连接)
      • SOCK_DGRAM:数据报套接字,对应UDP协议(不可靠、无连接)
      • SOCK_RAW:原始套接字,用于直接访问底层协议(如ICMP)
    • protocol:具体协议,通常设为0表示根据前两个参数自动选择默认协议
  • 返回值:成功返回非负的socket描述符,失败返回-1并设置errno
  1. bind() - 绑定地址和端口
int bind(int socket, const struct sockaddr *address, socklen_t address_len);
  • 功能:将socket与特定的IP地址和端口号绑定(主要用于服务器端)。
  • 参数
    • socketsocket()返回的描述符
    • address:指向struct sockaddr(或其衍生结构,如struct sockaddr_in)的指针,包含要绑定的IP和端口
    • address_lenaddress结构体的长度
  • 典型用法(服务器端):
    struct sockaddr_in serv_addr;
    serv_addr.sin_family = AF_INET;         // IPv4
    serv_addr.sin_addr.s_addr = INADDR_ANY; // 绑定到所有本地网卡
    serv_addr.sin_port = htons(8080);       // 端口号(需转换为网络字节序)
    bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
    
  • 返回值:成功返回0,失败返回-1
  1. listen() - 监听连接请求
int listen(int socket, int backlog);
  • 功能:将流式套接字(TCP)转为被动监听状态,准备接收客户端连接(仅服务器端使用)。
  • 参数
    • socket:已绑定的socket描述符
    • backlog:未处理连接的最大队列长度(超过此数的连接会被拒绝)
  • 注意:仅用于TCP协议,UDP无需监听
  • 返回值:成功返回0,失败返回-1
  1. accept() - 接收客户端连接
int accept(int socket, struct sockaddr* address, socklen_t* address_len);
  • 功能:从监听队列中取出一个客户端连接请求,创建新的socket用于与该客户端通信(仅TCP服务器使用)。
  • 参数
    • socket:处于监听状态的socket描述符(监听套接字)
    • address:输出参数,用于存储客户端的地址信息
    • address_len:输入输出参数,传入缓冲区长度,返回实际地址长度
  • 特点
    • 阻塞调用,若无连接会一直等待
    • 返回新的socket描述符(连接套接字),与客户端的通信通过该描述符进行
    • 原监听 socket继续监听新的连接
  • 返回值:成功返回新的socket描述符,失败返回-1
  1. connect() - 建立连接
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
  • 功能:客户端主动向服务器发起连接(仅TCP客户端使用)。
  • 参数
    • sockfd:客户端的socket描述符
    • addr:指向服务器地址结构的指针(包含服务器IP和端口)
    • addrlen:地址结构的长度
  • 特点
    • 触发TCP三次握手过程
    • 阻塞调用,直到连接建立或失败
  • 返回值:成功返回0,失败返回-1

典型工作流程

  • TCP服务器socket()bind()listen()accept() → 读写数据
  • TCP客户端socket()connect() → 读写数据
  • UDP(无连接):通常只需socket()bind()(服务器),无需listen()/accept()/connect()

🌉sockaddr 结构

socket API 是一层抽象的网络编程接口,适用于各种底层网络协议,如IPv4、IPv6,以及后面要讲的UNIXDomainSocket.然而,各种网络协议的地址格式并不相同.

在这里插入图片描述

  • IPv4IPv6的地址格式定义在netinet/in.h中,IPv4地址用sockaddr_in结构体表示,包括16位地址类型,16位端口号和32IP地址.
  • IPv4、IPv6地址类型分别定义为常数AF_INETAF_INET6.这样,只要取得某种sockaddr结构体的首地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的内容.
  • socketAPI可以都用struct sockaddr *类型表示, 在使用的时候需要强制转化成sockaddr_in; 这样的好处是程序的通用性,可以接收IPv4, IPv6, 以及UNIXDomain
  • Socket 各种类型的sockaddr结构体指针做为参数;

  1. sockaddr 结构
/* Structure describing a generic socket address.  */
struct __attribute_struct_may_alias__ sockaddr{__SOCKADDR_COMMON (sa_);	/* Common data: address family and length.  */char sa_data[14];		/* Address data.  */};
  1. sockaddr_in 结构
/* Structure describing an Internet socket address.  */
struct __attribute_struct_may_alias__ sockaddr_in{__SOCKADDR_COMMON (sin_);in_port_t sin_port;			/* Port number.  */struct in_addr sin_addr;		/* Internet address.  *//* Pad to size of `struct sockaddr'.  */unsigned char sin_zero[sizeof (struct sockaddr)- __SOCKADDR_COMMON_SIZE- sizeof (in_port_t)- sizeof (struct in_addr)];};

虽然socket api的接口是sockaddr, 但是我们真正在基于IPv4编程时,使用的数据结构是sockaddr_in; 这个结构里主要有三部分信息:地址类型,端口号,IP地址.

🌉in_addr 结构

/* Internet address.  */
typedef uint32_t in_addr_t;
struct in_addr{in_addr_t s_addr;};

in_addr 用来表示一个IPv4IP地址.其实就是一个32位的整数


🚩总结

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/89232.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/89232.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React+Next.js+Tailwind CSS 电商 SEO 优化

一、项目背景与技术选型​1. 原始痛点​项目最初基于纯 React 开发&#xff08;SPA 架构&#xff09;&#xff0c;存在三个致命问题&#xff1a;​搜索引擎爬虫无法有效抓取动态渲染的商品详情、分类页内容&#xff1b;​单页面应用 难以实现页面级的 meta 定制&#xff0c;关键…

Process Lasso:提升电脑性能的得力助手

在日常使用电脑的过程中&#xff0c;我们常常会遇到这样的问题&#xff1a;电脑运行缓慢、程序响应迟缓、多任务处理时卡顿不断。这些问题不仅影响工作效率&#xff0c;还让人感到非常烦躁。其实&#xff0c;这些问题很多时候是因为电脑的进程管理不够优化。而Process Lasso正是…

AI驱动的大前端内容创作与个性化推送:资讯类应用实战指南

在信息爆炸的时代&#xff0c;资讯类应用面临两大核心挑战&#xff1a;一是如何高效生产海量优质内容&#xff0c;二是如何让用户从海量信息中快速获取感兴趣的内容。AI技术的介入正在重构资讯类应用的开发模式&#xff0c;从内容生产到用户触达形成全链路智能化。本文将从开发…

2025/7/16——java学习总结

Java IO 流全体系总结&#xff1a;从基础到实战的完整突破&#xff08;重写&#xff09;一、基础核心&#xff1a;字节流与字符流的底层逻辑&#xff08;一&#xff09;字节流&#xff1a;二进制数据的读写基础操作字节输入流&#xff1a;掌握 FileInputStream 单字节读取细节&…

书籍自然数数组的排序(8)0715

题目给定一个长度为N的整型数组arr&#xff0c;其中有N个互不相等的自然数1~N&#xff0c;请实现arr的排序&#xff0c;但是不要把下标0~N-1位置上的数通过直接赋值的方式替换成1~N。解答 arr在调整之后应该事下标从0到N-1的位置上依次放着1~N&#xff0c;即arr[index] index …

【08】MFC入门到精通——MFC模态对话框 和 非模态对话框 解析 及 实例演示

文章目录八、模态对话框 和 非模态对话框 创建及显示8.1 对话框是怎样弹出的8.2 模态对话框的创建及显示8.3 非模态对话框的创建及显示8.4 完整代码下载八、模态对话框 和 非模态对话框 创建及显示 Windows对话框分为两类&#xff1a;模态对话框 和 非模态对话框。 模态对话框…

github上传大文件(多种解决方案)

之前一直用vscode的上传项目方法&#xff0c;这个方便之处在于不用打开git终端输入各种命令&#xff0c;不过麻烦的是我一直无法拉取github上的远程仓库提交&#xff0c;每次只能更新已有的仓库并且上传的文件还不能太大&#xff0c;应该是不能超过100MB&#xff0c;而且直接在…

生活污水深度除磷的方法

生活污水中磷含量过多的危害大家都知道总磷是水质检测的重要指标之一&#xff0c;在污水处理中生活污水往往都会出现总磷超标的现象。生活污水磷超标的危害是多方面的主要包括水体富营养化、危害水生生物、影响人类健康&#xff0c;以及可能引发蓝藻水华等问题。除磷方法污水的…

Flutter瀑布流布局深度实践:打造高性能动态图片墙

本文将深入探讨如何在Flutter中实现高性能瀑布流布局&#xff0c;解决动态高度内容展示的核心难题&#xff0c;并带来卓越的用户体验。引言&#xff1a;瀑布流布局的魅力 瀑布流布局(Pinterest-style layout)已成为现代应用展示图片和内容的黄金标准。它通过错落有致的排列方式…

OpenCV 伽马校正函数gammaCorrection()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 该函数用于对输入图像应用伽马校正&#xff08;Gamma Correction&#xff09;&#xff0c;这是一种非线性的图像处理技术&#xff0c;主要用于调整…

Linux-局域网构建+VLAN 划分 + 端口 MAC-IP 绑定 + 静态 DHCP

文章目录1. 适用于家庭、工作室或小型企业的局域网构建2. VLAN划分3. VLAN 划分 端口 MAC-IP 绑定 静态 DHCP跳转→网络管理基础复习 1. 适用于家庭、工作室或小型企业的局域网构建 ✅ 一、硬件连线&#xff08;一次到位&#xff09; 光纤入户 → 光猫/宽带调制解调器光猫…

渗透测试路线

渗透测试学习路线报告&#xff08;从入门到高级&#xff09; 引言&#xff1a;渗透测试概述与学习路线设计 渗透测试作为网络安全体系中的核心实践环节&#xff0c;通过模拟真实攻击者的技术手段与攻击路径&#xff0c;主动识别信息系统中的安全漏洞、评估防护机制有效性&#…

Node.js 中http 和 http/2 是两个不同模块对比

1. 核心模块对比 特性http 模块 (HTTP/1.1)http2 模块 (HTTP/2)协议版本HTTP/1.1&#xff08;文本协议&#xff09;HTTP/2&#xff08;二进制协议&#xff09;多路复用不支持&#xff08;需多个 TCP 连接&#xff09;支持&#xff08;单连接多流&#xff09;头部压缩无HPACK 压…

3DGS之COLMAP

COLMAP 在 3DGS 中起到了数据预处理和三维重建的关键作用&#xff0c;其处理流程包括特征提取与匹配、稀疏重建、稠密重建和输出文件生成。结合 3DGS 的高斯分布建模和优化算法&#xff0c;COLMAP 提供了场景的几何和相机信息&#xff0c;为实时渲染和三维重建奠定了基础。一、…

RabbitMQ中队列长度限制(Queue Length Limit)详解

在 RabbitMQ 中&#xff0c;队列长度限制&#xff08;Queue Length Limit&#xff09;是指对队列中消息数量的最大限制。当队列中的消息数量达到设定的上限时&#xff0c;RabbitMQ 会根据配置的策略&#xff08;如丢弃旧消息、拒绝新消息或将消息转移到另一个队列&#xff09;来…

Python设计模式深度解析:建造者模式(Builder Pattern)完全指南

Python设计模式深度解析&#xff1a;建造者模式&#xff08;Builder Pattern&#xff09;完全指南前言什么是建造者模式&#xff1f;建造者模式的核心思想模式的核心组成实际案例一&#xff1a;UI选择组件的动态构建抽象建造者基类具体建造者实现列表框建造者复选框建造者工厂建…

elementuiPlus+vue3手脚架后台管理系统,上生产环境之后,如何隐藏vite.config.ts的target地址

在项目根目录创建 .env.production 文件&#xff1a; VITE_API_TARGEThttps://your-real-api.com修改 vite.config.ts&#xff1a; import { defineConfig, loadEnv } from viteexport default defineConfig(({ mode }) > {const env loadEnv(mode, process.cwd(), )return…

ARCGIS PRO DSK 颜色选择控件(ColorPickerControl)的调用

颜色选择控件ColorPickerControl 。一、XAML 集成方式 1 、在WPF窗体上使用&#xff0c;xml&#xff1a;加入空间命名引用xmlns:ui1"clr-namespace:ArcGIS.Desktop.Internal.Mapping.Symbology;assemblyArcGIS.Desktop.Mapping" xmlns:uil"http://schemas.xceed…

深浅拷贝以及函数缓存

目录 数据类型介绍 基本数据类型&#xff08;Primitive Types&#xff09; 引用数据类型&#xff08;Reference Types&#xff09; 浅拷贝 深拷贝 利用JSON的序列化和反序列化实现深拷贝 递归实现深拷贝 第三方库lodash的cloneDeep 函数缓存的概念 实现方法 数据类型介…

第六届信号处理与计算机科学国际学术会议(SPCS 2025)

重要信息 官网&#xff1a;www.icspcs.org &#xff08;详情见官网&#xff09; 时间&#xff1a;2025年8月15-17日 地点&#xff1a;西安 主题 信号处理与智能计算计算科学与人工智能网络与多媒体技术数字信号处理 雷达信号处理 通信信号处理 临时和传感器网络 模拟和…