网络编程懒人入门(二):快速理解网络通信协议(下篇)

转自即时通讯网:http://www.52im.net/

原作者:阮一峰(ruanyifeng.com),本文由即时通讯网重新整理发布,感谢原作者的无私分享。

1、前言

本文上篇《网络编程懒人入门(一):快速理解网络通信协议(上篇)》分析了互联网的总体构思,从下至上,每一层协议的设计思想。基于知识连贯性的考虑,建议您先看完上篇后再来阅读本文。
本文从设计者的角度看问题,今天我想切换到用户的角度,看看用户是如何从上至下,与这些协议互动的。

 

2、系列文章

本文是系列文章中的第2篇,本系列文章的大纲如下:

  • 《网络编程懒人入门(一):快速理解网络通信协议(上篇)》(本文)
  • 《网络编程懒人入门(二):快速理解网络通信协议(下篇)》
  • 《网络编程懒人入门(三):快速理解TCP协议一篇就够》
  • 《网络编程懒人入门(四):快速理解TCP和UDP的差异》
  • 《网络编程懒人入门(五):快速理解为什么说UDP有时比TCP更有优势》
  • 《网络编程懒人入门(六):史上最通俗的集线器、交换机、路由器功能原理入门》
  • 《网络编程懒人入门(七):深入浅出,全面理解HTTP协议》
  • 《网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接》


本站的《脑残式网络编程入门》也适合入门学习,本系列大纲如下:

  • 《脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手》
  • 《脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?》
  • 《脑残式网络编程入门(三):HTTP协议必知必会的一些知识》
  • 《脑残式网络编程入门(四):快速理解HTTP/2的服务器推送(Server Push)》


如果您觉得本系列文章过于基础,您可直接阅读《不为人知的网络编程》系列文章,该系列目录如下:

  • 《不为人知的网络编程(一):浅析TCP协议中的疑难杂症(上篇)》
  • 《不为人知的网络编程(二):浅析TCP协议中的疑难杂症(下篇)》
  • 《不为人知的网络编程(三):关闭TCP连接时为什么会TIME_WAIT、CLOSE_WAIT》
  • 《不为人知的网络编程(四):深入研究分析TCP的异常关闭》
  • 《不为人知的网络编程(五):UDP的连接性和负载均衡》
  • 《不为人知的网络编程(六):深入地理解UDP协议并用好它》


关于移动端网络特性及优化手段的总结性文章请见:

  • 《现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障》
  • 《移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”》
  • 《移动端IM开发者必读(二):史上最全移动弱网络优化方法总结》

 

3、参考资料

  • 《TCP/IP详解 - 第11章·UDP:用户数据报协议》
  • 《TCP/IP详解 - 第17章·TCP:传输控制协议》
  • 《TCP/IP详解 - 第18章·TCP连接的建立与终止》
  • 《TCP/IP详解 - 第21章·TCP的超时与重传》
  • 《通俗易懂-深入理解TCP协议(上):理论基础》
  • 《通俗易懂-深入理解TCP协议(下):RTT、滑动窗口、拥塞处理》
  • 《理论经典:TCP协议的3次握手与4次挥手过程详解》
  • 《理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程》
  • 《计算机网络通讯协议关系图(中文珍藏版)》
  • 《高性能网络编程(一):单台服务器并发TCP连接数到底可以有多少》
  • 《高性能网络编程(二):上一个10年,著名的C10K并发连接问题》
  • 《高性能网络编程(三):下一个10年,是时候考虑C10M并发问题了》
  • 《高性能网络编程(四):从C10K到C10M高性能网络应用的理论探索》
  • 《简述传输层协议TCP和UDP的区别》
  • 《为什么QQ用的是UDP协议而不是TCP协议?》
  • 《移动端即时通讯协议选择:UDP还是TCP?》

 

4、一个小节

先对前面的内容,做一个小结(详见本文上篇《网络编程懒人入门(一):快速理解网络通信协议(上篇)》)。
我们已经知道,网络通信就是交换数据包。电脑A向电脑B发送一个数据包,后者收到了,回复一个数据包,从而实现两台电脑之间的通信。

数据包的结构,基本上是下面这样:

网络编程懒人入门(二):快速理解网络通信协议(下篇)_1.png

发送这个包,需要知道两个地址:

  • * 对方的MAC地址;
  • * 对方的IP地址。

有了这两个地址,数据包才能准确送到接收者手中。但是,前面说过,MAC地址有局限性,如果两台电脑不在同一个子网络,就无法知道对方的MAC地址,必须通过网关(gateway)转发。

网络编程懒人入门(二):快速理解网络通信协议(下篇)_2.jpg

上图中,1号电脑要向4号电脑发送一个数据包。它先判断4号电脑是否在同一个子网络,结果发现不是(后文介绍判断方法),于是就把这个数据包发到网关A。网关A通过路由协议,发现4号电脑位于子网络B,又把数据包发给网关B,网关B再转发到4号电脑。

1号电脑把数据包发到网关A,必须知道网关A的MAC地址。所以,数据包的目标地址,实际上分成两种情况:

场景数据包地址
同一个子网络对方的MAC地址,对方的IP地址
非同一个子网络网关的MAC地址,对方的IP地址

发送数据包之前,电脑必须判断对方是否在同一个子网络,然后选择相应的MAC地址。接下来,我们就来看,实际使用中,这个过程是怎么完成的。

 

5、用户的上网设置

5.1 静态IP地址

你买了一台新电脑,插上网线,开机,这时电脑能够上网吗?

网络编程懒人入门(二):快速理解网络通信协议(下篇)_3.jpg

通常你必须做一些设置。有时,管理员(或者ISP)会告诉你下面四个参数,你把它们填入操作系统,计算机就能连上网了:

  • * 本机的IP地址;
  • * 子网掩码;
  • * 网关的IP地址;
  • * DNS的IP地址。

网络编程懒人入门(二):快速理解网络通信协议(下篇)_4.png

这四个参数缺一不可,后文会解释为什么需要知道它们才能上网。由于它们是给定的,计算机每次开机,都会分到同样的IP地址,所以这种情况被称作"静态IP地址上网"。但是,这样的设置很专业,普通用户望而生畏,而且如果一台电脑的IP地址保持不变,其他电脑就不能使用这个地址,不够灵活。出于这两个原因,大多数用户使用"动态IP地址上网"。

 

5.2动态IP地址

所谓"动态IP地址",指计算机开机后,会自动分配到一个IP地址,不用人为设定。它使用的协议叫做DHCP协议。
这个协议规定,每一个子网络中,有一台计算机负责管理本网络的所有IP地址,它叫做"DHCP服务器"。新的计算机加入网络,必须向"DHCP服务器"发送一个"DHCP请求"数据包,申请IP地址和相关的网络参数。
前面说过,如果两台计算机在同一个子网络,必须知道对方的MAC地址和IP地址,才能发送数据包。但是,新加入的计算机不知道这两个地址,怎么发送数据包呢?DHCP协议做了一些巧妙的规定。

 

5.3DHCP协议

首先,它是一种应用层协议,建立在UDP协议之上,所以整个数据包是这样的:

网络编程懒人入门(二):快速理解网络通信协议(下篇)_5.png

  • 1)最前面的"以太网标头":设置发出方(本机)的MAC地址和接收方(DHCP服务器)的MAC地址。前者就是本机网卡的MAC地址,后者这时不知道,就填入一个广播地址:FF-FF-FF-FF-FF-FF。
  • 2)后面的"IP标头":设置发出方的IP地址和接收方的IP地址。这时,对于这两者,本机都不知道。于是,发出方的IP地址就设为0.0.0.0,接收方的IP地址设为255.255.255.255。
  • 3)最后的"UDP标头":设置发出方的端口和接收方的端口。这一部分是DHCP协议规定好的,发出方是68端口,接收方是67端口。

这个数据包构造完成后,就可以发出了。以太网是广播发送,同一个子网络的每台计算机都收到了这个包。因为接收方的MAC地址是FF-FF-FF-FF-FF-FF,看不出是发给谁的,所以每台收到这个包的计算机,还必须分析这个包的IP地址,才能确定是不是发给自己的。当看到发出方IP地址是0.0.0.0,接收方是255.255.255.255,于是DHCP服务器知道"这个包是发给我的",而其他计算机就可以丢弃这个包。

接下来,DHCP服务器读出这个包的数据内容,分配好IP地址,发送回去一个"DHCP响应"数据包。这个响应包的结构也是类似的,以太网标头的MAC地址是双方的网卡地址,IP标头的IP地址是DHCP服务器的IP地址(发出方)和255.255.255.255(接收方),UDP标头的端口是67(发出方)和68(接收方),分配给请求端的IP地址和本网络的具体参数则包含在Data部分。

新加入的计算机收到这个响应包,于是就知道了自己的IP地址、子网掩码、网关地址、DNS服务器等等参数。

 

5.4 上网设置:小结

这个部分,需要记住的就是一点:不管是"静态IP地址"还是"动态IP地址",电脑上网的首要步骤,是确定四个参数。
这四个值很重要,值得重复一遍:

  • * 本机的IP地址;
  • * 子网掩码;
  • * 网关的IP地址;
  • * DNS的IP地址。

有了这几个数值,电脑就可以上网"冲浪"了。接下来,我们来看一个实例,当用户访问网页的时候,互联网协议是怎么运作的。

 

6.一个实例:访问网页

6.1本机参数

我们假定,经过上一节的步骤,用户设置好了自己的网络参数:

  • * 本机的IP地址:192.168.1.100;
  • * 子网掩码:255.255.255.0;
  • * 网关的IP地址:192.168.1.1;
  • * DNS的IP地址:8.8.8.8。

然后他打开浏览器,想要访问Google,在地址栏输入了网址:www.google.com。

网络编程懒人入门(二):快速理解网络通信协议(下篇)_6.png

这意味着,浏览器要向Google发送一个网页请求的数据包。

 

6.2DNS协议

我们知道,发送数据包,必须要知道对方的IP地址。但是,现在,我们只知道网址www.google.com,不知道它的IP地址。DNS协议可以帮助我们,将这个网址转换成IP地址。已知DNS服务器为8.8.8.8,于是我们向这个地址发送一个DNS数据包(53端口)。

网络编程懒人入门(二):快速理解网络通信协议(下篇)_7.png

然后,DNS服务器做出响应,告诉我们Google的IP地址是172.194.72.105。于是,我们知道了对方的IP地址。

 

6.3 子网掩码

接下来,我们要判断,这个IP地址是不是在同一个子网络,这就要用到子网掩码。
已知子网掩码是255.255.255.0,本机用它对自己的IP地址192.168.1.100,做一个二进制的AND运算(两个数位都为1,结果为1,否则为0),计算结果为192.168.1.0;然后对Google的IP地址172.194.72.105也做一个AND运算,计算结果为172.194.72.0。这两个结果不相等,所以结论是,Google与本机不在同一个子网络。
因此,我们要向Google发送数据包,必须通过网关192.168.1.1转发,也就是说,接收方的MAC地址将是网关的MAC地址。

 

6.4 应用层协议

浏览网页用的是HTTP协议,它的整个数据包构造是这样的:

网络编程懒人入门(二):快速理解网络通信协议(下篇)_9.png

HTTP部分的内容,类似于下面这样:

GET / HTTP/1.1
Host: [url=http://www.google.com]www.google.com[/url]
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 6.1) ......
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8
Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3
Cookie: ... ...

我们假定这个部分的长度为4960字节,它会被嵌在TCP数据包之中。

 

6.5 TCP协议

TCP数据包需要设置端口,接收方(Google)的HTTP端口默认是80,发送方(本机)的端口是一个随机生成的1024-65535之间的整数,假定为51775。TCP数据包的标头长度为20字节,加上嵌入HTTP的数据包,总长度变为4980字节。

 

6.6 IP协议

然后,TCP数据包再嵌入IP数据包。IP数据包需要设置双方的IP地址,这是已知的,发送方是192.168.1.100(本机),接收方是172.194.72.105(Google)。IP数据包的标头长度为20字节,加上嵌入的TCP数据包,总长度变为5000字节。

 

6.7 协议

最后,IP数据包嵌入以太网数据包。以太网数据包需要设置双方的MAC地址,发送方为本机的网卡MAC地址,接收方为网关192.168.1.1的MAC地址(通过ARP协议得到)。

以太网数据包的数据部分,最大长度为1500字节,而现在的IP数据包长度为5000字节。因此,IP数据包必须分割成四个包。因为每个包都有自己的IP标头(20字节),所以四个包的IP数据包的长度分别为1500、1500、1500、560。(1480+1480+1480+560)

网络编程懒人入门(二):快速理解网络通信协议(下篇)_10.png

 

6.8 服务器端响应

经过多个网关的转发,Google的服务器172.194.72.105,收到了这四个以太网数据包。根据IP标头的序号,Google将四个包拼起来,取出完整的TCP数据包,然后读出里面的"HTTP请求",接着做出"HTTP响应",再用TCP协议发回来。

本机收到HTTP响应以后,就可以将网页显示出来,完成一次网络通信。

网络编程懒人入门(二):快速理解网络通信协议(下篇)_10.jpg

这个例子就到此为止,虽然经过了简化,但它大致上反映了互联网协议的整个通信过程。

 

附录:更多网络编程资料

《技术往事:改变世界的TCP/IP协议(珍贵多图、手机慎点)》
《UDP中一个包的大小最大能多大?》
《Java新一代网络编程模型AIO原理及Linux系统AIO介绍》
《NIO框架入门(一):服务端基于Netty4的UDP双向通信Demo演示》
《NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示》
《NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战》
《NIO框架入门(四):Android与MINA2、Netty4的跨平台UDP双向通信实战》
《P2P技术详解(一):NAT详解——详细原理、P2P简介》
《P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解》
《P2P技术详解(三):P2P技术之STUN、TURN、ICE详解》
《通俗易懂:快速理解P2P技术中的NAT穿透原理》

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/440263.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为什么说逻辑回归LR是线性分类器?

问题描述:为什么说逻辑回归LR是非常典型的线性分类器? 首先,我们要弄明白区分线性与非线性分类器的标准是什么?是决策边界(Decision Boundary) 以二分类(LR可以用于多分类)为例进行…

朴素贝叶斯算法注意事项(有待完善)

1.朴素贝叶斯算法的优缺点总结: 优点: 朴素贝叶斯模型发源于古典数学理论,有稳定的分类效率;分类速度快,准确度高;对缺失数据不太敏感,算法简单,常用于文本分类(如新闻…

网络编程懒人入门(三):快速理解TCP协议一篇就够

转自即时通讯网:http://www.52im.net/ 原作者:阮一峰(ruanyifeng.com),本文由即时通讯网重新整理发布,感谢原作者的无私分享。 1、前言 本系列文章的前两篇《网络编程懒人入门(一):快速理解网络通信协议…

分类问题的模型评估指标总结

在分类任务下,预测结果(Predicted Condition)与正确标记(True Condition)之间存在四中不同的组合,构成混淆矩阵(可适用于多分类),通常有这几种主要模型评估指标:精确率(查的准)、召回率(查的全对正样本的区分能力)、F1值(反映模型…

nltk安装punkt等语料库时报SSL错误完美解决方案及离线安装方法

nltk是NLP领域中一个比较通用的国际分词工具,但是使用时往往依赖语料库数据包,需要安装到本地,以下介绍在线安装和离线安装两种方式: (ps:对NLP感兴趣的朋友可以相互学习,我的微信号&#xff1…

7. Deep Learning From Scratch

Intro 这是深度学习第7课。 到目前为止,您构建的模型依赖于预先训练的模型。 但它们不是许多用例的理想解决方案。 在本课程中,您将学习如何构建全新的模型。 Lesson [1] from IPython.display import YouTubeVideo YouTubeVideo(YbNE3zhtsoo, widt…

最实用的Git命令总结:新建本地分支、远程分支、关联和取消关联分支、清除本地和远程分支、合并分支、版本还原、tag命令、中文乱码解决方案、如何fork一个分支和修改后发起合并请求

1.常用命令git、tag整理 1、新建分支本地分支 git branch <branch-name>远程分支 git push origin <branch-name>:<new-branch-name> 2、删除分支本地分支 git branch -d <branch-name> 或 git branch -D <branch-name>远程分支 git push o…

Java基础部分快速复习(以前复习的时候放在自己的新浪博客上)

工作后Java基本没有用到&#xff0c;有时候自己也会把基础过一遍&#xff0c;下面的链接是以前重温的时候整理的Java基础最核心部分的知识点和代码示例放在自己的新浪博客上&#xff0c;如果以后有需要&#xff0c;直接从这里进入&#xff0c;可以快速复习&#xff0c;节省时间…

SQL基础用法总结(以前复习的时候放在自己的新浪博客上)

工作后主要做移动端和前端这一块&#xff0c;后端的知识都是靠自己学习积累的&#xff0c;下面的链接是以前重温的时候整理的SQL基础最核心部分的知识点和代码示例放在自己的新浪博客上&#xff0c;如果以后有需要&#xff0c;直接从这里进入&#xff0c;可以快速复习&#xff…

网络编程懒人入门(四):快速理解TCP和UDP的差异

转自即时通讯网&#xff1a;http://www.52im.net/ 原作者&#xff1a;MeloDev&#xff0c;本文由即时通讯网重新修订发布&#xff0c;感谢原作者的无私分享。 1、前言 对于即时通讯开发者新手来说&#xff0c;在开始着手编写IM或消息推送系统的代码前&#xff0c;最头疼的问…

Apollo自动驾驶入门课程第⑤讲 — 感知(下)

目录 1. 卷积神经网络 2. 检测与分类 3. 跟踪 4. 分割 5. Apollo感知 6. 传感器数据比较 7. 感知融合策略 本文转自微信公众号&#xff1a;Apollo开发者社区 原创&#xff1a; 阿波君 Apollo开发者社区 8月29日 上一篇文章中&#xff0c;我们发布了无人驾驶技术的 感知篇…

TextRank算法原理和提取关键词的主要过程详解 计算句子相似度 计算句子重要性公式

1、TextRank计算句子相似度和句子重要性的公式 2、TextRank算法提取关键词的过程 3、TextRank建立关键词无向图

Apollo自动驾驶入门课程第⑥讲 — 预测

目录 1. 简介 2. 不同的预测方式 3. 基于车道序列的预测 4. 障碍物状态 5. 预测目标车道 6. 递归神经网络 7. 递归神经网络在目标车道预测的应用 8. 轨迹生成 本文转自微信公众号&#xff1a;Apollo开发者社区 原创&#xff1a;涛涛CV Apollo开发者社区 9月6日 上一篇文…

使用PDF.js实现前端和手机端网页预览PDF文件(可定制,支持本地文件、Base64编码和远程URL跨域方式)

1.插件下载地址&#xff1a;https://mozilla.github.io/pdf.js/ 下载后解压pdfjs-1.10.88-dist.zip文件后得到&#xff1a; 2.把pdfjs-1.10.88-dist放到项目静态资源中&#xff0c;在自己的页面中通过iframe链接到pdfjs-1.10.88-dist/web/viewer.html文件中。 3.访问自己的页…

移动互联网浩荡十年 有的升腾,有的陨落

原创&#xff1a; 颜西龙 猎云网 &#xff08;ilieyun&#xff09;1周前 中国移动互联网的十年&#xff0c;是波澜壮阔、荡气回肠的十年。本文回溯了这段历史&#xff0c;在这十年间里&#xff0c;有的企业升腾&#xff0c;有的企业陨落。 2011年8月16日&#xff0c;北京798艺术…

原生JS动态计算输入框文本内容的宽度,当内容宽度超过输入框的宽度时可控

需求场景&#xff1a;左边输入框输入内容&#xff0c;右边输入框用placeholder展示&#xff0c;当placeholder的内容宽度超过右边输入框的宽度时&#xff0c;placeholder强行替换为“请选择” 注意事项&#xff1a;1、左右输入框的大小、样式都无关&#xff1b; 2、实际业务中…

Apollo自动驾驶入门课程第⑦讲 — 规划(上)

目录 1. 规划简介 2. 将地图转为图形 3. 路径查找算法&#xff1a;A* 4. 轨迹生成 5. Fernet坐标系 本文转自微信公众号&#xff1a;Apollo开发者社区 原创&#xff1a; 阿波君 Apollo开发者社区 9月13日 上周我们发布了无人驾驶技术的 预测篇&#xff0c;简要介绍了预测的…

JS正则表达式常见场景下的用法总结

&#xff08;一&#xff09;前置知识总结&#xff1a; 1. 正则表达式 /xxxx/[标识] 其中的标识含义 •g &#xff08;全文查找&#xff09; •i &#xff08;忽略大小写&#xff09; •m &#xff08;多行查找&#xff09; 2. 正则表达式创建的两种方式&#xff08;等价&#…

Apollo自动驾驶入门课程第⑧讲 — 规划(下)

目录 1. 路径-速度解耦规划 2. 路径生成与选择 3. ST图 4. 速度规划 5. 优化 6. 路径-速度规划的轨迹生成 7. Lattice规划 8. ST轨迹的终止状态 9. SL轨迹的终止状态 10. Lattice规划的轨迹生成 本文转自微信公众号&#xff1a;Apollo开发者社区 原创&#xff1a; 阿…

网络编程懒人入门(五):快速理解为什么说UDP有时比TCP更有优势

转自即时通讯网&#xff1a;http://www.52im.net/ 本文观点仅作参考&#xff0c;请根据自已系统的应用场景合理地选择数据传输层协议即可&#xff0c;无需盲目崇拜大牛言论。 1、前言 对于即时通讯开者新手来说&#xff0c;在开始着手编写IM或消息推送系统的代码前&#xff…