Total Pageviews

Tuesday, 15 October 2024

快速了解必要的网络知识

 

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

如何路由?

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

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

为啥要弄个端口出来?

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

TCP如何做到有连接?

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

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

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

TCP提供了哪些可靠性?

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

真的可靠吗?

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



如何做到真的可靠?

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

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

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

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

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

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

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

为什么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的事情,我觉得还是让教授们去干吧。

为什么到处都是HTTP?

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

如何抓包分析?

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

最后讲点有趣的?

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

No comments:

Post a Comment