快速了解必要的网络知识

 超哥  other  2017-05-18  769  发表评论

这是一篇非常简单的文章,帮助程序员快速地、大致地了解下网络相关的基础知识。写这篇文章的目的当然是想帮助许多对网络知识不了解的朋友用尽量少的时间了解必要的知识,学习网络相关知识当然少不了去看书,如被奉为经典的《TCP/IP详解,但对大多数程序员来说,没那么多时间看完这么枯燥的书,也没必要(嗯,我承认我这里有点政治不正确了),而当我们想快速补习下这方面的知识而去搜索技术博客或者知乎的时候,得到的回答总是去看XXX书吧……So,我打算提供一些便利,只管有用,不管政治正不正确,呵呵。

1,七层还是四层?

说起网络,99%的书总是一开始就七层架构,考试的时候也是乐意考这么个填空题,而我们经常能看到的名词还有“四层架构”,那到底七层还是四层?简单地说:“七层”是ISO标准,“四层”是TCP/IP。ISO是个标准组织,它定义的网络七层架构叫OSI标准,而我们现在广泛使用的TCP/IP网络则实现了其中四层。我们如今说的网络一般来说指的就是TCP/IP网络,所以对我们而言,四层更有现实意义。哪四层?

2,四层架构有哪些相关名词?

应用层 —— HTTP
传输层 —— 端口,TCP
网络层 —— IP,IP地址,路由
链路层 —— MAC地址

我不打算列更多的名词了,有这些够了,也许跟你在别处看到的不同,比如我这里的链路层别处可能叫“网络接口层”,不要在意这些细节……

3,对链路层要了解哪些东西?

我们电脑连接的有线网络99.9%是以太网(还有0.1%我没见过,哈哈),以太网的重要外观就是用双绞线连接电脑网口和交换机网口,这个你肯定懂。


以太网是什么?——就是这玩意儿(简单粗暴^_^)

以太网有以太网的通讯标准,标准由IEEE制定,IEEE和ISO一样是个标准组织,如今的链路层均遵循其标准,这是一系列的标准,相当庞大而复杂(如果细分的话,以太网本身就有多种标准)这个系列标准叫“IEEE 802系列”,IEEE 802系列标准之庞大,包括了几乎所有我们能见到的网络——以太网、2G、3G、4G、WIFI、近场通讯……等等,而每个我们熟悉的名词拆分开又有不同的标准定义,真是烦!——所幸的是我们不需要管那么多,我们只需要知道,在链路层上传输的单元叫“帧”,而帧中包含了“MAC地址”,俗称“物理地址”,链路层不提供路由功能,若无上层协议的支持,链路层只能实现直接连接的节点之间通讯,比如你的电脑的网口连着公司的交换机,只依赖链路层的话,你的电脑就只能跟公司的交换机聊聊天。关心链路层的人更多的是电子工程师或网管,我等码农大致看看就好。

4,如何路由?

网络层是对链路层的封装,最重要的东西应数IP地址,有了IP地址,就有了路由的能力,使得通讯可以跨越多个节点,实现网间通讯了,这相当好理解,交换机理解IP地址和网口的对应关系,它知道这个网络包(前面叫“帧”,这里叫“包”了,哈哈,真会整人)应该往哪个网口丢,如果实在不知道,那么就往“网关”丢,网关再往别处丢,如果IP地址正确,网络也没什么问题,那总归能抵达目的地的,这就是IP协议最重要的任务——路由。

也许你想问:有没有不用IP协议的网络?有啊,蓝牙设备通常就不用(蓝牙的规范且不在IEEE802系列中),其实是没必要,因为它通常只作为单点连接,不需要实现网间通讯,反过来说,如果要实现网间通讯,应该没什么比IP协议更合适的了。

5,为啥要弄个端口出来?

光有IP地址,恐怕还不够,想想我们电脑上N多程序都需要使用网络,那么如何区分程序各自的网络访问包呢?如果分不开,那岂不是乱了套,所以要用传输层包装,传输层包装里多了一个“端口”的东西。例如:我们在电脑上启动Web服务器,默认打开了80端口监听,一个端口只能由一个程序打开,这样就不会乱套了。端口是对网络层的进一步扩展,对上层提供了更友好的使用界面。

6,TCP如何做到有连接?

有了TCP协议,从此有了“连接”的概念,否则你想连接从何而来?从网络层上看,反正都是一个个网络包,前一个包传了过去,后一个包被交换机卡住了,没看出来“连接”在哪里啊,其实“有连接”只是个概念,它的原理是通过那些“握手”、“挥手”、“心跳”、“应答”和“超时检查”在传输的双方保持了一些“状态”,所以,准确说是“看起来有连接”而已。

7,对开发者而言网络到底是怎样的存在?

那传输层体现在应用程序上又是个怎么样的东西?——是Socket。网络编程是件挺头疼的事情,从一开始就是,所以弄了个Socket的概念出来方便我们程序员访问网络,这最早是出现在Unix系统上的,后来Windows也借鉴了这套方法,搞了套自己的Socket API,用起来大家都很像。总体的编程思想大概就是(以TCP客户端为例):指定目标服务器IP地址和端口,连接,获取到了Socket(通常用一个整型数来表示),以后就往这个Socket上读写东西(跟读写本地文件有些类似)来实现收发,中间还可以用一些函数查询这个Socket的状态,不用了之后就close掉这个Socket以断开TCP连接。这是比较简单的情形,事实上,为了更好地挖掘系统的潜能,提高系统的网络吞吐量,不同的系统还祭出了自己的一些所谓高级网络编程模型,如Windows的完成端口,Linux的epoll等,但对程序而言,网络访问依旧是对Socket进行操作。实际上,程序员们仍然认为Socket是比较底层的东西,需要进一步抽象,于是诞生了如HttpContext之类东西,大伙们不再需要直接操作Socket了,甚至都可以不知道Socket的存在。

8,TCP提供了哪些可靠性?

主要两方面:成功保障和次序保障。对于成功保障,很好理解,如果网络包发送成功,对方应答一下,发送方便知道了,认为接收方一定成功接收;而次序保障,则是通过在传输包中加入一个次序标识来实现的,当传输包抵达对方节点时,TCP根据次序标识对收到的内容重新“组包”。那么,现在考虑一下这种可能性:发送方的包确实已经发送至接收方了,但接收方的应答却没有成功发往发送方,这时候是不是会错误判断为发送失败?——答案是肯定的,所以TCP有个重发机制,当迟迟没收到应答的时候,会尝试重发数次,如果依旧出现没有应答,那就真的判定为失败了,所以TCP能知道“一定成功”,但却无法知道“一定失败”。

9,真的可靠吗?

TCP连接为我们的程序通信创造了一条“通道”,我们程序间发送数据就变得有保障起来,那根据上面提供的这些信息,你认为这条通道有多牢靠?——事实上是这样的:如果网络系统确确实实按照了既定的规则去工作的话,可靠性是显而易见的,但,谁说网络上途径的这么多节点每个都会老老实实工作?有没有可能在传输过程中将我们的包截获并篡改?或者干脆就直接造一个假的包冒充发送?——我说,这种事情不光可能,而且一直在发生!不需要我证明给你看,你自己想想,有没有自己建了一个好端端的网站,别人打开的时候却无缘无故弹出广告之类的事情发生?而你确信自己的网站没问题,没中病毒之类的……恭喜你啊,你的网站被电信劫持了,你的页面在传输中被篡改了,HTTP协议是基于TCP的,所以你说从这个角度看可不可靠?


一个典型的http劫持的例子,看看右下角这个连滚动条都挡住了的广告

10,如何做到真的可靠?

当然是使用SSL,SSL现在又叫TLS,但旧名字叫惯了就沿用下来,它是在传输层上包了一层加密,这层加密实现了这些功能:

  • 密钥不直接在网络上传输(通过一个非对称加密实现)
  • 所有数据皆经过加密,即便截获也没用
  • 如果试图伪造或篡改数据包,那接收方一定知道数据不合法并丢弃

另外SSL还可以通过层级证书手段,对传输方的身份进行认证。某大牛说过:“没有SSL的安全都是在假装安全。”用了SSL之后,传输安全了,网站图标绿了,框也不弹了。另外注意:SSL是用来防范“中间人攻击”的手段,至于主机上中了木马之类的,它却无能为力。

11,关于TCP还有哪些东西没谈?

太多了,比如流量控制,但我不打算说,否则此文就没什么意义了。一般来说,需要的时候才去学比较好,虽然技不压身,这个谁都清楚,可学习技术要花不少时间,而且最关键的是:人是会遗忘的,尤其是学而不用的话。

12,不是还有个叫UDP的东西吗?

传输层有两套协议,一是前面提到的TCP,另一是UDP,TCP如今大行其道,而UDP则用得很少,UDP是无连接协议,比TCP简单得多,最形象的比喻就是以前的“写信”,我写好信了之后(发送的数据),把信装进信封(UDP包),写上地址和收件人(IP地址端口),扔进邮箱(send)即可,既不等待应答,也不保证次序,也没有连接通道的概念。由于UDP形式如此简单,所以在以前某些特定的环境里,它传输效率高于TCP,所以被用于一些对传输性能要求比较苛刻的场景,如网游,但现在世道变了,网络资源不再像当年那么紧张,TCP显然是更好的选择。当然了,还有些特殊场合是非用UDP不可的,如实现局域网广播,这个TCP做不到。

13,为什么IP地址仍然不枯竭?

我们常说的IP地址指的是IPv4地址,例如“10.186.3.21”,其实它是个32位整型,表面上看最高可支持2的32次方个节点,即42亿多,事实上远远没那么多,首先其中有很多属于“保留地址”,做特殊用途使用的,其次,大量优质地址段被一些寡头占据了(主要是美国政府及美国一些科技公司),所以剩下的可用地址可谓宝贵,国人早意识到了这点,所以很早就发力研究IPv6,我在N年前就看到过国内XX大学的教授在带学生研究IPv6的一些报道,号称我们走在了世界领先,报道还做了一些技术细节介绍,如IPv4是“xxx.xxx.xxx.xxx”这样(四段),而IPv6则变成了“xxx.xxx.xxx.xxx.xxx.xxx”(六段),所以地址多了很多……我晕!我虽然读书少,但也少拿这个来糊弄我了,事实上的IPv6地址高达128位,与之最接近的是什么?——作为程序员,马上回答!UUID啊!UUID不也128位么?——有点跑题了,回到正题,为啥现在IP地址仍然不枯竭?——那是因为我们绝大多数人都没有公网地址。这个你可以马上自己试试,比如你的手机,连着3G,貌似接入了公网了,你还可以在设置中看到自己的IP地址,这是运营商分配的,但我向你保证,这个地址其实是运营商的局域网地址,要证明很简单,你用手机浏览器打开http://www.ip138.com/看看自己的“公网IP”,是不是不一样?也就是说,你想用手机当服务器让Internet上的用户来连是不行的。虽然没有公网,但通过NAT,我们照样访问Internet没啥问题。至于推IPv6的事情,我觉得还是让教授们去干吧。

14,为什么到处都是HTTP?

我想那是因为——简单!HTTP是一个基于TCP的请求/应答模型的协议,客户端一问,服务器一答,就这么简单,跟程序里的函数调用似的,所以很多RPC在底下也使用了HTTP协议,HTTP协议还使用了非常易读的文本格式,一出就被广泛追捧。如今广泛使用的HTTP 1.1协议最后的一次修订是在1999年,距今17年了,看吧,越是简单基础的东西越不容易变化。

15,如何抓包分析?

如果仅仅是想抓取HTTP包的话,IE的HttpWatch Pro是不错的东西,Firefox下有个跟它类似的叫“httpfox”,我不知道现在还在不在,chrome的话本身也提供了一些简单的查看http包的功能。想专业一点的话可以考虑用Fiddler,Windows环境下的抓包利器,Mac下则用Charles。当然了,最强大(但也很复杂)的抓包神器当然是Wireshark,这玩意儿甚至能看链路层的帧。

16,最后讲点有趣的?

很多年前我的公司由于网口少,我跟一个同事共用一个网口(通过一个集线器),集线器这玩意儿跟交换机不同,它不会“路由”,收到任何包都是直接广播到所有网口,于是我用抓包工具抓了一些网络包,这位同事用MSN的聊天信息我全部都能看到,由于这样,我后来一直不敢用MSN在公司里乱说话,你想MSN这么烂的东西为啥公司喜欢让我们用呢?不过几年后MSN用户就几乎绝迹了。

所有评论
加载评论 ...
发表评论