Linux网络 —— 网络基础概念
- 计算机网络背景
- 网络发展
- 初始协议
- 协议分层
- 协议分层的好处
- OSI七层模型
- TCP/IP五层(或四层)模型
- 再识协议
- 为什么要有TCP/IP协议?
- 什么是TCP/IP协议?
- TCP/IP协议与操作系统的关系
- 所以究竟什么是协议?
- 网络传输基本流程
- 局域网网络传输流程图
- 局域网(以太网为例)通信原理
- 认识MAC地址
- 数据包封装和分用
- 跨网络传输流程图
- 网络中的地址管理-认识IP地址
- IP地址与MAC地址的区别
- Socket编程准备
- 1. 理解源IP地址和目的IP地址
- 2. 认识端口号
- 端口号范围划分
- 理解"端口号"和"进程ID"
- 理解socket
- 3. 传输层的典型代表
- 认识TCP协议
- 认识UDP协议
- 4. 网络字节序
- 5. socket编程接口
- socket常见API
- sockaddr结构
计算机网络背景
网络发展
计算机网络的发展历程是一个复杂而多样的过程,涉及多个阶段和技术进步。经历了从独立模式到网络互联的转变,为了更好的工作,提高工作效率,自然出现了信息的交流,从本地的交流再到网络的信息传输,可以说网络的出现是一个必然的结果。
独立模式:
在早期计算机发展阶段,计算机之间是相互独立的,通常只有一台主机与多个终端连接。这种模式下,终端设备无法进行独立运算,只能依赖于主机进行数据处理。这一时期的网络基本上是以主机为中心,用户通过终端访问主机资源,形成了最初的计算机通信网络。
网络互联:
随着计算机技术的进步,尤其是分组交换技术的出现,计算机之间开始实现互联。这一阶段标志着 “计算机-计算机” 网络的形成,使得多台计算机能够相互连接,共享数据和资源。网络互联不仅提高了资源利用率,还推动了信息共享和协作工作的发展。
局域网(LAN)
局域网(LAN) 是指在有限地理范围内(如办公室或校园)连接多台计算机的网络。通过交换机和路由器,这些计算机可以实现高效的数据传输和资源共享。局域网的出现极大地提高了数据传输速度和网络管理效率,使得企业和组织能够更好地进行内部沟通与协作。
广域网(WAN)
广域网(WAN) 则是将地理上相隔较远的计算机连接在一起,通常涵盖城市、国家甚至全球范围。广域网通过各种通信技术(如光纤、卫星等)实现长距离的数据传输。 它使得同地点的用户能够方便地共享信息和资源,是现代互联网的重要基础设施。
局域网与广域网的互补关系
局域网与广域网 之间可以被视为一种包含关系:多个局域网可以组成一个广域网。局域网提供了快速、低延迟的数据传输,而广域网则扩展了网络的覆盖范围,使得不同地点的用户能够互联互通。这种结构使得企业能够在本地高效工作,同时又能通过广域网实现远程协作。
总之,计算机作为人类工作的重要工具,其发展必然推动了网络技术的进步。随着人们对信息共享和协同工作的需求增加,网络的产生与发展成为一种必然趋势。无论是局域网还是广域网,都在不断促进人们之间的信息交流与合作,从而推动社会各个领域的发展。
初始协议
协议的基本概念
协议是一种约定,规定了在通信过程中各方应遵循的规则和标准。它类似于语言的约定,不同的设备和系统需要使用相同的“语言”来进行有效的通信。这些约定包括数据格式、传输方式、错误处理机制等。
例如:计算机之间的传输媒介是光信号和电信号,通过"频率"和"强弱"来表示0
和1
这样的信息·要想传递各种不同的信息,就需要约定好双方的数据格式。
只要通信的两台主机,约定好协议就可以了么?
定好协议,但是你用频率表示
01
,我用强弱表示01
,就好比我用中国话,你用葡萄牙语一样,虽然大家可能遵守的一套通信规则,但是语言不同,即是订好了基本的协议,也是无法正常通信的。
所以,完善的协议,需要更多更细致的规定,并让参与的人都要遵守。
要想让参与的人都遵守协议,得面临一下几个问题:
- 计算机生产厂商有很多
- 计算机的操作系统也有很多
- 计算机网络硬件设备,也是有很多
并且要想做到网络的通信,以上都得做到大统一,那如何让这些不同厂商之间生产的计算机能够互相顺畅的通信呢?这时候就需要有人来站出来,约定一个共同的标准,并且让大家都来遵守,这就是:网络协议!
一般具有定制协议或者标准的资格的组织或者公司都必须是业界公认或者具有江湖地位的组织或者公司。
以下结果来源于对文心一言的提问:
问:能定制协议标准的组织或者公司
- 国际标准化组织:
- IEEE(电气和电子工程师协会):这是一个由计算机和工程领域专家组成
的庞大技术组织,在通信协议领域贡献突出。IEEE 制定了全世界电子、电气和计算机科学领域30%左右的标准,包括IEEE 802 系列标准,这些标准涵盖了从局域网(LAN)到广域网(WAN)等多种网络技术。- ISO(国际标准化组织):ISO 是由多个国家的标准化团体组成的国际组
织,它在开放系统互连(OSI)模型方面的工作尤为著名。OSI 模型定义了网络通信的七层协议结构,尽管在实际应用中,TCP/IP 协议族更为普遍,但OSI 模型仍然在学术和理论研究中占有重要地位。- ITU(国际电信联盟):ITU 是联合国下属的专门机构,负责制定电信领域
的国际标准。ITU-T 制定的标准涵盖了电话和网络通信,与ISO 合作确保了通信
技术的全球兼容性和互操作性。- 区域标准化组织:
- ETSI(欧洲电信标准学会):由欧洲共同体各国政府资助,是一个由电信
行业的厂商与研究机构参加并从事研究开发到标准制定的组织。- ASTAP(亚洲与泛太平洋电信标准化协会):1998年由日本与韩国发起成
立的标准化组织,旨在加强亚洲与太平洋地区各国信息通信基础设施及其相互连
接的标准化工作的协作。- 公司:
- 某些公司,如泰凌微,也自研各种标准的软件协议栈,包括低功耗蓝牙、
zigbee、thread 及Matter等,并可进行定制化改动,这是其核心竞争力之一。泰
凌微还计划重点发展智能电子价签、智能遥控、智能家居等市场。- 民间国际团体:
- IETF(互联网工程师任务组):这是一个负责开发和推广互联网协议(特别
是构成TCP/IP协议族的协议)的志愿组织,通过 RFC 发布新的或者取代老的协议标准。- 官方机构:
- FCC(联邦通信委员会):美国对通信技术的管理的官方机构,主要职责是
通过对无线电、电视和有线通信的管理来保护公众利益。也对包括标准化在内的
通信产品技术特性进行审查和监督。
以上这些组织或公司都能在一定程度上定制协议标准,以满足特定需求或推动技术发
展。(了解即可)
协议分层
协议本质也是软件,在设计上为了更好的进行模块化,解耦合,也是被设计成为层状结构的。
协议分层的好处
- 在上图这个例子中,“协议” 只包含了两层,即 “语言层” , “通信设备层” 。
- 不同协议栈的同一协议层都是直接沟通的, 也就是说比如语言层的沟通不受通信设备层的影响!
- 所以,也就是说设计上本身就是为了更好的模块化,当作软件来处理,低耦合的设计保证了不同协议层的独立,故设计为层状结构!
OSI七层模型
OSl(OpenSystemInterconnection) 七层模型是 国际标准化组织(ISO) 提出的一个概念性的网络框架,是一个逻辑上的定义和规范。用于定义计算机网络中不同功能层次的通信标准。 该模型将网络通信过程划分为七个逻辑层次,每一层都有相对应的协议和物理设备,比如路由器,交换机 ,并通过接口与上下层进行交互。
OSI七层模型是一种框架性的设计方法,其最主要的功能使就是帮助不同类型的主机实现数据传输。
OSI七层模型 它的最大优点是将服务
、接口
和 协议
这三个概念明确地区分开来,概念清楚理论也比较完整.通过七个层次化的结构模型使不同的系统不同的网络之间实现可靠的通讯。
但是在实际操作的过程中,会话层、表示层是不可能接入到操作系统中的,所以在工程实践中,最终落地的是5
层协议,又因为复杂又不实用,所以我们按照TCP/IP 四层模型来讲解。
TCP/IP五层(或四层)模型
TCP/IP
是一组协议的代名词,它还包括许多协议,组成了TCP/IP
协议簇。
TCP/IP
通讯协议采用了5
层的层级结构,每一层都呼叫它的下一层所提供的网络来完成自己的需求。
- 物理层: 负责光/电信号的传递方式。 比如现在以太网通用的网线(双绞线)、早
期以太网采用的的同轴电缆(现在主要用于有线电视)、光纤, 现在的wifi 无线网使用电磁波等都属于物理层的概念。物理层的能力决定了最大传输速率、传输距离、抗干扰性等. 集线器(Hub)工作在物理层。 - 数据链路层: 负责设备之间的数据帧的传送和识别. 例如网卡设备的驱动、帧同步(就是说从网线上检测到什么信号算作新帧的开始)、冲突检测(如果检测到冲突就自动重发)、数据差错校验等工作. 有以太网、令牌环网, 无线LAN 等标准. 交换机(Switch)工作在数据链路层.
- 网络层: 负责地址管理和路由选择. 例如在IP 协议中, 通过IP 地址来标识一台
主机, 并通过路由表的方式规划出两台主机之间的数据传输的线路(路由)。路由器
(Router)工作在网路层。 - 传输层: 负责两台主机之间的数据传输。 如传输控制协议(TCP), 能够确保数据
可靠的从源主机发送到目标主机。 - 应用层: 负责应用程序间沟通。如简单电子邮件传输(SMTP)、文件传输协
议(FTP)、网络远程访问协议(Telnet)等. 我们的网络编程主要就是针对应用层.
物理层我们考虑的比较少,我们只考虑软件相关的内容. 因此很多时候我们直接称为
TCP/IP
四层模型.
- 对于一台主机,它的操作系统内核实现了从传输层到物理层的内容;
- 对于一台路由器,它实现了从网络层到物理层
- 对于一台交换机,它实现了从数据链路层到物理层;
- 对于集线器,它只实现了物理层;
但是并不绝对.很多交换机也实现了网络层的转发;很多路由器也实现了部分传输层的
内容(比如端口转发);
再识协议
为什么要有TCP/IP协议?
首先,我们应该知道即便是单机,你的计算机内部,其实都是存在协议的,比如:其他设备和内存通信,会有内存协议。其他设备和磁盘通信,会有磁盘相关的协议,比如:SATA,IDE,SCSI 等。只不过我们感知不到罢了。而且这些协议都在本地主机各自的硬件中,通信的成本低、问题比较少。
其次,网络通信最大的特点就是主机之间变远了。任何通信特征的变化,一定会带来新的问题,有问题就得解决问题,所以需要新的协议咯。
TCP/IP
协议的存在是为了应对计算机通信中日益增长的复杂性和远程通信需求。随着计算机和网络的普及,通信主机之间的距离不断增大,单纯依靠简单的通信约定已无法满足实际需求。综上所述,
TCP/IP
协议的设计与实现是为了应对计算机通信距离增加带来的挑战,确保不同设备之间能够高效、可靠地进行数据交换,从而推动了互联网及其他网络技术的发展。
什么是TCP/IP协议?
TCP/IP 协议的本质是一种解决方案
TCP/IP协议(Transmission Control Protocol/Internet Protocol) 是一组用于计算机网络通信的协议,构成了互联网的基础。它定义了数据在网络中如何被分割、传输和重组,并确保不同设备之间能够有效地进行信息交换。TCP/IP
协议通常分为四个层次:应用层、传输层、网络层和链路层,每一层都负责特定的功能,协同工作以实现端到端的数据传输。通过这一协议,设备能够在全球范围内互联互通,支持各种类型的网络应用。
TCP/IP协议与操作系统的关系
TCP/IP
协议栈通常作为操作系统内核的一部分实现, 为上层应用程序提供网络通信功能。操作系统内核中包含了完整的TCP/IP协议栈
,负责处理数据的发送和接收。
具体来说,TCP/IP
协议栈在操作系统内核中包括以下几个关键组件:
- Socket接口: 操作系统提供
Socket
编程接口,应用程序通过调用这些接口来使用TCP/IP
协议进行网络通信。Socket
作为应用层与传输层之间的桥梁,屏蔽了TCP/IP
协议的复杂性。 - 网络协议模块: 内核中包含了
TCP
、UDP
、IP
等网络协议的实现模块。这些模块负责数据包的分段、重组、寻址、路由选择等功能,确保数据能够在网络中正确传输。 - 网络驱动程序: 操作系统还包含了网络接口卡(NIC)的设备驱动程序。这些驱动程序处理物理层和数据链路层的通信细节,与网络硬件进行交互,实现数据的物理传输。
通过在操作系统内核中实现TCP/IP
协议栈,不同应用程序都可以基于统一的Socket
接口使用网络通信功能。这种设计使得应用程序开发更加简单和高效。
TCP/IP
协议栈的另一个重要作用是使得不同主机之间能够进行通信。 ,主要由下面几个方面实现:
-
统一的协议标准:
TCP/IP
协议族定义了一套统一的通信标准,包括数据格式、寻址方式、传输机制等。只要遵循这些标准,不同厂商生产的主机和设备就能够相互通信。 -
IP地址寻址:
TCP/IP
协议使用IP
地址对主机进行寻址。每个主机都有一个唯一的IP地址,通过这个地址就能够在网络中找到目标主机。IP
地址的分层结构使得路由选择变得更加高效。 -
分层协议栈:
TCP/IP
协议采用分层的设计, 每一层都有特定的功能和协议。这种分层结构使得不同层次之间的通信变得更加简单,也提高了系统的灵活性和可扩展性。 -
端到端的可靠传输:
TCP
协议提供了可靠的端到端数据传输服务,包括流量控制、重传机制、拥塞控制等功能。即使在不可靠的网络环境中,TCP
也能够确保数据的完整性和正确性。
所以究竟什么是协议?
在计算机网络中,协议的本质是通信双方所共同理解并遵循的结构化数据类型。 这种结构化的数据类型定义了信息的格式和传输规则,确保了数据能够在不同的系统和设备之间有效地交换。协议栈的分层设计使得每一层都可以独立定义自己的协议,同时又能够与相邻层进行交互。
因为协议栈是分层的,所以每一层都有其特定的协议,这些协议允许同层之间的实体互相识别和理解对方所使用的协议。例如,在传输层,TCP
和 UDP
分别定义了不同的数据传输方式,但它们都遵循同一层次的标准,使得在这一层的通信能够顺利进行。各层之间通过添加或剥离协议头(报头)来实现数据的封装和解封装,从而确保数据在发送和接收过程中保持一致性。
什么是协议头
协议头是附加在数据包前面的信息部分,用于提供网络通信中的控制和管理信息。它包含了源地址、目的地址、序列号、校验和等字段,这些信息对于数据的正确传输至关重要。协议头的存在使得接收方能够理解如何处理接收到的数据,以及如何与发送方进行有效的通信。在分层协议栈中,每一层都有自己的协议头,确保不同层次之间能够顺利地进行信息交换和数据封装。
假设在网络协议栈的每一层都定义下面这个结构体:
struct protocol {
int a;
int b;
int c;
};
struct protocol data = {10, 20, 30};
这个结构体定义了一种特定的数据格式,通信双方在同一层(例如传输层)约定使用这个结构体作为数据交换的格式。当一台主机发送这个结构体时,它会在协议栈中经过各个层,最终被封装成适合网络传输的数据包。 接收方在接收到数据后,会根据相同的协议解析出这个结构体,从而理解其中的信息。
因此,协议的本质在于提供一种标准化的方法,使得不同系统能够在同一通信层次上进行有效沟通,而这种沟通依赖于双方对各自所使用协议的共同理解和遵循。
网络传输基本流程
局域网网络传输流程图
局域网(以太网为例)通信原理
提问:两台主机在同一个局域网,是否能够直接通信呢?
答: 可以!
以太网是一种广泛使用的局域网技术,最初在20世纪70年代开发,旨在连接计算机和其他设备。它通过电缆(如双绞线、光纤或同轴电缆)在局域网内传输数据,并使用特定的协议来管理数据包的发送和接收。
每台主机在局域网上,要有唯一的标识来保证主机的唯一性:mac 地址
认识MAC地址
MAC地址(Media Access Control Address) 是网络设备的唯一标识符,用于在局域网中识别和定位设备。
它由 48位(6字节) 组成,通常以十六进制格式表示,如00:1A:2B:3C:4D:5E
。
MAC地址的前24
位是由IEEE
分配给设备制造商的组织唯一标识符(OUI),后24
位则由制造商自行分配,确保在同一制造商的设备中唯一性。
MAC地址在数据链路层工作,主要用于设备之间的直接通信,帮助网络交换机识别目标设备并转发数据包。每个具有网络接口的设备都配有一个MAC地址,类似于身份证号码,确保在局域网内的唯一性和有效性。
- 在以太网中,任何时刻,只允许一台机器向网络中发送数据,如果有多台同时发送,会发生数据干扰,我们称之为数据碰撞。所有发送数据的主机要进行碰撞检测和碰撞避免。
- 在没有交换机的情况下,一个以太网就是一个碰撞域。
- 局域网通信的过程中,主机对收到的报文确认是否是发给自己的,是通过目标mac 地址判定。
下面试着从系统角度来理解局域网的通信原理:
在同一个网段内的两台主机是如何进行通信的呢?
而其中每层都有协议,所以当我进行上述传输流程的时候,要进行封装和解包。
通信流程:
- 数据封装: 当用户A想要向用户B发送数据时,首先在应用层构建要发送的信息。然后,随着数据逐层向下传递,每一层都会添加相应的协议头(Header),形成数据帧。这一过程称为封装。例如,在传输层,
TCP
协议会添加源端口和目的端口信息,而在网络层,IP
协议会添加源IP
地址和目的IP
地址。在数据链路层,以太网协议会添加源MAC地址
和目的MAC地址
。 - 数据传输: 封装后的数据通过网络接口发送到局域网中。在局域网内,所有设备都可以接收到这个 数据帧 ,但 只有目标主机(用户B) 会检查其目的
MAC
地址是否与自己的MAC
地址匹配。如果匹配,用户B将响应并处理该数据帧。 - 数据解包: 当用户B接收到数据帧后,它会逐层解包,从物理层开始去掉协议头,直到应用层。每一层都会识别并处理相应的协议头信息,以提取出原始的数据内容。这一过程确保了用户B能够正确理解和处理来自用户A的数据。
在这个过程中,值得注意的是,尽管数据在多个层次上进行了封装和解包,但同层之间的通信是直接的。也就是说,用户A的应用层与用户B的应用层之间通过网络传输的数据内容是相同的。 每一层都认为自己在与对方同层的协议进行直接通信,这种设计使得各个协议能够独立工作,同时又能有效协作。
报头部分:就是对应协议层的结构体字段,我们一般叫做报头(协议头)。除了报头,剩下的叫做有效载荷。
所以,报文= 报头+ 有效载荷。
在网络通信中,不同协议层对数据包有不同的称谓:
- 应用层: 在应用层,数据被称为消息(Message),这是用户实际想要传输的信息。
- 传输层: 在传输层,数据被称为段(Segment),此时会添加TCP或UDP头部,包含源端口和目的端口信息。
- 网络层: 在网络层,数据被称为数据报(Datagram),此时会添加IP头部,包含源IP地址和目的IP地址。
- 数据链路层: 在数据链路层,数据被称为帧(Frame),此时会添加源MAC地址和目的MAC地址,以及用于错误检测的帧校验序列(FCS)。
最后,在整体复盘一下:
在网络传输的过程中,数据不是直接发送给对方主机的,而是先要自定向下将数据交付给下层协议,最后由底层发送,然后由对方主机的底层来进行接受,在自底向上进行向上交付。
数据包封装和分用
下图为数据封装的过程:
下图为数据分用的过程:
从今天开始,我们学习任何协议,都要先宏观上建立这样的认识:
- 要学习的协议,是如何做到解包的?只有明确了解包,封包也就能理解
- 要学习的协议,是如何做到将自己的有效载荷,交付给上层协议的?
跨网络传输流程图
网络中的地址管理-认识IP地址
IP 协议
有两个版本, IPv4
和 IPv6
. 我们整个的课程, 凡是提到IP协议
, 没有特殊说明的,默认都是指IPv4
:
IP 地址
是在IP 协议中, 用来标识网络中不同主机的地址;- 对于
IPv4
来说, IP 地址是一个4
字节,32
位的整数; - 我们通常也使用 “点分十进制” 的字符串表示
IP 地址
, 例如192.168.0.1
; 用点分割的每一个数字表示一个字节, 范围是0 - 255;
跨网段的主机的数据传输. 数据从一台计算机到另一台计算机传输过程中要经过一个或多个路由器.
下面是一张示意图:
首先理解一下IP 地址的意义:
IP地址(Internet Protocol Address) 是用于标识网络中每个设备的唯一地址,类似于邮寄地址。它允许设备在互联网上相互通信,确保数据能够准确地从发送方传输到接收方。IP地址有两个主要功能:标识设备和寻址。通过IP地址,网络设备可以确定数据的来源和目的地,从而实现有效的网络通信。
为什么要去目标主机,先要走路由器?
在局域网中,设备之间的通信通常是直接的;但当数据需要从一个网络传输到另一个网络时,就必须通过路由器。路由器的主要功能是根据目的IP地址决定数据包的转发路径。它连接不同的网络,并负责选择最佳路径,将数据从源主机传送到目标主机。没有路由器,数据包无法跨越不同的网络边界,因此无法到达目的地。
目的IP的意义:
目的IP地址是数据包中指定接收方设备的地址。当用户A发送数据到用户B时,目的IP地址指明了数据应发送到哪个设备。路由器和其他网络设备使用这个信息来确定数据包的转发路径。目的IP地址确保了数据能够准确地送达目标主机,并且在整个互联网中,每个设备都必须有一个唯一的IP地址,以便能够正确识别和定位。
下图体现了当数据从一个网络传输到另外一个网络时,IP地址的重要性,其确保了数据能够准确的传送给目标主机,并且得益于IP
的唯一性,以便能够正确识别和定位目标主机。
然后结合封装与解包,体现路由器解包和重新封装的特点:
IP地址与MAC地址的区别
- 定义与作用:
- IP地址是网络层的地址,用于在互联网上唯一标识每个设备,便于数据包在不同网络之间进行路由和传输。它在整个路由过程中保持不变,指示数据包的最终目的地。
- MAC地址是数据链路层的地址,用于在局域网内唯一标识网络接口卡(NIC)。它通常是硬件固定的,虽然可以被修改,但一般情况下在设备制造时就已设定。
- 稳定性:
- IP地址 在数据传输过程中通常保持不变,特别是在同一网络环境中。
- MAC地址 是在局域网内进行通信时使用的,可能会因网络设备的更换或配置而变化。
- 用途:
- 目的IP地址 是进行路径选择的重要依据,帮助路由器决定如何转发数据包。
- MAC地址 则是局域网转发的重要依据,确保数据帧能够在同一局域网内正确送达目标设备。
数据的传输需要经过多个路由器的路由,可以说,Mac地址标记的是下一个路由器的地址,而IP地址则是标记了最终目标的地址!
IP 网络层存在的意义:提供网络虚拟层,让世界的所有网络都是IP 网络,屏蔽最底层网络的差异
Socket编程准备
1. 理解源IP地址和目的IP地址
IP 在网络中,用来标识主机的唯一性
但是这里要思考一个问题:数据传输到主机是目的吗?不是的。因为数据是给人用的。比如:聊天是人在聊天,下载是人在下载,浏览网页是人在浏览?
但是人是怎么看到聊天信息的呢?怎么执行下载任务呢?怎么浏览网页信息呢?通过启动的qq,迅雷,浏览器。
而启动的qq,迅雷,浏览器都是进程。换句话说,进程是人在系统中的代表,只要把数据给进程,人就相当于就拿到了数据。
所以:数据传输到主机不是目的,而是手段。到达主机内部,在交给主机内的进程,才是目的。
但是系统中,同时会存在非常多的进程,当数据到达目标主机之后,怎么转发给目标进程?这就要在网络的背景下,在系统中,标识主机的唯一性,这里需要了解到端口号了。
2. 认识端口号
端口号(port)是传输层协议的内容。
端口号是一个2 字节16 位的整数,端口号用来标识一个进程,告诉操作系统, 当前的这个数据要交给哪一个进程来处理。
IP 地址+ 端口号 能够标识网络上的某一台主机的某一个进程。
一个端口号只能被一个进程占用。
端口号范围划分
0 - 1023
: 知名端口号,HTTP
,FTP
,SSH
等这些广为使用的应用层协议, 他们的
端口号都是固定的。1024 - 65535
: 操作系统动态分配的端口号. 客户端程序的端口号, 就是由操作
系统从这个范围分配的。
理解"端口号"和"进程ID"
端口号 和 进程ID(PID) 都是用于标识计算机系统中不同实体的重要概念,但它们的作用和使用场景有所不同:
- 定义:
- 进程ID (PID): 是操作系统分配给每个运行进程的唯一标识符。每当一个程序被执行时,系统会为其分配一个唯一的PID,以便于管理和跟踪该进程的状态。PID在进程生命周期内保持唯一,但在进程结束后,该PID可能会被回收并分配给新的进程。
- 端口号: 是用于标识网络通信中不同服务或应用程序的接口。每个网络应用程序通常会绑定一个或多个端口号,以便客户端通过这些端口与服务器进行通信。端口号范围从0到65535,其中0到1023为知名端口,通常被系统服务使用。
- 关系:
- 一个网络应用程序通常至少会开放一个端口,以便接收来自客户端的请求。因此,一个端口可以对应一个或多个进程(例如,负载均衡器可能会将请求分发给多个后端服务)。
- 反之,一个进程可以绑定多个端口,特别是在需要同时提供多种服务的情况下。例如,一个Web服务器可以同时监听HTTP(80端口)和HTTPS(443端口)请求。
在网络通信中,使用端口号而不是进程ID(PID)来标识进程有以下几个原因:
- PID只在本地系统内唯一,而端口号在网络范围内唯一。当进程需要跨主机通信时,PID就无法唯一标识远程主机上的进程。端口号可以与IP地址结合,在网络中唯一标识一个进程。
- PID在进程结束后会被回收重用,而端口号在连接结束后会保持一段时间。 这样可以避免端口号被重复使用导致的错误。
- PID通常是操作系统内部使用的,应用程序很少直接使用PID。 而端口号是应用层协议(如TCP/UDP)使用的,应用程序需要绑定和监听特定端口。
- 使用端口号可以将网络通信与进程管理解耦。应用程序只需要绑定端口并处理数据,不需要关心PID。这样设计更加灵活和模块化。
- 端口号的范围足够大(0-65535),可以满足大部分应用程序的需求。而PID的范围通常较小,可能会出现冲突。
所以,端口号作为网络通信的标识符,能够更好地适应跨主机的进程间通信需求。PID和端口号各自在操作系统和网络协议中发挥着不同的作用。
理解socket
IP 地址
用来标识互联网中唯一的一台主机,port
用来标识该主机上唯一的一个网络进程。
IP+Port
就能表示互联网中唯一的一个进程
所以,通信的时候,本质是两个互联网进程代表人来进行通信,{srcIp,srcPort,dstIp,dstPort}
这样的4 元组就能标识互联网中唯二的两个进程。
所以,网络通信的本质,也是进程间通信,我们把 ip+port
叫做套接字 socket
。
3. 传输层的典型代表
如果我们了解了系统,也了解了网络协议栈,我们就会清楚,传输层是属于内核的,那么我们要通过网络协议栈进行通信,必定调用的是传输层提供的系统调用,来进行的网络通信。
认识TCP协议
TCP协议(传输控制协议) 是计算机网络中重要的传输层协议,主要用于在不同设备之间建立可靠、面向连接的数据传输。以下是对TCP协议概念的简要介绍:
TCP协议的基本概念
- 面向连接:
TCP
是一种面向连接的协议,意味着在数据传输之前,通信双方必须先建立连接。这通常通过 “三次握手” 过程实现,以确保双方都准备好进行数据交换。 - 可靠性:
TCP
提供可靠的数据传输服务,确保数据在传输过程中不会丢失、重复或乱序。它通过为每个数据包分配序列号,并使用确认应答机制(ACK)来跟踪已经成功接收的数据包。如果发送方在合理的时间内未收到确认,它将重新发送丢失的数据包。 - 流控制与拥塞控制:
TCP
使用流控制机制,确保发送方不会超出接收方的处理能力。它还实施拥塞控制,以避免网络过载,从而提高整体网络性能。 - 面向字节流:
TCP
将应用层数据视为一个连续的字节流,而不是独立的数据包。它负责将这个字节流分段成适当大小的数据包进行传输,并在接收端重新组装成完整的数据流。 - 端口号:
TCP
通过端口号来识别不同的应用程序或服务。每个TCP
连接由源IP地址
、源端口号、目的IP地址和目的端口号唯一标识,这使得同一台主机可以同时处理多个连接。
认识UDP协议
UDP(用户数据报协议) 是一种简单的、无连接的传输层协议。以下是对UDP
协议的简单讲解:
UDP的特点
- 无连接:
UDP
在发送数据前不需要建立连接,只需要知道对方的IP地址和端口号即可直接发送数据包。 - 不可靠:
UDP
不提供数据包的可靠性保证,也没有重传机制。如果数据包在传输过程中丢失或错误,UDP
不会进行重发。 - 面向报文:
UDP
将应用程序交给UDP
的报文,在添加UDP
头部后直接交给IP层
。UDP
既不会对报文进行拆分和合并,也不会缓存报文。 - 高效: 由于
UDP
没有复杂的机制,开销小,处理速度快。适合于一次性传输少量数据的应用。
4. 网络字节序
我们已经知道,内存中的多字节数据相对于内存地址有大端和小端之分, 磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分, 网络数据流同样有大端小端之分. 那么如何定义网络数据流的地址呢?
- 发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出;
- 接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存;
- 因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址.
TCP/IP
协议规定,网络数据流应采用大端字节序,即低地址高字节.- 不管这台主机是大端机还是小端机, 都会按照这个TCP/IP 规定的网络字节序来发送/接收数据;
- 如果当前发送主机是小端, 就需要先将数据转成大端; 否则就忽略, 直接发送即可;
为使网络程序具有可移植性,使同样的C 代码在大端和小端计算机上编译后都能正常运
行,可以调用以下库函数做网络字节序和主机字节序的转换。
这些函数名很好记,h
表示 host
, n
表示 network
, l
表示 32 位长整数,s
表示 16 位短整数。
例如,htonl
表示将32位的长整数从主机字节序转换为网络字节序,例如IP
地址转换后准备发送。
5. 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);
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 DomainSocket
各种类型的sockaddr
结构体指针做为参数。
sockaddr 结构
#include <sys/types.h>
typedef unsigned short sa_family_t;
struct sockaddr {
sa_family_t sa_family; // 地址族,例如AF_INET或AF_INET6
char sa_data[14]; // 协议地址的14字节数据
};
sa_family
: 表示地址族,指明使用的协议类型(如IPv4、IPv6等)。sa_data
: 存储具体的地址信息,长度为14字节,可以存放不同协议的地址数据。
sockaddr_in 结构
#include <netinet/in.h>
struct sockaddr_in {
sa_family_t sin_family; // 地址族,通常为AF_INET
in_port_t sin_port; // 端口号(网络字节序)
struct in_addr sin_addr; // IP地址
unsigned char sin_zero[8]; // 填充,使结构体大小与sockaddr相同
};
虽然socket api
的接口是 sockaddr
, 但是我们真正在基于IPv4
编程时, 使用的数据结构是sockaddr_in
; 这个结构里主要有三部分信息: 地址类型, 端口号, IP 地址
in_addr结构
#include <stdint.h>
typedef uint32_t in_addr_t;
struct in_addr {
in_addr_t s_addr; // IPv4地址,采用网络字节序(大端序)
};
in_addr
用来表示一个IPv4
的 IP 地址
. 其实就是一个32 位的整数;