【TCP/IP协议栈】【传输层】端口号、套接字、多路复用/分解、网络字节序

参考资料:

前言:

总结:

【计算机网络】套接字(应用层和传输层之间的接口)

  1. 套接字是一个通用的通信接口抽象
  2. 不仅限于TCP/IP协议族
  3. 作为应用层和传输层之间的桥梁
  4. 支持多种通信方式和协议族

套接字定义

在 TCP 或者 UDP 发送具体的报文信息前,需要先经过一扇 ,这个门就是套接字(socket),套接字向上连接着应用层,向下连接着网络层。在操作系统中,操作系统分别为应用和硬件提供了接口(Application Programming Interface)。而在计算机网络中,套接字同样是一种接口,它也是有接口 API 的。

使用 TCP 或 UDP 通信时,会广泛用到套接字的 API,使用这套 API 设置 IP 地址、端口号,实现数据的发送和接收。

                套接字在OSI和TCP/IP模型中的位置对比
                
                OSI七层模型                TCP/IP四层模型
                +---------------+          +---------------+
                |    应用层     |          |               |
                |   表示层      |  ------> |    应用层      |
                |   会话层      |          |               |
                +---------------+          +---------------+
                        ↑                         ↑
                        |                         |
                   Socket接口                 Socket接口
                        |                         |
                        ↓                         ↓
                +---------------+          +---------------+
                |   传输层      |  ------> |    传输层      |
                +---------------+          +---------------+
                |   网络层      |  ------> |    网络层      |
                +---------------+          +---------------+
                |   数据链路层   |          |               |
                |   物理层      |  ------> |   网络接口层   |
                +---------------+          +---------------+

套接字类型

套接字的主要类型有三种,下面我们分别介绍一下

  • 数据报套接字(Datagram sockets):数据报套接字提供一种无连接的服务,而且并不能保证数据传输的可靠性。数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据报套接字使用UDP( User DatagramProtocol)协议进行数据的传输。由于数据报套接字不能保证数据传输的可靠性,对于有可能出现的数据丢失情况,需要在程序中做相应的处理。
  • 流套接字(Stream sockets):流套接字用于提供面向连接、可靠的数据传输服务。能够保证数据的可靠性、顺序性。流套接字之所以能够实现可靠的数据服务,原因在于其使用了传输控制协议,即 TCP(The Transmission Control Protocol)协议
  • 原始套接字(Raw sockets): 原始套接字允许直接发送和接收 IP 数据包,而无需任何特定于协议的传输层格式,原始套接字可以读写内核没有处理过的 IP 数据包。

套接字使用

现在我们知道了, Socket 和 TCP/IP 没有必然联系,Socket 的出现只是方便了 TCP/IP 的使用,如何方便使用呢?你可以直接使用下面 Socket API 的这些方法。

方法

描述

create()

创建一个 socket

bind()

套接字标识,一般用于绑定端口号

listen()

准备接收连接

connect()

准备充当发送者

accept()

准备作为接收者

write()

发送数据

read()

接收数据

close()

关闭连接

套接字处理过程

虽然套接字 API 位于应⽤程序层和传输层之间的通信模型中,但是套接字 API 不属于通信模型。套接字 API 允许应⽤程序与传输层和⽹络层进⾏交互。

在往下继续聊之前,我们先播放⼀个⼩插曲,简单聊⼀聊 IP。

【补充】聊聊 IP

【传输层】端口号

网络编程套接字(Socket)_scoket编程中ipv4长度宏-CSDN博客

端口(port)是伴随着传输层诞生的概念。它可以将网络层的IP通信分送到各个通信通道。UDP协议和TCP协议尽管在工作方式上有很大的不同,但它们都建立了从一个端口到另一个端口的通信。

端口号定义:

  • 端口号是传输层的概念
  • 端口号是一个2字节/16位的整数
  • 端口号用来标识主机上唯一一个网络进程,公网IP标识互联网上唯一的主机。
    • 端口号用来标识一个进程,用来告诉OS,将数据交给哪一个进程
  • 端口号+IP地址可以标识互联网上唯一一个网络进程
    • IP地址+端口号可以唯一的表示网络中一个主机的某一个进程
  • 一个端口号只能被一个进程占用

PS:

  • 一台主机与另一台主机通信是进程间通信的另一种方式。

端口号和进程 ID:

一个进程PID也可以唯一的标识一个进程,那为什么还需要使用端口号来标识一个主机中的进程呢?

  • 当一个进程退出时,在次启动进程时,它的PID已经变化。所以要将进程和端口号绑定来标识这个进程
  • 一个进程可以绑定多个端口号,但是一个端口号只能被一个进程绑定

源端口号和目标端口号:

传输层协议TCP/UDP数据段中,也存在两个字段,一个是源端口号,一个是目的端口号,它用来表示这个数据是哪一个进程发的,要发给哪一个进程,也就是谁发的要发给谁

学习传输层协议之前,再谈端口号:

在网络编程套接字(Socket)_scoket编程中ipv4长度宏-CSDN博客中谈到端口号标识了一个主机上进行通信的不同应用程序

TCP/IP协议中, 用"源IP", "源端口号", "目的IP", "目的端口号", "协议号" 这样一个五元组来标识一个通信。

可以通过 netstat -n查看,协议号指的是那个使用协议

一个进程可以绑定多个端口号,但是一个端口号不能被多个进程绑定。

  • TCP 如何判断是哪个端口的呢?

端口号范围划分:

端⼝号是 16 位的⾮负整数,它的范围是 0 - 65535 之间,这个范围会分为三种不同的端⼝号段,由 Internet 号码分配机构 IANA 进⾏分配

  • 0 - 1023: 知名端口号,HTTP、FTP、 SSH等这些广为使用的应用层协议他们的端口号都是固定的,自己写的程序中,不能随意绑定知名端口号。
  • 1024 - 65535:操作系统动态分配的端口号。 客户端程序的端口号,就是由操作系统从这个范围分配的。
    • 注册端⼝号,范围是 1024 - 49151
    • 私有端⼝号,范围是 49152 - 6553

常见的知名端口号

  • ssh服务器:22端口
  • ftp服务器:21端口
  • http服务器:80端口
  • telnet服务器:23端口
  • https服务器:443端口
  • MYSQL服务器:3306端口

PS:

  • 在Linux操作系统中使用命令cat /etc/services可以看到所有的知名端口。

应用程序&&端口号:

⼀台计算机上可以运⾏多个应⽤程序,当⼀个报⽂段到达主机后,应该传输给哪个应⽤程序呢?你怎么知道这个报⽂段就是传递给 HTTP 服务器⽽不是 SSH 服务器的呢?

是凭借端⼝号吗?当报⽂到达服务器时,是端⼝号来区分不同应⽤程序的,所以应该借助端⼝号来区分。

举个例⼦反驳⼀下 cxuan,假如到达服务器的两条数据都是由 80 端⼝发出的你该如何区分呢?或者说到达服务器的两条数据端⼝⼀样,协议不同,该如何区分呢?

所以仅凭端⼝号来确定某⼀条报⽂显然是不够的。

互联⽹上⼀般使⽤ 源 IP 地址、⽬标 IP 地址、源端⼝号、⽬标端⼝号、协议类型 这个五元组来进⾏区分。如果其中的某⼀项不同,就被认为是不同的报⽂段。这些也是多路分解和多路复⽤的基础。

确定端口号:

在实际通信之前,需要先确定⼀下端⼝号,确定端⼝号的⽅法分为两种:

  • 标准既定的端⼝号

标准既定的端⼝号是静态分配的,每个程序都会有⾃⼰的端⼝号,每个端⼝号都有不同的⽤途。端⼝号是⼀个 16⽐特的数,其⼤⼩在 0 - 65535 之间, 0 - 1023 范围内的端⼝号都是动态分配的既定端⼝号,例如 HTTP 使⽤ 80端⼝来标识, FTP 使⽤ 21 端⼝来标识, SSH 使⽤ 22 来标识。这类端⼝号有⼀个特殊的名字,叫做 周知端⼝号(Well-Known Port Number) 。

  • 时序分配的端⼝号

时序分配是⼀种动态分配的⽅式,它是由操作系统来进⾏分配端⼝号,能够保证不同应⽤程序使⽤不同的端⼝号。它的范围是从 1024 - 65535。

【补充】网络状态、进程查看工具:

netstat工具: 用来查看网络状态。

  • n 拒绝显示别名,能显示数字的全部转化成数字
  • l 仅列出有在Listen (监听)的服务状态
  • p 显示正在使用Socket的程序识别码和程序名称
  • t (tcp)仅显示tcp相关选项
  • u u (udp)仅显示udp相关选项
  • a (all)显示所有选项,默认不显示LISTEN相关

pidof [进程名]: 可以根据进程名直接查看服务器的进程id。例如:pidof sshd

【通信系统】多路复用和多路分解

多路复用(Multiplexing)

多路复用是一种技术,允许同时传输多个信号或数据流通过同一条通信信道。它通过不同的方法将多个信号合并成一个复合信号,以便在传输过程中共享资源。
主要方法:

  1. 频分复用(FDM):将不同的信号分配到不同的频率带宽上。
  2. 时分复用(TDM):按时间分割信道,每个信号占用不同的时间片。
  3. 码分复用(CDM):使用不同的编码区分信号。
  4. 波分复用(WDM):在光纤通信中,利用不同波长的光信号传输多个数据流。

多路分解(Demultiplexing)

多路分解是多路复用的逆过程,即接收端将复合信号分离回原来的各个独立信号。
主要方法:

  1. 频分多路分解:通过滤波器分离不同频率的信号。
  2. 时分多路分解:根据时间片分离信号。
  3. 码分多路分解:使用解码技术分离信号。
  4. 波分多路分解:通过分光器分离不同波长的光信号。

多路复用和多路分解在计算机网络中的应用

传输层通过多路复用和多路分解,利用端口号管理数据流,确保多个应用同时高效通信。这不仅提高了带宽利用率,还简化了网络结构,支持复杂的网络应用场景,如视频会议、在线游戏等,保障数据的准确传输。

  • 传输层&&多路复用

其实就是本来就只有一条传输通道(在同一个 IP),但是一条通道的带宽是不完全占用满的,所以加入了端口号的概念(对数据包进行分组),实现多进程/通道数据传输;

  • 传输层&&多路分解

其实就是把上面的端口号+IP 解包,给到不同的进程

多路复用(Multiplexing)在传输层的作用

  1. 定义:多路复用允许同时传输多个数据流,通过单一的物理或逻辑连接,提升带宽利用率。
  2. 实现方式
    • 端口号:传输层使用端口号区分不同应用的数据流。例如,HTTP使用80端口,FTP使用20和21端口。
    • TCP和UDP:这两种协议处理多路复用,TCP通过端口号管理可靠连接,UDP则快速传输数据包,同样依赖端口号区分。
  1. 应用场景:当设备同时运行多个程序(如浏览器、邮件客户端、FTP客户端)时,传输层利用端口号封装数据包,确保各应用的数据不会混淆。

多路分解(Demultiplexing)在传输层的作用

  1. 定义:多路分解是接收端根据特定标识符(如端口号)将复合数据流分离到正确应用的过程。
  2. 实现方式
    • 端口号匹配:接收方传输层检查数据包的端口号,将其分配给对应的进程或应用。
    • 套接字管理:每个连接由套接字(IP地址+端口号)唯一标识,确保数据正确分发。
  1. 应用场景:接收方的传输层拆分复合数据流,确保每个数据包到达正确的目的进程,如HTTP请求分发到Web服务器,FTP数据分发到文件传输应用。

传输层多路复用与分解的优势

  • 高效带宽利用:允许多个应用共享网络连接,提升效率。
  • 简化网络结构:无需为每个应用单独建立物理连接,减少网络复杂性。
  • 支持并发处理:服务器可同时处理多个客户端连接,每个连接由唯一的端口号管理。

【计算机网络】多路复用和多路分解

我们上面聊到了在主机上的每个套接字都会分配一个端口号,当报文段到达主机时,运输层会检查报文段中的目的端口号,并将其定向到相应的套接字,然后报文段中的数据通过套接字进入其所连接的进程。

下面我们来聊一下什么是多路复用和多路分解的概念。

多路复用和多路分解分为两种,即无连接的多路复用/多路分解和面向连接的多路复用/多路分解

多路复用和多路分解是通信系统中的两个基本概念,用于提高资源利用效率和信号传输的灵活性。

无连接的多路复用和多路分解

开发人员会编写代码确定端口号是周知端口号还是时序分配的端口号。

假如主机 A 中的一个 10637 端口要向主机 B 中的 45438 端口发送数据,运输层采用的是 UDP 协议,数据在应用层产生后,会在运输层中加工处理,然后在网络层将数据封装得到 IP 数据报,IP 数据包通过链路层交付给主机 B,主机 B 会检查报文段中的端口号判断是哪个套接字的,这一系列的过程如下所示

UDP 套接字就是一个二元组,二元组包含目的 IP 地址和目的端口号。

所以,如果两个 UDP 报文段有不同的源 IP 地址和/或相同的源端口号,但是具有相同的目的 IP 地址和目的端口号,那么这两个报文会通过套接字定位到相同的目的进程。

这里思考一个问题,主机 A 给主机 B 发送一个消息,为什么还需要知道源端口号呢?

比如我给妹子表达出我对你有点意思的信息,妹子还需要知道这个信息是从我的哪个器官发出的吗?知道是我这个人对你有点意思不就完了?实际上是需要的,因为妹子如果要表达出她对你也有点意思,她是不是可能会亲你一口,那她得知道往哪亲吧?

这就是,在 A 到 B 的报文段中,源端口号会作为返回地址的一部分,即当 B 需要回发一个报文段给 A 时,B 需要从 A 到 B 中的源端口号取值,如下图所示

面向连接的多路复用与多路分解

如果说无连接的多路复用和多路分解指的是 UDP 的话,那么面向连接的多路复用与多路分解指的是 TCP 了,TCP 和 UDP 在报文结构上的差别是,UDP 是一个二元组而 TCP 是一个四元组,即源 IP 地址、目标 IP 地址、源端口号、目标端口号 ,这个我们上面也提到了。当一个 TCP 报文段从网络到达一台主机时,这个主机会根据这四个值拆解到对应的套接字上。

上图显示了面向连接的多路复用和多路分解的过程,图中主机 C 向主机 B 发起了两个 HTTP 请求,主机 A 向主机 C 发起了一个 HTTP 请求,主机 A、B、C 都有自己唯一的 IP 地址,当主机 C 发出 HTTP 请求后,主机 B 能够分解这两个 HTTP 连接,因为主机 C 发出请求的两个源端口号不同,所以对于主机 B 来说,这是两条请求,主机 B 能够进行分解。对于主机 A 和主机 C 来说,这两个主机有不同的 IP 地址,所以对于主机 B 来说,也能够进行分解。

【计算机网络】网络字节序(大小端)

内存中大于1个字节的数据相对于内存地址存在大小端之分,磁盘文件中多字节数据相对于偏移地址也存在大小端之分,网络中的数据流也存在大小端之分。

什么是大小端之分?

单独总结我的另一篇博客:数据存储大小端解析-CSDN博客

网络字节流的大小端:

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

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

#include <arpa/inet.h>
//h--host主机,n--net网络,l--long长整型32位,s--short短整型16位
uint32_t htonl(uint32_t hostlong);//主机-->网络(32位)
uint16_t htons(uint16_t hostshort);//主机-->网络(16位)
uint32_t ntohl(uint32_t netlong);//网络-->主机(32位)
uint16_t ntohs(uint16_t netshort);//网络-->主机(16位)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【五.LangChain技术与应用】【31.LangChain ReAct Agent:反应式智能代理的实现】

一、ReAct Agent是啥?为什么说它比「普通AI」聪明? 想象一下,你让ChatGPT查快递物流,它可能直接编个假单号糊弄你。但换成ReAct Agent,它会先推理(Reasoning)需要调用哪个接口,再行动(Action)查询真实数据——这就是ReAct的核心:让AI学会「动脑子」再动手。 举个真…

软件信息安全性测试流程有哪些?专业软件测评服务机构分享

在数字化时代&#xff0c;软件信息安全性测试的重要性愈发凸显。尤其是对于企业来说&#xff0c;确保软件的安全性不仅是维护用户信任的关键&#xff0c;也是满足合规要求的必要条件。 软件信息安全性测试是指通过一系列系统化的测试手段&#xff0c;评估软件应用在受到攻击时…

SparkAi系统体验

DeepSeek-R1-671B大模型满血版私有化部署高可用教程-SparkAi系统集成图文教程 一、SparkAI是什么二、功能模块介绍系统快速体验 三、系统功能模块3.1 AI全模型支持/插件系统3.2 AI智能体应用3.3 AI专业绘画3.4 AI视频生成3.5 Dall-E2/E3/E4绘画3.6 智能思维导图生成3.7 AI绘画广…

Cursor如何调试.Net Core控制台程序

1.背景 在Cursor下调试.Net Core控制台程序会出现下面的问题&#xff1a; 因为Cursor是VS Code的变种版本&#xff0c;并不被官方的调试机制支持去使用。基于这种情况&#xff0c;就产生了本文。 2.解决方法 使用三星电子的开源调试工具netcoredbg&#xff0c;就能解决这个问…

记一次ScopeSentry搭建

介绍 Scope Sentry是一款具有资产测绘、子域名枚举、信息泄露检测、漏洞扫描、目录扫描、子域名接管、爬虫、页面监控功能的工具&#xff0c;通过构建多个节点&#xff0c;自由选择节点运行扫描任务。当出现新漏洞时可以快速排查关注资产是否存在相关组件。 目前功能 插件系…

Aws batch task 无法拉取ECR 镜像unable to pull secrets or registry auth 问题排查

AWS batch task使用了自定义镜像&#xff0c;在提作业后出现错误 具体错误是ResourceInitializationError: unable to pull secrets or registry auth: The task cannot pull registry auth from Amazon ECR: There is a connection issue between the task and Amazon ECR. C…

GPT 4.5 可能是戳破 AI 泡沫的模型

GPT 4.5 可能是戳破 AI 泡沫的模型 Andrew Zuo 本文点评&#xff1a;在AI技术狂飙突进的同时&#xff0c;也有许多声音包括本文的作者在内都认为AI行业正陷入巨大泡沫&#xff0c;技术突破逐渐停滞&#xff0c;高昂的硬件成本与资本退潮或将引爆寒冬。然而&#xff0c;这些观点…

【Linux内核系列】:进入文件系统的世界

&#x1f525; 本文专栏&#xff1a;Linux &#x1f338;作者主页&#xff1a;努力努力再努力wz 那么从本篇文章开始就要进入文件系统的学习了&#xff0c;那么之前的内容主要围绕的是进程的相关概念以及进程控制有关的系统调用接口的介绍&#xff0c;以及最后结合之前所学的知…

CentOS 7.9 安装 ClickHouse 文档

1. 环境准备 确保系统为 CentOS 7.9&#xff0c;并已安装 Docker。如果未安装 Docker&#xff0c;请先安装 Docker。 安装 Docker # 卸载旧版本 Docker&#xff08;如果有&#xff09; sudo yum remove -y docker docker-client docker-client-latest docker-common docker-…

(链表 删除链表的倒数第N个结点)leetcode 19

设空结点指向head便于插入和删除结点 考虑特殊情况 head结点被删除 a结点仅用来测试长度&#xff0c;找到目标结点的位置 b结点为空结点指向head返回值 cur用来删除目标值&#xff08;特殊情况 目标值为head 这时curb) 则开始就将cur初始化为b开始遍历 /*** Definition fo…

电力杆塔倾斜监测装置:守护电网安全的智能卫士

​ ​电力杆塔作为电力传输的重要支撑结构&#xff0c;其安全性直接关系到电网的稳定运行和电力供应的可靠性。然而&#xff0c;由于自然环境的复杂性和外部因素的影响&#xff0c;杆塔倾斜、倒塌等问题时有发生&#xff0c;给电力系统带来了巨大的安全隐患。为了应对这一挑…

【单片机项目】电源如何扩展、电源模块、电池模块如何接线

一、前言 解决2个关键问题&#xff1a; 【1】如果项目编号小于172之前的项目。 可能会遇到电源模块不够接&#xff0c;需要扩展电源的问题。 【2】如果项目编号是大于 172之后项目&#xff0c;部分项目用到了稳压电源模块或者是电池模块。 这篇文章单独讲解一下如何接线。 …

NO.28十六届蓝桥杯备战|string|insert|find|substr|关系运算|stoi|stol|stod|stof|to_string(C++)

insert 如果我们需要在字符串中间的某个位置插⼊⼀个字符串&#xff0c;得掌握⼀个函数就是insert string& insert (size_t pos, const string& str); //pos位置前⾯插⼊⼀个string字符串 string& insert (size_t pos, const char* s); //pos位置前⾯插⼊⼀个…

贪心算法一

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;了解什么是贪心算法&#xff0c;并且掌握贪心算法。 > 毒鸡汤&#xff1a;有些事情&#xff0c;总是不明白&#xff0c;所以我不会坚持。早安! >…

逐梦DBA:MySQL的编码设置

一、MySQL的编码设置 1.1 默认插入中文数据存在的问题 1.1.1 在 MySQL5.7 版本&#xff0c;默认在安装成功后存在中文乱码的问题 1. 通过 show create table xxx查看可以发现默认的字符集&#xff1a; 2. show variables like character_%;查看编码命令发现默认为拉丁 如果我…

Windows 图形显示驱动开发-WDDM 3.2-GPU-P 设备上的实时迁移(一)

本文介绍了通过 SR-IOV(单根 I/O 虚拟化)分区虚拟化的异构计算设备(GPU、NPU 等)实时迁移的功能设计。 通过 WDDM 和 MCDM 驱动程序模型支持分区的设备现已成为我们虚拟化产品不可或缺的一部分。 因此&#xff0c;必须支持实时迁移并帮助我们的虚拟化抽象实现最大程度的可靠性&…

张驰咨询:用六西格玛重构动力电池行业的BOM成本逻辑

在动力电池行业&#xff0c;BOM&#xff08;物料清单&#xff09;成本每降低1%&#xff0c;都可能改写企业的利润曲线。某头部企业的三元锂电池BOM成本曾较行业标杆高出11%&#xff0c;单电芯利润率被压缩至3%的生死线。然而&#xff0c;通过张驰咨询的六西格玛方法论&#xff…

Java 大视界 -- Java 大数据在智能政务公共服务资源优化配置中的应用(118)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

单例模式的五种实现方式

1、饿汉式 ①实现&#xff1a;在类加载的时候就初始化实例 ②优点&#xff1a;线程安全 ③缺点&#xff1a;实例在类加载的时候创建&#xff0c;可能会浪费资源 //饿汉式 public class EagerSingleton{private EagerSingleton(){} //私有构造方法private static EagerSingle…

WPS工具栏添加Mathtype加载项

问题描述&#xff1a; 分别安装好WPS和MathType之后&#xff0c;WPS工具栏没直接显示MathType工具&#xff0c;或者是前期使用正常&#xff0c;由于WPS更新之后MathType工具消失&#xff0c;如下图 解决办法 将文件“MathType Commands 2016.dotm”和“MathPage.wll”从Matht…