一道面试题了解计算机网络

本文是我在公司做的计算机网络知识的分享,特整理成文章供以后学习。本文内容大部分来自网上,并非完全原创,参考链接已经放到文章结尾处。



今天分享的主题是计算机网络。

我们先从一个经典的面试题开始讲起。 当我们输入URL,按下回车发生了什么?例如https://www.baidu.com

这是一个网址,浏览器的第一步是就是把网址解析成URL。这里我们讲第一个概念。

网址指因特网上网站的地址。将一些信息储存在网站上,所有开放资源都有一个相应的接口,以便其他用户访询而获取信息资料,这样的地址叫做网站地址。如果要从一台计算机访问网上另一台计算机,就必须知道对方的网址。这里所说的网址实际上指两个内涵,即IP和域名。 通用网址、域名、网站地址的三者是不同的概念,最基础的是域名。注册一个通用网址,你必须先要注册你的域名,提交给注册服务机构,这样通用网址就可以指向你提供的网站地址。

解析URL

网站地址是用将通向网站的地址用所属互联网类型(如最常见的www(万维网)等)访问协议+域名的形式表达出来。

url是统一资源定位符,对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。

URL地址的格式为协议://用户名:密码@子域名.域名.顶级域名:端口号/目录/文件名.文件后缀?参数=值#标志

我们从URL的地址就可以知道要传输的数据的协议类型,端口号,目标文件等。但是目前浏览器的地址栏中的地址还不是URL,因为我们通过www.baidu.com 这样的字符串获取到目标的IP。这时候我们需要DNS解析了。

DNS解析

不知道大家有没有做过自己的网站。我第一次做网站的时候,在万网注册了一个域名www.gaoyakang.tk,并给了我一个DNS服务器的地址。 但是这时候我并不能发布我的网站代码,万网的帮助中心说了我需要一个服务器来发布网站。 于是我到阿里云上买了一个服务器,把我网站的源代码放在了上面。这时候阿里云提示我要做一个DNS解析,因为现在服务器指向的是阿里默认的域名。于是我按照提示,在我的服务器上填上了我域名和DNS服务器值,然后输入我的域名之后就可以访问到网站了。

我们反过来看刚才那一个步骤,浏览器对于这个网址首先要去浏览器的缓存中查找对应的IP地址,如果没有再去本机系统的Hosts文件中查找对应的IP地址,如果没有就去路由器中查找,如果还是没有就去DNS服务器中去找到这个域名对应的IP地址。经过这一系列的步骤我们拿到了最终的IP地址。

IP协议

IP地址对应的是IP协议,我们讲第二个概念。

IP协议是将多个包交换网络连接起来,它在源地址和目的地址之间传送一种称之为数据包的东西,它还提供对数据大小的重新组装功能,以适应不同网络对包大小的要求。 IP不提供可靠的传输服务,它不提供端到端的或(路由)结点到(路由)结点的确认,对数据没有差错控制,它只使用报头的校验码,它不提供重发和流量控制。如果出错可以通过ICMP报告,ICMP在IP模块中实现。

IP协议的报文如图所示。在TCP/IP报文中IP报文是包住TCP报文的

IP数据报分配

标识、标志、分偏移这三个字段帮助标识由IPv4主机发送的数据报,这三个字段对实现分片很重要。因为大多数数据链路层不支持过长的IP数据报,所以要把IP数据报分片,分片之后的数据报每一片都是一个独立的ipv4数据报。

发送主机每次发送数据报都讲一个“内部计数器”加1,然后将数值复制“标识”字段中。

ARP地址解析

现在我们有了IP地址,我们知道我需要请求的资源在什么地方了,但是数据并不会直接根据IP就能直接到服务器。IP地址类似于收货地址,只有收货地址我们当然收不到快递了。我们需要知道去到这个地址应该走什么样的路线。那么这时候起作用的就是ARP协议了。

地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议主机发送信息时将包含目标IP地址的ARP请求广播到网络上的所有主机,并接收返回消息,以此确定目标的物理地址

发送ARP请求,我们需要有一个目标IP地址,同时还需要知道用于发送ARP广播的接口的Mac地址。每个网络设备都有一个MAC地址,用来唯一标识一台设备。APR解析的工作过程大致如下:

  • 首先查询ARP缓存,如果缓存命中,我们返回结果:目标IP = MAC

    如果缓存没有命中,就进行如下操作:

  • 查看路由表,看看目标IP地址是不是在本地路由表中的某个子网内。是的话,使用跟那个子网相连的接口,否则使用与默认网关相连的接口。
  • 查询选择的网络接口的MAC地址
  • 我们发送一个二层ARP请求:

在TCP/IP协议报文中,MAC地址是在Ethenet帧头里面的。

现在我们有了DNS服务器或者默认网关的IP地址,我们可以继续DNS请求了:

  • 使用53端口向DNS服务器发送UDP请求包,如果响应包太大,会使用TCP协议
  • 如果本地/ISP DNS服务器没有找到结果,它会发送一个递归查询请求,一层一层向高层DNS服务器做查询,直到查询到起始授权机构,如果找到会把结果返回。

使用套接字

当浏览器得到了目标服务器的IP地址,以及URL中给出来端口号(http协议默认端口号是80, https默认端口号是443),它会调用系统库函数 socket ,请求一个TCP流套接字,对应的参数是 AF_INETSOCK_STREAM

  • 这个请求首先被交给传输层,在传输层请求被封装成TCP segment。目标端口会被加入头部,源端口会在系统内核的动态端口范围内选取(Linux下是ip_local_port_range)
  • TCP segment被送往网络层,网络层会在其中再加入一个IP头部,里面包含了目标服务器的IP地址以及本机的IP地址,把它封装成一个TCP packet。
  • 这个TCP packet接下来会进入链路层,链路层会在封包中加入frame头部,里面包含了本地内置网卡的MAC地址以及网关(本地路由器)的MAC地址。像前面说的一样,如果内核不知道网关的MAC地址,它必须进行ARP广播来查询其地址。

  到了现在,TCP封包已经准备好了,可以进行传输了。

数据包传输

通常情况下,封包会从本地计算机出发,经过本地网络,再通过调制解调器(modem)把数字信号转换成模拟信号,使其适于在电话线路,有线电视光缆和无线电话线路上传输。在传输线路的另一端,是另外一个调制解调器,它把模拟信号转换回数字信号,交由下一个 网络节点 处理。

最终封包会到达管理本地子网的路由器。在那里出发,它会继续经过自治区域的边界路由器和其他自治区域,最终到达目标服务器。一路上经过的这些路由器会从IP数据报头部里提取出目标地址,并将封包正确地路由到下一个目的地。IP数据报头部TTL域的值每经过一个路由器就减1,如果封包的TTL变为0,或者路由器由于网络拥堵等原因封包队列满了,那么这个包会被路由器丢弃。

上面的发送和接受过程在TCP连接期间会发生很多次。

建立TCP连接

在TCP连接之前我们先看一下TCP报文的格式:

TCP首部一些重要字段:

序号(ISN):用于标识每个报文段,使目的主机可确认已收到指定报文段中的数据。当源主机用于多个报文段发送一个报文时,即使这些报文到达目的主机的顺序不一样,序列号也可以使目的主机按顺序排列它们。

同步(SYN):仅在三次握手建立 TCP 连接时有效。当 SYN = 1 而 ACK = 0 时,表明这是一个连接请求报文段,对方若同意建立连接,则应在相应的报文段中使用 SYN = 1 和 ACK = 1。因此,SYN 置 1 就表示这是一个连接请求或连接接受报文。

终止(FIN):用来释放一个连接。当 FIN = 1 时,表明此报文段的发送方的数据已经发送完毕,并要求释放运输连接。

数据包到达客户端后需要建立连接。TCP连接过程就是著名的三次握手。

  • 客户端选择一个初始序列号(ISN),将设置了SYN位的封包发送给服务器端,表明自己要建立连接并设置了初始序列号
  • 服务器端接受到SYN包
  • 服务器端选择它自己的初始序列号服务器端设置SYN位,表明自己选择了一个初始序列号服务器端把 (客户端ISN + 1) 复制到ACK域,并且设置ACK位,表明自己接收到了客户端的第一个封包
  • 客户端通过发送下面一个封包来确认这次连接:自己的序列号+1接收端ACK+1设置ACK位

数据通过下面的方式传输:

当一方发送了N个Bytes的数据之后,将自己的SEQ序列号也增加N另一方确认接收到这个数据包(或者一系列数据包)之后,它发送一个ACK包,ACK的值设置为接收到的数据包的最后一个序列号

关闭连接的过程就是也很著名的四次握手:

要关闭连接的一方发送一个FIN包另一方确认这个FIN包,并且发送自己的FIN包要关闭的一方使用ACK包来确认接收到了FIN。

HTTP服务器请求处理

HTTPD(HTTP Daemon)在服务器端处理请求/相应。最常见的 HTTPD 有 Linux 上常用的 Apache 和 nginx,与 Windows 上的 IIS。

  • HTTPD接收请求
    • 服务器把请求拆分为以下几个参数:

      HTTP请求方法(GET, POST, HEAD, PUT 和 DELETE )。在访问百度这种情况下,使用的是GET方法域名:baidu.com请求路径/页面:/ (我们没有请求baidu.com下的指定的页面,因此 / 是默认的路径)

  • 服务器验证其上已经配置了baidu.com的虚拟主机
  • 服务器验证baidu.com接受GET方法
  • 服务器验证该用户可以使用GET方法(根据IP地址,身份信息等)
  • 如果服务器安装了 URL 重写模块(例如 Apache 的 mod_rewrite 和 IIS 的 URL Rewrite),服务器会尝试匹配重写规则,如果匹配上的话,服务器会按照规则重写这个请求
  • 服务器根据请求信息获取相应的响应内容,这种情况下由于访问路径是 "/" ,会访问首页文件。(你可以重写这个规则,但是这个是最常用的)
  • 服务器会使用指定的处理程序分析处理这个文件,比如假设baidu使用Java,服务器会使用Java解析index文件,并捕获输出,把Java的输出结果给请求者。

最终浏览器会把HTML文档的结果渲染到浏览器的界面上。



相关链接:

HTTP长连接、短连接究竟是什么?

当我们输入URL,按下回车发生了什么?

在浏览器中输入Google.com并且按下回车之后发生了什么?

TCP和UDP报文分片的区别

TCP/IP协议、HTTP协议、SOCKET通讯详解

原文地址:https://www.cnblogs.com/rever/p/10223056.html

时间: 2024-08-07 12:27:17

一道面试题了解计算机网络的相关文章

一道面试题: C能申请的最大全局数组大小?

一道面试题: C能申请的最大全局数组大小?第一反应好像是4GB,但明显不对,代码和数据都要占空间,肯定到不了4GB.但是又想内存可以和硬盘数据交换,那到底是多少?应该是32位系统是理论上不能超过4GB(因为地址宽度4bytes,寻址的限制),实际中由于OS实现的细节会更少(比如Linux 1GB给了内核),而64位系统不超过2^64-1:内存大小最好大于数组长度,否则导致和磁盘交换数据,性能下降如果是局部变量,分配在栈上,空间会更小,取决于编译器 参考:http://stackoverflow.

华为的一道机试题--等式变换

华为的一道机试题 (http://blog.csdn.net/zombie_slicer/article/details/37346025) 第三题:等式变换 输入一个正整数X,在下面的等式左边的数字之间添加+号或者-号,使得等式成立. 1 2 3 4 5 6 7 8 9 = X 比如: 12-34+5-67+89 = 5 1+23+4-5+6-7-8-9 = 5 请编写程序,统计满足输入整数的所有整数个数. 输入:       正整数,等式右边的数字 输出:       使该等式成立的个数 样

Java中有关构造函数的一道笔试题解析

Java中有关构造函数的一道笔试题解析 1.具体题目如下 下列说法正确的有() A. class中的constructor不可省略 B. constructor必须与class同名,但方法不能与class同名 C. constructor在一个对象被new时执行 D.一个class只能定义一个constructor 2.解析说明 (1)class中的构造函数是可以省略的 /** * @Title:User.java * @Package:com.you.user.model * @Descrip

Android多线程研究(4)——从一道面试题说起

有一道这种面试题:开启一个子线程和主线程同一时候运行,子线程输出10次后接着主线程输出100次,如此重复50次.先看以下代码: package com.maso.test; /** * * @author Administrator * 两个线程,当中是一个主线程,第一个线程先运行输出10次,主线程接着运行输出100次,如此重复50次 */ public class ThreadTest3 implements Runnable{ private static Test test; @Overr

0810------笔试题----------腾讯2012年的一道笔试题

1.题目要求 a)b[i] = a[0] *a[1] *a[2]*….a[n-1]/ a[i],求出数组b: b)要求不能用除法,除循环控制变量以外,不许额外申请其余变量,时间复杂度为O(n),空间复杂度为O(1). 2.程序思路 a)假设 N = 5,那么 b[0] =      a[1]*a[2]*a[3]*a[4];            b[1] = a[0]*     a[2]*a[3]*a[4];            b[2] = a[0]*a[1]*     a[3]*a[4];

关于阿里的一道笔试题分析

其题目如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #pragma pack(2) class A { public:     int i;     union U     {         char buff[13];         int i;     }u;     void foo() {    }     typedef char* (*f)(void*);     enum{red, green, blue} color; }a; class A

关于Java类加载双亲委派机制的思考(附一道面试题)

预定义类加载器和双亲委派机制 JVM预定义的三种类型类加载器: 启动(Bootstrap)类加载器:是用本地代码实现的类装入器,它负责将 <Java_Runtime_Home>/lib下面的类库加载到内存中(比如rt.jar).由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作. 标准扩展(Extension)类加载器:是由 Sun 的 ExtClassLoader(sun.misc.Launcher$ExtClassLoader)

好玩的一道笔试题

/*实现函数: void f(int a, int b, int c) 编码中不允许出现燃和if,switch,for,while之类的关键词以及"?:"表达式,并要求: a=1时,打印b+c的值: a=2时,打印b-c的值: a=3时,打印b*c的值: a=4时,打印b/c的值. */ 下面是我的解答,哈哈: #include <iostream> int cal(int a,int b, int c){ int res = 0; (!(a^1) && (

送上今年微软的一道笔试题

这里送上一道微软的笔试题,具体题目如下: Time Limit: 10000msCase Time Limit: 1000msMemory Limit: 256MB Description Consider a string set that each of them consists of {0, 1} only. All strings in the set have the same number of 0s and 1s. Write a program to find and outp