10.网络编程

一、前言

网络编程是一个很重要的点,毕竟现在的软件,很少有不需要网络的了,别的不说,很多软件一般都会有一个检测升级的功能。

但在了解网路编程之前,我们必须要有一个总体观念:

网络通信是对于整个电脑而言,而不单单是我们写的这个程序,我们所写的程序实际上是在调用我们电脑网络通信的能力

也就是说,网络编程是一个与具体编程语言无关的一个概念,虽然各个语言实现的方式可能略有差别,但本质上功能、目的都是一样的。

二、网络编程基础

首先还是来考虑一个问题,我们为什么需要网络?

这个问题应该是很简单的,因为我们需要和他人交换信息、通信。

虽然目前大部分电脑的操作系统本身,都是支持多用户使用同一台电脑的。

Windows系统也是一样,你可以在电脑上建立多个用户,且这多个用户不会互相影响

但实际上,目前个人电脑应该是占主导地位的,即自己独占一台电脑。

也就是说,如果现在我想要和朋友通信,或者从别人的网页上下载资料,就只需要让我的电脑和它的电脑通信即可,即两台电脑互相通信。

但问题来了,通信肯定需要介质来传输信息,就算是我们说话,那也需要用空气传递声波,别人才能听到!

而电脑之间的传输介质就很多了,比如无线Wifi,光纤等等。

虽然介质很多,但对于我们而言,其实可以直接抽象一下,即两个电脑之间可以直接看作,有一根线将它们连接了起来。

因为我们不需要关心各个电脑之间是用什么传输的,我们只需要知道它们能够传输信息即可。

graph LR
A[电脑]--- B[电脑]

但这只是最简化的想法,因为现实中,不可能给每个电脑或手机都拉一根线。

毕竟当前世界的电子产品数量大的惊人,所以很多时候,大家都是共用一根线来节约成本的。

graph LR
A[电脑1]--- C[公共线路]
C---B[电脑2]
A1[电脑3]---C
C---B1[电脑4]

但这时候就出现问题了,即一个电脑发送的消息,如何判断它能够准确的发送到目的计算机上呢?

因为大家都是共用的一根线传输数据!你得区分各个电脑啊!

所以这时候就有了地址,每个连上了网的电脑都会被分配一个地址,即我们常说的IP地址:

graph LR
A[电脑1 : 192.168.0.1]--- C[公共线路]
C---B[电脑2: 192.168.0.2]
A1[电脑3: 192.168.0.3]---C
C---B1[电脑4: 192.168.0.4]

当然了,上面这些地址都是我乱写的,理解一下即可

即当一个电脑想要发送信息时,只需要在信息前面添加一个IP地址,然后将这个信息发送到公有线路上。

如果接收方看到这个信息的接收地址是自己,那就接收,不是自己的话,要么转发,要么直接丢弃

比如上图中,电脑1想要给电脑4发送一条消息,那么就会在这条信息前面添加上目的地的IP地址,即192.168.0.4

但这条信息会发送到这条线路上的每一个电脑,当电脑2,电脑3看到这条信息目的地IP不是自己,就丢弃了,而电脑4看到这个IP地址就是自己的地址,才会接收。

上面这种通过给每个电脑都分配IP的方法,是最开始的设想,它被称为IPv4

但后来,谁也没想到世界的电子设备迅速增长,IP地址不够用了!

因为IPv4是用的32位二进制表示的地址,即可以表示2的32次方个地址,虽然实际上要比这个数小,但也大约可以有43亿个设备。

前面的192.168.0.1是二进制相应的十进制表示法,每8位分隔一下,所以四个区域中的数字,最大也只能为255,这是为了方便我们使用。

可现在世界上的人口都有八十亿了,这肯定不够的呀!所以就出现了Ipv6地址,用64位表示。

但由于Ipv4的基础设施已经搭建好了,想要迅速过渡到Ipv6,就意味着需要大量更换基础设施,这样成本太高了。

所以为了正常过渡到Ipv6,同时不影响现在使用,就出现了局域网!仅仅使用Ipv4就能基本满足现在的需求。

专业点来说就是NAT机制,除此之外还有动态分配机制等等技术来解决这一问题。

如果你现在电脑连的Wifi上网,那么就已经身处局域网之内了。

局域网的概念就是,不用每一个电脑都连上公网,只需要一个设备连接上公网,比如路由器,而其它设备连接路由器即可:

graph LR
A[设备1 : 公网ip1]--- C[公网ip线路]
C---B[设备2 : 公网ip2]
A1[设备3: 公网ip3]---C
C---B1[设备4: 公网ip4]
D[设备5 : 局域网ip1] --- A
D1[设备6 : 局域网ip2] --- A

这样,就能够极大缓解IP资源不够的情况!上面只是公网IP下的一层,但其实还可以继续递推嵌套下去

因为我们很可能处于局域网中的局域网。

比如我们常见的IP地址:192.168.0.1,前面由192.168开头的就是一个局域网IP,虽然在同一个局域网下这个IP地址不能重复,但在不同局域网下,这个IP地址是可以重复的。

比如我当前电脑就连接的Wifi,这就是在局域网下,给我分配的IP地址为192.168.3.8

image-20231103161947436

同时也能看到,上面还有一个IPv6地址,因为它是64位,如果用十进制就太长了,所以它用的十六进制表示。

局域网ip地址有三种:

10.0.0.0 - 10.255.255.255 
172.16.0.0 - 172.31.255.255 
192.168.0.0 -192.168.255.255 

如果你的电脑IP在这个范围里面,那就说明你处于局域网下。

而这也就导致了,如果你的朋友也在另外一个局域网下,你两是无法直接通过对方IP地址通信的!

但为啥我们用QQ、微信也能通信呢?

那是因为这是腾讯在公网IP上架设的服务器,你发送给朋友的信息,实际上是先发送给腾讯,腾讯再帮你转发给你的朋友。

我们为什么能上网看到网页呢?

这是因为网站的服务器都是放在了公网IP上,所以你可以访问。

总结来说就是:

  1. 处在同一局域网中可以互相访问。
  2. 不同局域网之间不能直接互相访问。
  3. 任何网络都可以访问公网IP。
  4. 公网IP想要访问局域网IP,就必须局域网IP先访问自己,才能回访。

三、网络协议

一开始新手听到协议两个字,会觉得协议很高级的样子,很抽象,无法理解,但其实熟悉了之后你会发现,所谓协议不过是官方定制的标准而已,也就是规矩!

比如,上面我们已经讲了两台电脑之间传输数据,需要对方的ip地址,那么ip地址放在哪里呢?

放在数据的最前面,中间,或是最后面?似乎都是可以的,只是实现复杂度可能不同而已。

为了避免出现混乱,就出现了规矩,即协议,规定IP地址只能写在数据的最前面,放在其它地方,其它电脑就不认识。

因为根据协议,它们只看数据的最前面,不是自己的IP就丢弃。

对于我们程序开发人员而言,网络协议一般只需要知道两种即可,即我们常能看到的TCP协议、UDP协议。

直接介绍这种种协议的概念,可能你会有点抽象,所以这里我们还是用两个计算机的通信举例子

1.TCP

首先是TCP协议,即想要建立TCP连接的规矩,当A计算机想要和B计算机通信时:

  1. 根据协议,A必须先给B发送一个请求连接的消息
  2. B接收到了A的请求连接,就给A发送一个应答消息
  3. A接收到了B的应答消息,就再给B回复一个应答消息,便于B确定A收到了自己的回复

也就是说,在TCP连接的阶段,需要发送三次信息,第一次和第三次都是请求方发送方的,第二次是等待连接方发送的。

上述过程也被称为三次握手,完成了三次握手,通信双方就可以自由的发送信息了!

这个过程在C/C++网络编程中,对应着的就是connect函数。

当发送完成了之后,想要断开连接时,比如A想要断开双方的连接:

  1. A向B发送断开连接请求
  2. B收到了之后,向A发送确认自己收到的请求
  3. B再向A发送断开请求
  4. A向B发送确认自己收到的请求

可以看到,断开连接阶段,需要发送4次信息,即一次为主动发出断开请求,一次为被动发出确认自己收到的请求。

这也被称为4次挥手

这个过程对应的就是closesocket函数。

至于发送、接受数据,则是通过sendrecv等函数来完成,它们必须在连接之后才能被调用。

通过以上的过程,我们看得出来,TCP协议重在严谨!因为每次给对方发送了信息之后,都要等待对方回应它收到了信息,来确保消息无误。

所以我们对TCP就有了以下结论:

  • 面向连接:只有双方建立起来连接,才能互相发送数据。

  • 单播传输:即每次只能两个计算机之间进行传输数据。

  • 可靠传输:因为TCP发送数据之后,都要等待对方回应自己收到的信息,所以很可靠(如果数据半路丢失,没有收到对方的回应,数据就会重新传输)

至于如何编程,可以参考本站其它具体编程语言教程的实现。

2.UDP

看到上方的TCP协议,你可能会觉得很麻烦,而且消耗资源。

因为它每次发送数据都要等待对方的回应,这数据传输的速度肯定就慢了!

在很多时候,我们可能并不需要数据太多准确,只要能用就行,比如你打微信视频时,有时候网不好就会出现卡顿、丢帧的情况,但这样也无所谓,只要能保证流畅就行嘛!

为了解决这些更强调速度的网络环境,就有了UDP协议。

这个协议非常简单,不用连接,只要你知道对方电脑的IP地址与端口,就能直接给对方发送信息!

不过前提是对方在公网上,或者与自己在同一个局域网内。

也正是因为UDP这种不需要连接的特性,它发送数据的速度非常快,而且还可以同时向多个目标发送数据!

总结来说就是:

  • 非连接:不需要进行连接就能发送消息。
  • 不可靠:不会对消息是否正确进行确认。
  • 可广播:它可以同时向一个网段中的所有电脑发送数据。

同样的,至于如何编程,可以参考本站其它具体编程语言教程的实现。

作者:余识
全部文章:0
会员文章:0
总阅读量:0
c/c++pythonrustJavaScriptwindowslinux