Socket编程:一点点教你做个聊天工具——(一)计算机网络基础理论篇

一个简单的聊天工具,写个小系列,Python代码实现。最后的成品在这里,你可以先下载下来玩一下,再考虑要不要看这个系列的东西。

链接:https://pan.baidu.com/s/192onr8E0KWxH4EfmOBqb6g 
           提取码:0hsf 
 

首界面:

 

左上角Config菜单配置ip:

 

在你的cmd命令行里打入ipconfig命令,查看你的ip。

 

我这里连接的是无线,找到WLAN的适配器,查看ip:192.168.1.117,这是一个局域网IP,对于什么是局域网,我们后面谈,这里注意,如果你测试机的ip是局域网ip,需要两台通讯机器连接到同一局域网上。(也就是说链接的是同一个wifi)

这里点击确认(confirm)后,应该会有个弹框,问你是否允许程序执行某些东西,点击确认就行。别担心,我只是占用了你的55555号端口,至于端口是什么,我们同样后面说。

 

相同的道理,问问你哥们的ip是多少,在config里配置send_ip。

顺便可以自己起个暱称。config ID

配置完毕后,界面会有提示:

 

自己的机器算是配置完了。同样的,把你哥们的也配置好。不过注意这里的ip是它的ip,它的send_ip才是你的IP,别搞混了啊。

 

当全部配置完毕后,在输入框里(下面小的那个)输入你想发送的消息,点击submit发送。下面就是两台电脑间的通讯结果:

 

 

 

ok,演示已经结束了。你现在需要考虑要不要把时间丢在这上面了。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

哇,如果你看到了这句话,那你应该就决定留下来了。不过我还是要奉劝一句:别抱有太大的期望,万一失望了呢。

哈哈哈,开玩笑,既然决定了,那就一起努力吧。

 

文章的标题已经指出了,理论片。不要一听到这篇文章没代码就很伤心,程序的代码并不长,但涉及到的理论并不少,有些原理的东西无关紧要,但有些最基础的东西,不理解是没办法懂得程序含义的。

 

首篇文章,我们就先来解决这些东西。

 

就从程序运行的过程一点点说起。最开始,我们配置的就是自己的IP,那第一个概念来了,什么是IP(WHAT)。

 

IP(Internet Protocol Address),简单来说就是地址(WHERE)。分IPv4和IPv6,我们常用的是IPv4,有什么区别呢?也没太大区别,IPv4用32位的长度来表示一个ip地址,而IPv6用128位表示一个地址(我说的是二进制位)。至于IPv6为什么会出现,也完全是因为IPv4不够用了。

 

也就是说,你自己的IP是在网络中定位你位置用的。数据的传输要有目的地,通过你的IP地址,数据才能准确的发到你的手里。

 

就拿这里来说,往上看这篇文章的链接地址:

https://blog.csdn.net/qq_41500251/article/details/90114802

如果你不小心点进去了,那............这篇文章的点击量+1,感谢。

 

在计算机网络中,数据传输通过的是协议。又一个概念——协议。我不想说的太官方,搜索了解下。这里我简单谈理解,协议——就是“规则”。两台机器之间通信,我们要指定规则,举个例子,比如A给B发消息,B接收到了。A怎么知道B是否接受到了呢?如果B没接收到,那我还要重新发送。Now,制定规则,B如果你接收到了,给我回个消息说:“我收到了!”。A收到了确认消息,知道发送成功,不管了。那B怎么知道A是否收到了B发送的确认消息呢?制定规则,A你收到了我收到的消息,也告诉我一声。B如果收到了A的确认消息,OK了,已经可以确定AB的接受和发送能力没问题,换句话说A和B之间的链接没问题,可以通信了。

 

我上面说到的这个例子是TCP(一种运输层协议,有些地方叫传输层)协议建立链接的过程,建立完链接,就可以在这条通道上传输数据了。

 

回过来再看那个链接:

https://blog.csdn.net/qq_41500251/article/details/90114802

如果你不小心又点到,那......你懂的。

 

http是应用层的一种协议(就按我刚刚说的理解,就是一种数据的传输规则)。从刚才的运输层,又到了现在的应用层,这都是什么东西啊。

 

别急,听我言。因为网络协议的指定过于复杂,我们人工的对它进行了分层。这个东西和我们写代码是一样的,比如我们写个飞机大战的代码。我们不太可能从头到尾一溜烟儿的把逻辑写完,因为写着写着就乱了。我们会写个飞机移动的函数move(),飞机开火的函数fire()。然后我们在主函数里调用就完了,网络协议的分层完全可以靠这种理解。

 

                       

这张图片并不准确,因为有些层之间的区分并不很明确,而且有些层在一些地方也不会用到(比如表示层和会话层等等)。

 

最底层的物理层,相信不需要过多的介绍了,就是在网络之间传送01数字,我们知道数据除了0就是1,至于问什么计算机可以把01变成我们能够看到的图片,视频,文字等完全是软件的功劳。

 

简单点理解,物理层你就是在写函数功能,最上面那一层就是在调函数。下层对上层提供服务,让上层在逻辑功能的表示上更加简单。

 

回过来说那个连接:

https://blog.csdn.net/qq_41500251/article/details/90114802

你懂我要说什么,因为问题一直在发散,我们说完一个问题就回到主干往下延伸,你们习惯下我的思维。

 

这个链接,也就是我们经常说的网页地址,它有个自己的学名——URL(Uniform Resourfe Locator)统一资源定位符。我们知道IP和port在网络中表示一台设备,而URL标识的更加精细,他是网络中某一文档的表示。

 

URL的一般形式由以下四个部分组成:

<协议>://<主机>:<端口>/<路径>

 

协议就是指出使用什么协议来获取万维网文档。我们经常用的是http和ftp(文件传输协议),主机端口我们就不多解释了,后面的路径,当然就是文档的目录了。

 

我们在输网址时一般不会输入端口号,默认为80。如果访问自己本地的服务器时,就要按着服务器容器的端口去请求了。比如TomCat的端口默认8080等等。

 

我们说了http属于应用层的一个协议,而给http提供服务的运输层协议就是TCP。我们在浏览网页的时候应该也注意到了,全是靠的http协议来传输数据的。回眼两行看链接:

http后紧跟的是blog.csdn.net,这个东西叫做域名(因器内容与程序没太大关系,我把基础理论放在文章后面,感兴趣的可以自行查看),你可以和IP等同。我们前面说了IPv4是32位长度的一个地址,拿我的局域网ip来说:

 

192.168.1.117。

我们通常用十进位来表示,八位二进制表示成一位十进制数字:

192 —— 11000000, 168——10101000, 1——00000001, 117——01110101。

所以,我的局域网IP地址的二进制表现形式是:

 11000000 10101000 00000001 01110101 (32位)

 

我们上面说到的域名,其实是和IP绑定上的,等同于IP,但不是IP。为什么这么做呢?一来是你输入地址时方便,我们所有人访问百度都知道是www.baidu.com,你知道他的IP吗。二来,为了保护服务器的安全,不直接显示IP地址。

 

当然如果你知道服务器的详细IP地址,就可以把域名换掉,效果是一样的。打个比方,如果csdn博客的服务器ip是192.168.1.117。那你请求这个地址,效果是完全一样的:

https://192.168.1.117/qq_41500251/article/details/90114802

当然你不可能请求到,因为这是个局域网IP。

 

说回来,当你在浏览器地址栏中输入了:

https://blog.csdn.net/qq_41500251/article/details/90114802

按下回车,你会向csdn的服务器发送个请求,来请求建立链接。整个过程就是前面我们拿AB说的那个例子,而他的底层就是靠TCP这个协议实现的。那个过程执行完毕,服务器就会给你发数据,你接收到展示出来,就是你眼前的这篇文章了。也就是说你虽然能看到我的这篇文章,但是这篇文章并不在你的电脑上,而是csdn服务器发给你的,哪的服务器?就是blog.csdn.net这个域名所代表的服务器。你是怎么找到这个服务器的?靠服务器IP地址。

 

现在清晰IP是个什么功能了吗?行吧,IP就先说到这里了。已经烦了是不是,再坚持下,这很重要。

 

演示中我说过,当你在配置自己的IP地址的时候,系统问你是否同意程序执行某些东西。我说过了,我要占用你的端口。又一个概念来了——端口(port)。

 

我们还从例子出发:

 

你打开了自己的电脑,登上了QQ,然后打开了浏览器,请求了csdn的博客,csdn服务器给你发回来数据。你的浏览器接收到,展现出来。

 

有没有想过这个问题——为什么是数据能精确的给了浏览器,为什么它没把数据给了QQ?

 

嗯,就是那个意思。通过IP我知道了你的机器在哪里(这里说法并不准确,很多设备都可以有IP,联系物联网思考下),我只是把数据给了你的机器,怎么精确定位到具体要给你机器的哪个程序呢?

 

这就是端口的功能了。

 

对于端口,我们多说点。端口大了分可以分为两类——服务器端使用的端口和客户端使用的端口。

 

服务器端口中,又分为两类:

1.系统端口号,数值为0-1023,这些端口是大众熟知的端口,很重要,不会让用户随意修改。

2.登记端口号,数值为1024-49151,这些端口使用也是需要做登记的。

 

客户端使用的端口,就是给我们计算机上的进程用的了,数值为49152-65535。它是动态分配的,来一个进程给一个端口,不用了收回来,给别的程序使用。(我占用了你的55555端口,那个弹窗就是请求你同意的。)

 

也因此,网络中两台PC的数据交换,其实是两个进程之间的数据交换。

 

现在我们有了两个重要概念:IP和port。

 

这二者的结合,(IP, port)就是socket,套接字。

 

有了上面的理解,我们就能清楚的了解到通过socket我就能定位到指定机器的指定进程,有了目标之后,就可以对目标发送数据了。

 

最后的一个概念,也是最开始说的“局域网ip”。

 

其实从概念上应该也能明白个差不多,就是在局域有效的ip。我们知道表示地址的的长度就那么几位,是有限的,会被分完的。

 

局域网从某一方面上减缓了这种情况。我们简单说下吧。假如,我有10个ip分别是1, 2, 3, 4........10(这里只是为了书写简便)。

 

那我的网络中最终只能有10台机器,再多我就没地址可以给了。

 

现在规定8, 9, 10这3个ip是局域网ip,这几个ip只在局部有效。我把1, 2, 3....其他的ip分给路由器(不能再扩展了,没完没了了。简单理解路由器就是网络中转发数据的机器)。

 

                               

 

如果我把其余七个ip给了7个路由器,每个路由器都可以连接3台机器构成一个局域网,三台机器用8,9,10ip标记。也就是说如果1局域网里用8给9发数据,接收的也是1局域网里的9,而不是2局域网里的9。这种方式来分配IP,那算算看我们能分配多上设备:7个路由器加上7 x 3 =21台PC。

 

问题来了,那我1里面的8要给2里面的9发送数据怎么办呢?因为8, 9, 10ip是局域网的,他不能在外网进行传输(图中1到2之间的网络就可以看成外网),最终通过路由器1和路由器2之间传输数据进行实现。也就是说如果局域8,9,10要给其他局域网里的机器发送数据,他们都要把数据给他们的路由器,然后路由器给目标机器的所在网络的路由器。那个路由器再根据你发的数据选择目标,带到它的局域网里,找到指定机器给它。局域网数据出局域网的端口IP,就是我们平常说的“网关”。

 

路由器又是怎么知道是局域网哪台机器的数据,当数据在经过路由器时,它会做记录。具体的东西,我们就不在这里做解释了。

 

将局域网ip转化为全球外部ip的方法叫做NAT,感兴趣的同学可以去搜索了解下。换句话说,在互联网看来,1局域网的任一PC和2局域网中的任一PC通信,都是路由器1,2之间通信,至于局域网内部的东西,就不是外网的管辖范围了。

 

在局域网中使用的IP地址,是我们人为指明的一些地址,又被叫做专用地址。这些地址只能用于一个机构的内部通信,而不能用于和互联网上的主机通信。换言之,专用地址只能用作本地地址,而不能用作全球地址。在互联网的所有路由器中,对目的地址是专用地址的数据报(又一个概念,简单理解“数据报”就是一段数据),一律不进行转发。

 

那怎样识别一个IP是否是专用地址?

 

专用地址的指派如下:

 

1. 10.0.0.0 到10.255.255.255

2. 172.16.0.0 到 172.31.255.255

3. 192.168.0.0 到 192.168.255.255

 

有了这些东西,应该能明白为什么我说如果PC是局域网IP需要连接到同一个局域网里了吧。因为我们写的程序没办法去控制网关,让路由器发给别的局域网。

 

当然,如果是座机,用的宽带连接。那通过查看ipconfig的本地连接的IP地址,不属于专用地址的范围段,那就不需要关注了。因为如果有外网的IP,它就可以在互联网中传递了呀。不用局限在我们的局域网范围中。

 

学校某些机房的计算机都是有外网IP的,你可以通过它给其他任一具有全球外网IP的PC发送消息。

 

本来想着涉及点代码,概念太多了,我们放到下篇文章吧。这篇文章好好理解下,下次我们就动手来实现下TCP数据传输。

 

这篇文章要好好看啊,不然会影响到后面的逻辑。

 

 

 

 

 

扩展:

域名系统DNS(Domain Name System),用来把便于人们使用的机器的名字转换为IP地址。

csdn的域名来解释:

blog.csdn.net,左右端的net叫做顶级域名,csdn是二级域名,blog是三级域名(或者说是一台host)。域名只是个逻辑地址,并不代表计算机所在的物理地点。

互联网中采用了层次树状结构的命名方法,在寻找主机时,先寻找net域,再在net域中寻找csdn域,在csdn中找到blog那台主机。(域中如果有多个分块,我们把他们叫做“区”)

常见的顶级域名如下:

1)国家顶级域名:如cn表中国,us表美国(但是人家一般不会用,因为整个DNS都是人家的,人家不想服从别人的游戏规则),uk表英国。

2)通用顶级域名:com(公司企业,比如www.baidu.com),net(网络服务机构,csdn就是这种),org(非营利性组织,比如python官网),int(国际组织),edu(美国专用的教育机构,所以我们的教育机构是edu.cn,在我们自己的cn后面偷偷建edu),gov(美国政府部门),mil(美国军事部门)

后来陆续增加的一些顶级域名:

biz(公司和企业),jobs(人力资源管理者),museum(emmmm,不用解释了),name(个人),pro(有证书的专业人员,嗯,就是),travel(旅游业,就是表面意思)。

 

因为我国的顶级域名是cn,因此我们的类别域名主要在二级域名:

类别域名:ac(科研机构),com(工、商、金融等企业),edu(教育机构,我们学校的官网基本都是这种),gov(政府机构),mil(国防机构),net(提供互联网络服务的机构),org(和顶级是一样的)

行政区域名:这个我们不常见,因为我们不用。比如:bj(北京市),js(江苏省)等等。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章