Socket编程
Socket编程是网络编程最常用的手段,单纯要应用socket编程事实上不需要了解计算机网络那么多的知识,我们只需要知道两个概念:
- IP地址可以唯一的标识一台计算机。
- 端口号可以唯一的标识计算机中的某一网络进程。
这两个概念都不完全严谨,但在不了解太多网络知识的前提下我们可以先认为这是对的。 IP地址可以认为是我们现实生活中的一个身份证,通过身份证号我们可以唯一的在我们国家找到一个人。也就是说,如果我们知道某一台计算机的IP地址,那么我们就可以在全国那么多台计算机中找到我们要进行通信的那台计算机了。目前我们IP地址主要由点分十进制的方式给出,例如192.168.0.1 . 其中每一个数在0-255之间。通过四个十进制数就可以在偌大的网络世界找到一台你想要传递信息的计算机。
端口号是指计算机中某一个网络进程的标识符,通过IP地址,我们可以把消息传递到某一台计算机。但一台计算机中肯定有很多软件都在访问互联网,而这一条消息应该发往哪一个程序这件事就应该由端口号去给出。
以下是一个形象的例子:
以上有A,B两台电脑,A的IP地址是192.168.0.22,B的IP地址是192.168.0.25. 通过IP地址,我们可以很直观的区分出两台电脑来。然后在A,B两台电脑上都运行着QQ,腾讯视频,QQ邮箱三个软件,三个软件都属于网络应用,但它们的端口号不同。例如:我们通过QQ从电脑A发送一条消息到电脑B。
当前A发送给B的消息包含3部分,IP地址,端口号以及消息。我们试想一下:
- 如果只有端口号没有地址:A会不知道发送给哪一台电脑,因此无法精确到达B。
- 如果只有IP地址没有端口号:A可以找到B,并且消息也可以抵达B,但到了B之后又应该由哪一个程序接收呢?QQ发送出来的消息,如果发送到B的腾讯视频中,可以想象腾讯视频可没有一个对话框给你显示“你好”这一句话。
因此没有端口号我们还是不能知道我们应该发给谁。
只有IP地址和端口号都存在了,才能正确知道“你好”这条消息发给谁。那么不难发现,IP地址和端口号就是网络编程中最重要的元素,为了方便我们把两者加在一起就合称socket!而socket编程就是通过IP地址与端口号确定目标的方式实现信息的相互发送。
C/S架构
有了socket就可以给自己想要发送的主机发送信息啦。但我们需要思考另一个问题,我们使用QQ的时候只在一台电脑上使用吗?答案是否定的,我们可以在学校的电脑登上QQ和熟悉的人进行交谈,也可以在家里的电脑登上QQ找同学老师聊天。既然IP地址是唯一标识一台主机的,那么家里电脑和学校电脑的IP地址固然不同。我们假设学校的电脑是A,家里的电脑是C,我们可以用A和B进行通信,也可以用C和B进行通信。的确,我们只要知道B的IP地址就很容易实现,但如果B也会在家校之间移动呢?如下图所示:
由于我们不可能时刻知道目前我们想要交流用户的确切IP地址,因此我们会无法在网络世界找到他,也无法进行通信。
在互联网世界中,给出的解决方案是这样的。既然用户的位置会变,IP地址也随之改变,那么我们就用一个位置不变,IP地址也不变的“计算机”作为中转。形象的来说,就是A先把自己要说的话告诉S,然后由S再传递给B。同理,B要找A也是B先把消息告诉S,再由S传递给A。如下图所示:
A发送给B的消息,带上B的唯一标识符(此处为QQ号)先发给了C,那么问题来了,C作为中转,C又怎么知道该发给哪一台电脑呢?A不知道B的IP地址,也没有提供给C。
事实上,我们使用QQ都有一个操作就是登陆,既然我们知道C的IP地址是固定的,那么我们在登录的时候就主动发一条消息,告诉C自己的IP地址?也就是下图的这种模式:
这样A再发送数据的时候,我们就可以清晰的知道它应该发送给谁了。上面用了一种全新的表示方式,就是IP地址+端口号写在一起,中间用“:”符号进行分割,是网络中非常常见的一种表示socket的方法。一下为交互的最终图:
在整个上述过程中,C就是我们常说的服务器,A,B就是我们常说的客户端。服务器拥有固定的IP地址,客户端的IP地址是可以随意改变的。而他们合在一起就是我们常说的C/S架构(客户端/服务器架构)。 上述过程中,登录则是一个建立连接的过程,我们只有建立起服务器与客户端之间的连接,才能成功的通信,才能知道你这个消息应该发给谁。
对IP地址的更正
这一部分是对IP地址的一个说明,如果不希望深入理解计算机网络的基本原理我们可以记住以下几个结论:
- 由于IP地址数量有限,并不是全世界计算机都有唯一的IP地址,而是大量计算机用重复的地址,被称为内网地址,而众多内网地址的集合共享有一个外网地址,需要NAT技术进行内外网之间的转换。
- 由于我们家用计算机没有永久固定的IP地址,因此不适合作为服务器使用。服务器应租赁云平台上具有永久性IP地址的站点。
事实上,IP地址并不是唯一表示一台计算机的。首先,我们算一下一共有多少IP地址?2的32次方,约为42亿。而目前我们所使用到的网络电子设备(注意,包括手机/路由器/服务器都算网络电子设备)似乎略大于这个数?那么有一天所有IP地址都分配完了怎么办呢?(事实上目前已分配完)
那么我们会引入内网这个概念:
内网就是在某一部分计算机相互通信中,我们使用一部分规定可以重复使用的IP地址。例如192.168.0.X就是很常见的可以重复使用的IP地址。而他们访问外网则用一个统一的外网地址,如188.244.238.126. 那么内网中的计算机访问外网时将会有一次socket的转换: 如上图所示,A,B,C在一个内网中,A下的某一个网络进程(socket:192.168.0.25:26)与C的两个网络进程(socket:192.168.0.44:26 192.168.0.44:3366)都在同时与D进行交互(socket: 129.204.252.166:731).但在通过NAT的时候,A,B,C的IP地址事实上都会变成统一的188.244.238.126一致对外,而区别他们的依据则还是端口号。
此时对于D来说,A,B,C发过来的消息似乎是一台电脑发过来的一样,D可以根据一台电脑中的不同网络进程这种方式去处理这些网络信息。例如D往A发送数据,它是往188.244.238.126:1 这个socket下发送的,而NAT中转则会自动把这个信息再转发给A. 这个内外网切换的过程就称为NAT技术。
事实上,这一部分操作是完全不用我们自己去实现的,我们需要知道的是,如A,B,C这样的一般个人电脑个人网络是不具有永久性IP地址的,例如A现在可能是192.168.0.25,明天再开机可能就变成192.168.0.33了。因此这种个人网络是不适合作为服务器的。(需要使用NAT隧道技术,有兴趣可以了解一下)
但是如果对于D这种具有永久性IP地址的,就可以作为服务器端中转如A,B,C这类客户端的消息,从而形成一个完整的C/S架构。
小结
通过以上分析,我们大致可以了解到,需要进行C/S架构的网络编程,我们需要以下条件:
- 有一个具有永久IP地址的端口作为服务器来进行信息的中转。
- 需要有建立连接的过程使得服务器知道对应的客户端信息。
- 通过socket来索引对应的客户来进行信息的交互。
那么下面我们将会进入网络编程的相关常识以及代码实现。鉴于讲解方便,我们将使用笔者认为最简单的编程语言C#来作为演示。但对应的网络编程相关函数大多数编程语言差异不大,都能相互支持,因此读着也可以根据自己熟悉的语言来进行实现。
|