协议专栏特别福利 | 答疑解惑第一期
下载APP
关闭
渠道合作
推荐作者
协议专栏特别福利 | 答疑解惑第一期
2018-08-20 刘超 来自北京
《趣谈网络协议》
课程介绍
讲述:刘超
时长14:41大小6.73M
你好,我是刘超。
首先,感谢大家关注并在留言区写下近 3000 条留言。留言太多,没有及时回复,一是每周写三篇文章压力真的挺大的。为了保质保量地产出,晚上和周末的时间基本上都搭进去了。二是很多人的留言非常有深度,水平很高,提的问题一两句话解释不清楚。
每一节结尾我基本都会留两个思考题,其中第一个问题是启发思考的,是对本节内容的延伸学习;第二个问题是为了引出下一节,下一节的内容其实就是答案。
所以我会回答一下每一节的第一个问题,并列出第一个同我的思路最相近的同学,并对留言中比较有代表性的问题,做一个统一的回答,顺便也实现之前要送知识图谱和奖励礼券的承诺。
当然,这并不能说明我的回答就是一定是正确的或者全面的,有很多同学的留言有非常大的信息量,甚至更广的思路,也对这些同学表示感谢。还有些同学指出了我的错误,也感谢你们。
《第 1 讲 | 为什么要学习网络协议?》
课后思考题
当网络包到达一个城关的时候,可以通过路由表得到下一个城关的 IP 地址,直接通过 IP 地址找就可以了,为什么还要通过本地的 MAC 地址呢?
徐良红同学说的比较接近。在网络包里,有源 IP 地址和目标 IP 地址、源 MAC 地址和目标 MAC 地址。从路由表中取得下一跳的 IP 地址后,应该把这个地址放在哪里呢?如果放在目标 IP 地址里面,到了城关,谁知道最终的目标在哪里呢?所以要用 MAC 地址。
所谓的下一跳,看起来是 IP 地址,其实是要通过 ARP 得到 MAC 地址,将下一跳的 MAC 地址放在目标 MAC 地址里面。
留言问题
1.MAC 地址可以修改吗?
我查了一下,MAC(Media Access Control,介质访问控制)地址,也叫硬件地址,长度是 48 比特(6 字节),由 16 进制的数字组成,分为前 24 位和后 24 位。
前 24 位叫作组织唯一标志符(Organizationally Unique Identifier,OUI),是由 IEEE 的注册管理机构给不同厂家分配的代码,用于区分不同的厂家。后 24 位是厂家自己分配的,称为扩展标识符。同一个厂家生产的网卡中 MAC 地址后 24 位是不同的。
也就是说,MAC 本来设计为唯一性的,但是后来设备越来越多,而且还有虚拟化的设备和网卡,有很多工具可以修改,就很难保证不冲突了。但是至少应该保持一个局域网内是唯一的。
MAC 的设计,使得即便不能保证绝对唯一,但是能保证一个局域网内出现冲突的概率很小。这样,一台机器启动的时候,就能够在没有 IP 地址的情况下,先用 MAC 地址进行通信,获得 IP 地址。
好在 MAC 地址是工作在一个局域网中的,因而即便出现了冲突,网络工程师也能够在自己的范围内很快定位并解决这个问题。这就像我们生成 UUID 或者哈希值,大部分情况下是不会冲突的,但是如果碰巧出现冲突了,采取一定的机制解决冲突就好。
2.TCP 重试有没有可能导致重复下单?
那什么时候会导致重复下单呢?因为网络原因或者服务端错误,导致 TCP 连接断了,这样会重新发送应用层的请求,也即 HTTP 的请求会重新发送一遍。
如果服务端设计的是无状态的,它记不住上一次已经发送了一次请求。如果处理不好,就会导致重复下单,这就需要服务端除了实现无状态,还需要根据传过来的订单号实现幂等,同一个订单只处理一次。
还会有的现象是请求被黑客拦截,发送多次,这在 HTTPS 层可以有很多种机制,例如通过 Timestamp 和 Nonce 随机数联合起来,然后做一个不可逆的签名来保证。
3.TCP 报平安的包是原路返回吗?
谢谢语鬼同学的指正。这里的比喻不够严谨,容易让读者产生误会,这里的原路返回的意思是原样返回,也就是返回也是这个过程,不一定是完全一样的路径。
4.IP 地址和 MAC 地址的关系?
我个人认为,即便有了 IPv6,也不会改变当前的网络分层模式,还是 IP 层解决远程定位问题,只不过改成 IPv6 了,到了本地,还是通过 MAC。
5. 如果最后一跳的时候,IP 改变了怎么办?
对于 IP 层来讲,当包到达最后一跳的时候,原来的 IP 不存在了。比如网线拔掉了,或者服务器直接宕机了,则 ARP 就找不到了,所以这个包就会发送失败了。对于 IP 层的工作就结束了。
但是 IP 层之上还有 TCP 层,TCP 会重试的,包还是会重新发送,但是如果服务器没有启动起来,超过一定的次数,最终放弃。
如果服务器重启了,IP 还是原来的 IP 地址,这个时候 TCP 重新发送的一个包的时候,ARP 是能够得到这个地址的,因而会发到这台机器上来,但是机器上面没有启动服务端监听那个端口,于是会发送 ICMP 端口不可达。
如果服务器重启了,服务端也重新启动了,也在监听那个端口了,这个时候 TCP 的服务端由于是新的,Sequence Number 根本对不上,说明不是原来的连接,会发送 RST。
那有没有可能有特殊的场景 Sequence Number 也能对的上呢?按照 Sequence Number 的生成算法,是不可能的。
但是有一个非常特殊的方式,就是虚拟机的热迁移,从一台物理机迁移到另外一台物理机,IP 不变,MAC 不变,内存也拷贝过去,Sequence Number 在内存里面也保持住了,在迁移的过程中会丢失一两个包,但是从 TCP 来看,最终还是能够连接成功的。
6.TCP 层报平安,怎么确认浏览器收到呢?
TCP 报平安,只能保证 TCP 层能够收到,不保证浏览器能够收到。但是可以想象,如果浏览器是你写的一个程序,你也是通过 socket 编程写的,你是通过 socket,建立一个 TCP 的连接,然后从这个连接里面读取数据,读取的数据就是 TCP 层确认收到的。
这个读取的动作是本地系统调用,大部分情况下不会失败的。如果读取失败呢,当然本地会报错,你的 socket 读取函数会返回错误,如果你是浏览器程序的实现者,你有两种选择,一个是将错误报告给用户,另一个是重新发送一次请求,获取结果显示给用户。
7.ARP 协议属于哪一层?
ARP 属于哪个层,一直是有争议的。比如《TCP/IP 详解》把它放在了二层和三层之间,但是既然是协议,只要大家都遵守相同的格式、流程就可以了,在实际应用的时候,不会有歧义的,唯一有歧义的是参加各种考试,让你做选择题,ARP 属于哪一层?平时工作中咱不用纠结这个。
《第 2 讲 | 网络分层的真实含义是什么?》
课后思考题
如果你也觉得总经理和员工的比喻不恰当,你有更恰当的比喻吗?
我觉得,寄快递和寄信这两个比喻都挺好的。关键是有了封装和解封装的过程。有的同学举了爬楼,或者公司各层之间的沟通,都无法体现封装和解封装的过程。
留言问题
1. 为什么要分层?
是的,仅仅用复杂性来解释分层,太过牵强了。
其实这是一个架构设计的通用问题,不仅仅是网络协议的问题。一旦涉及到复杂的逻辑,或者软件需求需要经常变动,一般都会通过分层来解决问题。
假如我们将所有的代码都写在一起,但是产品经理突然想调整一下界面,这背后的业务逻辑变不变,那要不要一起修改呢?所以会拆成两层,把 UI 层从业务逻辑中分离出来,调用 API 来进行组合。API 不变,仅仅界面变,是不是就不影响后台的代码了?
为什么要把一些原子的 API 放在基础服务层呢?将数据库、缓存、搜索引擎等,屏蔽到基础服务层以下,基础服务层之上的组合逻辑层、API 层都只能调用基础服务层的 API,不能直接访问数据库。
比如我们要将 Oracle 切换成 MySQL。MySQL 有一个库,分库分表成为 4 个库。难道所有的代码都要修改吗?当然只要把基础服务层屏蔽,提供一致的接口就可以了。
网络协议也是这样的。有的想基于 TCP,自己不操心就能够保证到达;有的想自己实现可靠通信,不基于 TCP,而使用 UDP。一旦分了层就好办了,定制化后要依赖于下一层的接口,只要实现自己的逻辑就可以了。如果 TCP 的实现将所有的逻辑耦合在了整个七层,不用 TCP 的可靠传输机制都没有办法。
2. 层级之间真实的调用方式是什么样的?
如果文中是一个逻辑图,这个问题其实已经到实现层面上来了,需要看 TCP/IP 的协议栈代码了。这里首先推荐一本书《深入理解 Linux 网络技术内幕》。
其实下层的协议知道上层协议的,因为在每一层的包头里面,都会有上一层是哪个协议的标识,所以不是一个回调函数,每一层的处理函数都会在操作系统启动的时候,注册到内核的一个数据结构里面,但是到某一层的时候,是通过判断到底是哪一层的哪一个协议,然后去找相应的处理函数去调用。
接着,UDP 层会调用 IP 层的函数。
然后,IP 层通过路由判断,最终将包发给下一层。
发送的时候,要进行 ARP。如果有 MAC,则调用二层的函数,neigh 其实就是邻居系统,是二层的意思。
接收的时候,会调用这里的接收函数。
这个函数会根据是 ARP 或者 IP 等,选择调用不同的函数。如果是 IP 协议的话,就调用这里的函数。
这里也有路由判断。如果是本地的,则继续往上提交这个结构。
接着,还是根据 IP 头里面的协议号,来判断是什么协议,从而调用什么函数。下面这个是对 UDP 的调用。
3. 什么情况下会有下层没上层?
有时候我们自己写应用的时候,不一定是直接调用应用层协议的接口,例如 HTTP 等,而是自己写 Socket 编程,来约定应用层的协议。再如,ping 也是一个应用,但是它没有用传输层的协议,而是用了 ICMP 的协议。
最后,感谢留言次数前 15 名的同学,谢谢你们持之以恒的学习,相信你们一定有自己的收获。(统计数据截止到 2018 年 8 月 8 日)
同时感谢第 1 讲、第 2 讲中对内容有深度思考和提出问题的同学。我会为你们送上奖励礼券和知识图谱。(稍后运营同学会发送短信通知。)
欢迎你继续提问!
分享给需要的人,Ta购买本课程,你将得20元
生成海报并分享
赞 16
提建议
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
上一篇
第40讲 | 搭建一个网络实验环境:授人以鱼不如授人以渔
下一篇
协议专栏特别福利 | 答疑解惑第二期
精选留言(18)
- ╯梦深处゛2018-08-20老师能不能去分享一些抓包和网络包分析相关的内容,带着问题进行抓包和分析,这样应该可以让之前学习的理论更好的理解和应用,谢谢啦🙏29
- salmonl2019-08-22学习完整个专栏,收获确实不小,关于协议的几个困惑的地方,查了一些资料没有解惑。不知道这个提问刘老师还能不能看到。 问题一:一个数据包从上层往下层传,最终是传到物理层, 已经封包完成,那么是如何使用TCP建立的连接传输呢,又回去了? 问题二:为什么TCP建立连接的适合看似很简单(没有层层封包和拆包),发数据包的时候那么费劲,连接相当于管道,直接顺着管道传输不就完事了么,还需要封包和拆包? 问题三:建立TCP连接像不像先拨通电话呢,数据传输的过程跟对话一样复杂,那么建连的时候TCP包中只有源端口和目标端口,是怎么找到目标主机的呢? 多谢!展开
作者回复: 问题一:所谓的连接,没有在通路上做任何事情,只是在tcp层添加了一些用于重传的数据结构。所以所谓的连接,除了tcp层能够意识到有连接,其他层次,以及通路上都意识不到有连接的存在。所以底层管你上层有没有连接,我就傻傻的该传输就传输,如果丢了就丢了,我底层也不管。等真的丢了,tcp层的数据结构会发现丢了,要重传,底层也意识不到,这是一个重传的包,反正你上层让我传,我就传,如果丢了还是丢了就丢了。 问题二:连接不是管道,除了tcp层的数据结构,没有其他的地方知道这个连接的存在。同样,问题三,tcp连接可不是拨通电话,先建立一个连接。 tcp层的连接纯属这一层的数据结构一厢情愿的要保持顺序,不丢等。所以tcp层要做很多的工作。 所以这个问题,您对tcp连接是有误解的。再比喻一下,就是你是tcp层,你父母是应用层,高铁以及运输人员是IP层或者更底层。 你tcp告诉你父母应用层,现在从北京去上海可以包一个车厢了,其实底层也即高铁是不允许包车厢的,都是你多次跑火车站,自己一个一个的座位买,今天买不到一整个车厢,就换另一天,直到有一天你终于买了一整个车厢的票,然后你父母享受到了包车厢的服务。那问题一,高铁站当然不知道你是包车厢,反正你有票就做呗,谁知道你有这个执念,一定要包一整个车厢。 建立连接可不简单,看似三次握手,但是双方都要建立数据结构,就像你要制造一个假象给你父母说这个车厢是随便就能包了。等到了目的地,假设你有个接站的兄弟,他也要制造一个假象给你父母,车厢是随便就能包了
共 3 条评论17 - Ying|Ucloud2018-11-15针对第一个问题,为什么有IP了还要MAC,基本大家都已经说了,我再补充一点,首先你要知道交换机怎么判断是该二层转发还是三层转发,交换机只有收到MAC地址为自己的时候才会进行拆二层进行三层转发,否则就为二层转发共 1 条评论7
- Hurt2018-08-20我也想要~~~
作者回复: 有你的名字呀
共 2 条评论5 - 凉凉2019-06-09”如果服务器重启了,服务端也重新启动了,也在监听那个端口了,这个时候 TCP 的服务端由于是新的,Sequence Number 根本对不上,说明不是原来的链接“ 这句话怎么理解,,服务端是新的,序号为啥对不上,,, 不是原来的连接意思是一条新的连接?一条连接不是由(source ip, source port, dst ip, dst port)这四元组决定的吗,这些都没变为啥是新的连接?
作者回复: seq num标识连接。seq num匹配不上,说明连接不匹配
2 - 蚂蚁内推+v2018-08-21Nonce随机数的应用 方便刘老师介绍下吗 我理解是是服务端给客户端的盐2
- balancer2018-08-20老师如果能后面加几节实操课,比如 哪LVS 的各种模式配置来举例,分析,那课程就完美了共 1 条评论2
- zcpromising2018-08-20谢谢老师精彩用心的讲解,受益匪浅,学习完之后还有惊喜,太感谢老师了。期待老师下个专栏2
- 芒果2020-03-11收货满满啊1
- 啦啦啦2018-08-24我我想要1
- 蚂蚁内推+v2018-08-21Nonce 这块技术 可能了解不是特别清晰 方便老师介绍下吗 我理解是服务端发给客户端的随机数 具体怎么应用方便老师分享下吗2
- 夏洛克的救赎2018-08-20信息量有点大1
- Marty2021-06-02「.如果服务器重启了,IP 还是原来的 IP 地址,这个时候 TCP 重新发送的一个包的时候,ARP 是能够得到这个地址的,因而会发到这台机器上来,但是机器上面没有启动服务端监听那个端口,于是会发送 ICMP 端口不可达。」 這句描述有點疑問,ICMP 是要ping 服務器才會回的吧?對著沒監聽的端口發tcp 沒人收就等timeout了 服務器不會發回icmp 包回覆你的吧?共 1 条评论
- Geek_wadehao2020-06-22虚拟机的热迁移有点不太明白。迁移前后Ip不变,mac不变,这对客户端而言是很好,保持了访问基本不中断(纵向流量),但迁移时的拷贝内存的流量在网络上传输时的源mac,目的mac,源ip,目的ip是什么呀?不可能都一样吧?如何通信呢(横向流量)?
- 子杨2020-02-24超哥,我们家用路由器做 NAT 转换的时候,是不是会修改源和目的的 IP 和端口,发送的时候会把源地址和端口改成路由器自己的地址和端口,接收的时候则把目的地址和端口改成局域网主机的。
- Z.Clark2019-12-19老师,我初学计算机网络,有个问题不明白。 请问,无状态路由 是什么呢?它是怎样的基本思想呢? (这也是去年的一道计网考研真题) 谢谢老师解答!
- 有朋自远方来2019-11-14断断续续的听。 每天五分钟。 补充基础知识。 也想要奖品 (最新评论)
- stark2019-08-21这个课程真的是超级精彩,收益良多
作者回复: 谢谢