Linux--网络通信(一)概述

网络通信概述

网络通信本质上是一种进程间通信是位于网络中不同主机上的进程之间的通信,属于 IPC 的一种, 通常称为 socket IPC。所以网络通信是为了解决在网络环境中,不同主机上的应用程序之间的通信问题。
大概可以分为三个层次,如下所示:
1 )、硬件层:网卡设备,收发网络数据
2 )、驱动层:网卡驱动( Linux 内核网卡驱动代码)
3 )、应用层:上层应用程序(调用 socket 接口或更高级别接口实现网络相关应用程序)
在硬件上,两台主机都提供了网卡设备,也就满足了进行网络通信最基本的要求,网卡设备是实现网络数据收发的硬件基础。并且通信的两台主机之间需要建立网络连接,这样两台主机之间才可以进行数据传输,譬如通过网线进行数据传输。网络数据的传输媒介有很多种,大体上分为有线传输(譬如双绞线网线、光纤等)和无线传输(譬如 WIFI 、蓝牙、 ZigBee 4G/5G/GPRS 等), PC 机通常使用有线网络,而手机等移动设备通常使用无线网络。
在内核层,提供了网卡驱动程序,可以驱动底层网卡硬件设备,同时向应用层提供 socket 接口。
在应用层,应用程序基于内核提供的 socket 接口进行应用编程,实现自己的网络应用程序。需要注意的是,socket 接口是内核向应用层提供的一套网络编程接口,所以我们学习网络编程其实是学习 socket 编程,如何基于 socket 接口编写应用程序。
除了 socket 接口之外,在应用层通常还会使用一些更为高级的编程接口,譬如 http 、网络控件等,那么这些接口实际上是对 socket 接口的一种更高级别的封装。

1.1    所有的数据传输都有三要素:目的长度

所以,在网络传输中需要使用“ IP 和端口”来表示源或目的。

1.2  sever 和 client 

1.3  网络互联模型:OSI七层模型

七层模型,亦称 OSI Open System Interconnection )。 OSI 七层参考模型是国际标准化组织( ISO )制定的一个用于计算机或通信系统间网络互联的标准体系,一般称为 OSI 参考模型或七层模型。 OSI 七层模型是一个网络互连模型,从上到下依次是:
                                                   
从上可知,网络通信的模型分了很多层,为什么需要分为这么多层次?原因就在于网络是一种非常复杂的通信,需要进行分层,每一层需要去实现不同的功能。下面我们来详细看下 OSI 参考模型中每一层的作用。
 两种传输方式:TCP/UDP
在一般的网络书籍中,TCP/IP五层模型 分为 5 层,事实上, TCP/IP 模型是 OSI 模型的简化版本
                                    
              
应用层:它是体系结构中的最高层,直接为用户的应用进程(例如电子邮件、 文件传输和终端仿真)提供服务。在因特网中的应用层协议很多,如支持万维网应用的 HTTP 协议,支持电子邮件的 SMTP 协议,支持文件传送的 FTP 协议, DNS ,POP3, SNMP Telnet 等等。
运输层:负责向两个主机中进程之间的通信提供服务。
运输层主要使用以下两种协议:
传输控制协议 TCP(Transmission Control Protocol) :面向连接的,数据传输的单位是报文段,能够提供可靠的交付。
用户数据包协议 UDP(User Datagram Protocol) 无连接的,数据传输的单位是用户数据报,不保证提供可靠的交付,只能提供“ 尽最大努力交付
网络层:负责将被称为数据包( datagram )的网络层分组从一台主机移动到另一台主机。
链路层:因特网的网络层通过源和目的地之间的一系列路由器路由数据报。
物理层:在物理层上所传数据的单位是比特。物理层的任务就是透明地传送比特流。
这些层对于初学者来说很难理解,我们只需要知道:我们需要使用“运输层” 编写应用程序,我们的应用程序位于“应用层”。使用“运输层”时,可以选择 TCP 协议,也可以选择 UDP 协议。
数据的封装与拆装
网络通信中,数据从上层到下层交付时,要进行封装;同理,当目标主机接收到数据时,数据由下层传递给上层时需要进行拆封。这就是数据的封装与拆封。
1)当用户发送数据时,将数据向下交给传输层,但是在交给传输层之前,应用层相关协议会对用户数据进行封装,譬如 MQTT HTTP 等协议,其实就是在用户数据前添加一个应用程序头部,这是处于应用层的操作,最后应用层通过调用传输层接口来将封装好的数据交给传输层。
2)传输层会在数据前面加上传输层首部(此处以 TCP 协议为例,图中的传输层首部为 TCP 首部,也可以是 UDP 首部),然后向下交给网络层。
3)同样地,网络层会在数据前面加上网络层首部( IP 首部),然后将数据向下交给链路层,链路层会对数据进行最后一次封装,即在数据前面加上链路层首部(此处使用以太网接口为例,对应以太网首部),然后将数据交给网卡。
4)最后,由网卡硬件设备将数据转换成物理链路上的电平信号,数据就这样被发送到了网络中。这就是网络数据的发送过程,从图中可以看到,各层协议均会对数据进行相应的封装,可以概括为 TCP/IP 模型中的各层协议对数据进行封装的过程。
5)以上便是网络数据的封装过程,当数据被目标主机接收到之后,会进行相反的拆封过程,将每一层的首部进行拆解最终得到用户数据。所以,数据的接收过程与发送过程正好相反,可以概括为 TCP/IP 模型中的各层协议对数据进行解析的过程。

1.4  IP 地址

Internet 依靠 TCP/IP 协议,在全球范围内实现不同硬件结构、不同操作系统、不同网络系统的主机之间的互联。在 Internet 上,每一个节点都依靠唯一的 IP 地址相互区分和相互联系, IP 地址用于标识互联网中的每台主机的身份,设计人员为每个接入网络中的主机都分配一个 IP 地址( Internet Protocol Address ),只有合法的 IP 地址才能接入互联网中并且与其他主机进行网络通信, IP 地址是软件地址,不是硬件地址,硬件 MAC 地址是存储在网卡中的,应用于局域网中寻找目标主机。
IP地址的编址方式
互联网中的每一台主机都需要一个唯一的 IP 地址以标识自己的身份,那么 IP 地址究竟是什么,如何去定义一个 IP 呢?我们需要对 IP 地址的编址方式进行了解。
传统的 IP 地址是一个 32 位二进制数的地址,也叫 IPv4 地址,由 4 8 位字段组成。除了 IPv4 之外, 还有 IPv6 IPv6 采用 128 位地址长度, 8 16 位字段组成,本小节我们暂时不去理会 IPv6 地址。
在网络通信数据包中,IP 地址以 32 位二进制的形式表示;而在人机交互中,通常使用点分十进制方式表示,譬如 192.168.1.1 ,这就是点分十进制的表示方式。
IP 地址中的 32 位实际上包含 2 部分,分别为网络地址和主机地址,可通过子网掩码来确定网络地址和主机地址分别占用多少位。
补充:
  1. 子网掩码:

    • 子网掩码也是32位的二进制数,表示方式与IP地址相同(如255.255.255.0)。
    • 子网掩码中的连续的1表示网络部分,连续的0表示主机部分。

子网掩码的主要作用是确定一个IP地址属于哪个子网,从而实现网络分段和管理。具体来说,子网掩码将IP地址划分为网络地址和主机地址两部分:

  • 网络地址:子网中的所有主机共有的部分,用于标识子网。
  • 主机地址:子网中每个主机独有的部分,用于标识子网内的具体主机。

    2.子网划分:

通过使用子网掩码,可以将一个大网络划分为多个较小的子网,每个子网有自己的网络地址和主机范围。这种划分有助于:

  • 减少广播域:广播只在一个子网内传播,减少网络流量。
  • 提高网络安全:不同子网可以有不同的访问控制策略。
  • 更好地管理网络:网络划分使得网络管理更加灵活和高效。

IP 地址的分类
根据 IP 地址中网络地址和主机地址两部分分别占多少位的不同,将 IP 地址划分为 5 类,分别为 A 、B、 C D E 五类。
A 类地址范围为: 1.0.0.1 ~ 127.255.255.254;默认网络掩码为: 255.0.0.0
B 类地址范围:128.0.0.1 ~ 191.255.255.254;默认网络掩码为: 255.255.0.0
C 类地址范围为:192.0.0.1 ~ 223.255.255.254;默认网络掩码为: 255.255.255.0
D 类地址范围: 224.0.0.1 ~ 239.255.255.254;
E 类地址范围: 240.0.0.1 ~ 255.255.255.254;
如何判断 2 IP 地址是否在同一个网段内
如何判断两个 IP 地址是否处于同一个子网,可通过网络标识来进行判断,网络标识定义如下:
网络标识 = IP 地址 & 子网掩码
2 IP 地址的网络标识相同,那么它们就处于同一网络。譬如 192.168.1.50 192.168.1.100 ,这 2 个都是 C 类地址,对应的子网掩码为 255.255.255.0 ,很明显,这两个 IP 地址与子网掩码进行按位与操作时得到的结果(网络标识)是一样的,所以它们处于同一网络。

1.5、TCP/IP协议

TCP/IP 协议它其实是一个协议族,包含了众多的协议,譬如应用层协议 HTTP 、 FTP、 MQTT …以及传输层协议 TCP UDP 等这些都属于 TCP/IP 协议
所以,我们一般说 TCP/IP 协议,它不是指某一个具体的网络协议,而是一个协议族。网络通信当中涉及到的网络协议实在太多了,对于应用开发来说,可能使用更多的是应用层协议,譬如HTTP FTP SMTP 等
HTTP 协议
HTTP 超文本传输协议(英文: HyperText Transfer Protocol ,缩写: HTTP )是一种用于分布式、协作式 和超媒体信息系统的应用层协议。HTTP 是万维网数据通信的基础。 HTTP 的应用最为广泛,譬如大家经常会打开网页浏览器查询资料,通过浏览器便可开启 HTTP 通信。
HTTP 协议工作于客户端(用户)、服务器端(网站)模式下,浏览器作为 HTTP 客户端通过 URL 向HTTP 服务端即 WEB 服务器发送请求。 Web 服务器根据接收到的请求后,向客户端发送响应信息。借助这种浏览器和服务器之间的 HTTP 通信,我们能够足不出户地获取网络中的各种信息。
FTP 协议
FTP 协议的英文全称为 File Transfer Protocol ,简称为 FTP ,它是一种文件传输协议,从一个主机向一 个主机传输文件的协议。FTP 协议同样也是基于客户端 - 服务器模式,在客户端和服务器之间进行文件传输, 譬如我们通常会使用 FTP 协议在两台主机之间进行文件传输,譬如一台 Ubuntu 系统主机和一台 Windows 系统主机,将一台主机作为 FTP 服务器、另一台主机作为 FTP 客户端,建立 FTP 连接之后,客户端可以从服务器下载文件,同样也可以将文件上传至服务器。
FTP 除了基本的文件上传 / 下载功能外,还有目录操作、权限设置、身份验证等机制,许多网盘的文件传输功能都是基于 FTP 实现的。
TCP 协议
TCP Transmission Control Protocol ,传输控制协议)是一种面向连接的、可靠的、全双工的基于 IP 的传输协议。 TCP 协议工作在传输层,对上服务 socket 接口,对下调用 IP 层(网络层)。
关于 TCP 协议我们需要理解的重点如下:
①、 TCP 协议工作在传输层,对上服务 socket 接口,对下调用 IP 层;
②、 TCP 是一种面向连接的传输协议,通信之前必须通过三次握手与客户端建立连接关系后才可通信;
③、 TCP 协议提供可靠传输,不怕丢包、乱序。
        TCP 协议如何保证可靠传输?
①、 TCP 协议采用发送应答机制,即发送端发送的每个 TCP 报文段都必须得到接收方的应答,才能认
为这个 TCP 报文段传输成功。
②、 TCP 协议采用超时重传机制,发送端在发送出一个 TCP 报文段之后启动定时器,如果在定时时间
内未收到应答,它将重新发送该报文段。
③、由于 TCP 报文段最终是以 IP 数据报发送的,而 IP 数据报到达接收端可能乱序、重复、所以 TCP
协议还会将接收到的 TCP 报文段重排、整理、再交付给应用层。
        TCP 报文格式
当数据由上层发送到传输层时,数据会被封装为 TCP 数据段,我们将其称为 TCP 报文(或 TCP 报文段), TCP 报文由 TCP 首部 + 数据区域组成,一般 TCP 首部通常为 20 个字节大小,具体格式如下图所示:
        源端口号和目标端口号
源端口号和目标端口号各占 2 个字节,一个 4 个字节
每个 TCP 报文都包含源主机和目标主机的端口号,用于寻找发送端和接收端应用进程,这两个值加上 IP 首部中的源 IP 地址和目标 IP 地址就能确定唯一一个 TCP 连接。有时一个 IP 地址和一个端口号也称为 socket (插口)。
        建立 TCP 连接:三次握手
TCP 协议是一个面向连接的协议,双方在进行网络通信之间,都必须先在双方之间建立一条连接,俗称“握手”“三次握手”其实是指建立 TCP 连接的一个过程,通信双方建立一个 TCP 连接需要经过“三次握手”这样一个过程。
首先建立连接的过程是由客户端发起,而服务器会时刻监听、等待着客户端的连接,其示意图如下所示:
TCP 连接一般来说会经历以下过程:
第一次握手
客户端将 TCP 报文标志位 SYN(Synchronize,同步) 置为 1 ,随机产生一个序号值 seq=J ,保存在 TCP 首部的序列号 (Sequence Number)字段里,指明客户端打算连接的服务器的端口,并将该数据包发送给服务器端,发送完毕后,客户端进入 SYN_SENT 状态,等待服务器端确认。
第二次握手
服务器端收到数据包后由标志位 SYN=1 知道客户端请求建立连接,服务器端将 TCP 报文标志位 SYN 和 ACK 都置为 1 ack=J+1 ,随机产生一个序号值 seq=K ,并将该数据包发送给客户端以确认连接请求,服务器端进入 SYN_RCVD 状态。
第三次握手
客户端收到确认后,检查 ack 是否为 J+1 ACK 是否为 1 ,如果正确则将标志位 ACK 置为 1 ack=K+1 ,并将该数据包发送给服务器端,服务器端检查 ack 是否为 K+1 ACK 是否为 1 ,如果正确则连接建立成功,
客户端和服务器端进入 ESTABLISHED 状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了。在完成握手后,客户端与服务器就成功建立了连接,同时双方都得到了彼此的窗口大小,序列号等信息,在传输 TCP 报文段的时候,每个 TCP 报文段首部的 SYN 标志都会被置 0 ,因为它只用于发起连接,同步序号。
注意:上面写的 ack 和 ACK,不是同一个概念:
小写的 ack 代表的是头部的确认号 Acknowledge number,ack。
大写的 ACK,则是 TCP 首部的标志位,用于标志的 TCP 包是否对上一个包进行了确认操作,如果确认 了,则把 ACK 标志位设置成 1。
总结梳理:
发起:客户端发起第一次握手,将报文中的同步标志位置1,并随机产生一个序号,告诉服务端我要与你的某一个端口创建连接了;
应答:服务端收到数据包后根据同步标志位知道了客户端在请求建立连接,服务端发起第二次握手,将报文标志位SYN和应答位ACK都置1,告诉客户端我确认收到你的请求了;
连接:客户端收到应答报文后,检查应答标志位是否为1,是的话就发送带有特定确认序号的数据包,服务端再检查一下无误就成功建立连接。这一次握手就是互相最后再确认一下。
为什么需要三次握手?
其实 TCP 三次握手过程跟现实生活中的人与人之间的电话交流是很类似的,譬如 A 打电话给 B
A :“喂,你能听到我的声音吗?
B :“我听得到呀,你能听到我的声音吗?”
A :“我能听到你,………”
……
经过三次的互相确认,大家就会认为对方对听的到自己说话,才开始接下来的沟通交流,否则,如果不 进行确认,那么你在说话的时候,对方不一定能听到你的声音。所以,TCP 的三次握手是为了保证传输的安全、可靠。
         关闭 TCP 连接:四次挥手
除了“三次握手”,还有“四次挥手”,“四次挥手”(有一些书也会称为四次握手)其实是指关闭 TCP
连接的一个过程,当通信双方需要关闭 TCP 连接时需要经过“四次挥手”这样一个过程。
四次挥手即终止 TCP 连接,就是指断开一个 TCP 连接时,需要客户端和服务端总共发送 4 个包以确认连接的断开。在 socket 编程中,这一过程由客户端或服务端任一方执行 close 来触发。
由于 TCP 连接是全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个 FIN 来终止这一方向的连接,收到一个 FIN 只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个 TCP 连接上仍然能够发送数据,直到这一方向也发送了 FIN 。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。
第一次挥手
Client 端发起挥手请求,向 Server 端发出一个 FIN 报文段主动进行关闭连接,此时报文段的 FIN 标志位被设置为 1 。此时, Client 端进入 FIN_WAIT_1 状态,这表示 Client 端没有数据要发送给 Server 端了。
第二次挥手
Server 端收到了 Client 端发送的 FIN 报文段,向 Client 端返回一个 ACK 报文段,此时报文段的 ACK 标志位被设置为 1 ack 设为 seq 1 Client 端进入 FIN_WAIT_2 状态, Server 端告诉 Client 端,我确认并同意你的关闭请求。
第三次挥手
Server 端向 Client 端发送一个 FIN 报文段请求关闭连接,此时报文段的 FIN 标志位被设置为 1 ,同时 Client 端进入 LAST_ACK 状态。
第四次挥手
Client 端收到 Server 端发送的 FIN 报文段后,向 Server 端发送 ACK 报文段(此时报文段的 ACK 标志 位被设置为 1 ),然后 Client 端进入 TIME_WAIT 状态。 Server 端收到 Client 端的 ACK 报文段以后,就关 闭连接。此时,Client 端等待 2MSL 的时间后依然没有收到回复,则证明 Server 端已正常关闭,那好, Client 端也可以关闭连接了。
总结:本质上,TCP协议中的挥手握手的目的就是确保通信的双方对连接的理解状态保持一致,也就是实现双方对连接状态的同步。
UDP 协议
除了 TCP 协议外,还有 UDP 协议,想必大家都听过说, UDP User Datagram Protocol 的简称,中文名是用户数据报协议,是一种无连接、不可靠的协议,同样它也是工作在传顺层。它只是简单地实现从一端主机到另一端主机的数据传输功能,这些数据通过 IP 层发送,在网络中传输,到达目标主机的顺序是无法预知的,因此需要应用程序对这些数据进行排序处理,这就带来了很大的不方便,此外,UDP 协议更没有 流量控制、拥塞控制等功能,在发送的一端,UDP 只是把上层应用的数据封装到 UDP 报文中,在差错检测方面,仅仅是对数据进行了简单的校验,然后将其封装到 IP 数据报中发送出去。而在接收端,无论是否收到数据,它都不会产生一个应答发送给源主机,并且如果接收到数据发送校验错误,那么接收端就会丢弃该UDP 报文,也不会告诉源主机,这样子传输的数据是无法保障其准确性的,如果想要其准确性,那么就需要应用程序来保障了。
UDP 虽然有很多缺点,但也有自己的优点,所以它也有很多的应用场合,因为在如今的网络环境下, UDP 协议传输出现错误的概率是很小的,并且它的实时性是非常好,常用于实时视频的传输,比如直播、 网络电话等,因为即使是出现了数据丢失的情况,导致视频卡帧,这也不是什么大不了的事情,所以,UDP协议还是会被应用与对传输速度有要求,并且可以容忍出现差错的数据传输中。
 TCP UDP 原理上的区别
TCP 向它的应用程序提供了面向连接的服务。这种服务有 2 个特点:可靠传输、流量控制(即发送方/ 接收方速率匹配)。它包括了应用层报文划分为短报文,并提供拥塞控制机制。
UDP 协议向它的应用程序提供无连接服务。它没有可靠性,没有流量控制,也没有拥塞控制。
        既然 TCP 提供了可靠数据传输服务,而 UDP 不能提供,那么 TCP 是否总是首选呢?
答案是否定的,因为有许多应用更适合用 UDP ,举个例子:视频通话时,使用 UDP ,偶尔的丢包、偶尔的花屏时可以忍受的;如果使用 TCP ,每个数据包都要确保可靠传输,当它出错时就重传,这会导致后续的数据包被阻滞,视频效果反而不好。TCP保证数据的质、UDP保证数据的速和量。
使用 UDP 时,有如下特点:
1)关于何时发送什么数据控制的更为精细
采用 UDP 时只要应用进程将数据传递给 UDP UDP 就会立即将其传递给网络层。而 TCP 有重传机制,而不管可靠交付需要多长时间。但是实时应用通常不希望过分的延迟报文段的传送,且能容忍一部分数据丢失。
2)无需建立连接,不会引入建立连接时的延迟。
3)无连接状态,能支持更多的活跃客户。
4)分组首部开销较小。
端口号的概念
互联网中的每一台主机都需要一个唯一的 IP 地址以标识自己的身份,网络中传输的数据包通过 IP 地址找到对应的目标主机;一台主机通常只有一个 IP 地址,但主机上运行的网络进程却通常不止一个,譬如 Windows 电脑上运行着 QQ 、微信、钉钉、网页浏览器等,这些进程都需要进行网
络连接,它们都可通过网络发送 / 接收数据,那么这里就有一个问题?主机接收到网络数据之后,如何确定该数据是哪个进程对应的接收数据呢?其实就是通常端口号来确定的。

端口号本质上就是一个数字编号,用来在一台主机中唯一标识一个能上网(能够进行网络通信)的进程,端口号的取值范围为 0~65535 。一台主机通常只有一个 IP 地址,但是可能有多个端口号,每个端口号表示一个能上网的进程。一台拥有 IP 地址的主机可以提供许多服务,比如 Web 服务、 FTP 服务、 SMTP 服务等,这些服务都是能够进行网络通信的进程,IP 地址只能区分网络中不同的主机,并不能区分主机中的这些进程,显然不能只靠 IP 地址,因此才有了端口号。通过“ IP 地址+端口号”来区分主机不同的进程。
  • 11
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值