计算机网络
计算机网络
一些术语的缩写
MSL(Maximum Segment Lifetime)
:传输层的概念,表示TCP报文最大存活时间TTL(Time to Live)
:网络层的概念,每次IP数据包在网络中被路由器传递时,TTL值减一。当TTL减为零时,数据包会被丢弃,并向源发送一个 ICMP 时间超过消息。TTL用来防止数据包在网络中无限循环RTT(Round-Trip Time)
: 往返时延RTO(Retransmission Time Out)
:重传超时时间,即从数据发送时刻算起,超过这个时间便执行重传。
OSI 七层协议模型
OSI 模型(Open System Interconnection Model)是⼀个由 ISO 提出得到概念模型,试图提供⼀个使各种不同的的计算机和⽹络在世界范围内实现互联的标准框架。
虽然OSI参考模型在实际中的应⽤意义并不是很⼤,但是它对于理解⽹络协议内部的运作很有帮助,为我们学习⽹络协议提供了⼀个很好的参考。它将计算机⽹络体系结构划分为7层,每层都为上⼀层提供了良好的接⼝。以下将具体介绍各层结构及功能。
![OSI模型](/img/C++八股文/计网/osi七层协议图.gif)
主要分为以下七层(从下⾄上):物理层、数据链路层、⽹络层、传输层、会话层、表示层、应⽤层。
物理层:规定了一些机械特性,电⽓特性,功能特性,如网线、网卡标准,这⼀层传输的是 bit 流。
数据链路层:定义数据的基本格式,如何传输,如何标识,在不可靠的物理介质上提供可靠的传输。该层的作⽤包括:物理地址寻址、封装成帧、流量控制、数据的检错、重发等。这⼀层中将 bit 流封装成 frame 帧。
⽹络层:定义ip编址,对数据包进⾏路由选择。此外,⽹络层还可以实现拥塞控制、⽹际互连等功能。在这⼀层,数据的单位称为数据包(packet)。
传输层:提供端到端的、可靠的或不可靠的传输。此外,传输层还要处理端到端的差错控制和流量控制问题。在这⼀层,数据的单位称为数据段(segment)。
会话层:控制应用程序之间会话能力。如不同软件负责不同软件分发给不同软件。
表示层:数据格式标识,基本压缩加密功能
应⽤层:各种应用软件,包括 Web 应用。
网络七层模型是一个标准,而非实现。网络四层模型由七层模型简化而来,是一个实现的应用模型。
TCP 三次握手和四次挥手的流程
三次握手
- 第⼀次:客户端发含SYN位,SEQ_NUM = S的包到服务器。(客 -> SYN_SEND)
- 第⼆次:服务器发含ACK,SYN位且ACK_NUM = S + 1,SEQ_NUM = P的包到客户机。(服 -> SYN_RECV)
- 第三次:客户机发送含ACK位,ACK_NUM = P + 1的包到服务器。(客 -> ESTABLISH,服 -> ESTABLISH)
四次挥手
- 第⼀次:客户机发含FIN位,SEQ = Q的包到服务器。(客 -> FIN_WAIT_1)
- 第⼆次:服务器发送含ACK且ACK_NUM = Q + 1的包到服务器。(服 -> CLOSE_WAIT,客 -> FIN_WAIT_2)
- 此处有等待
- 第三次:服务器发送含FIN且SEQ_NUM = R的包到客户机。(服 -> LAST_ACK,客 -> TIME_WAIT)
- 此处有等待
- 第四次:客户机发送最后⼀个含有ACK位且ACK_NUM = R + 1的包到客户机。(服 -> CLOSED
为什么建立连接时候要三次握手?不是两次也不是四次?
“三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。
例子:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。
所以说两次握手不能满足需求,而三次握手已经可以满足需求,那么四次握手就是浪费了。
从另一个角度看“TCP建立连接为什么是三次握手?”,这个问题的本质是,信道不可靠, 但是通信双发需要就某个问题达成一致. 而要解决这个问题, 无论你在消息中包含什么信息, 三次通信是理论上的最小值. 所以三次握手不是TCP本身的要求, 而是为了满足"在不可靠信道上可靠地传输信息"这一需求所导致的. 请注意这里的本质需求,信道不可靠, 数据传输要可靠. 三次达到了, 那后面你想接着握手也好, 发数据也好, 跟进行可靠信息传输的需求就没关系了. 因此,如果信道是可靠的, 即无论什么时候发出消息, 对方一定能收到, 或者你不关心是否要保证对方收到你的消息, 那就能像UDP那样直接发送消息就可以了.”。
说一下一次完整的HTTP请求过程包括哪些内容?
域名解析 --> 发起TCP的3次握手 --> 建立TCP连接后发起http请求 --> 服务器响应http请求,浏览器得到html代码 --> 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等) --> 浏览器对页面进行渲染呈现给用户。
你知道DNS是什么?
官方解释:DNS(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。
通过主机名,最终得到该主机名对应的IP地址的过程叫做域名解析(或主机名解析)。
通俗的讲,我们更习惯于记住一个网站的名字,比如www.baidu.com,而不是记住它的ip地址,比如:167.23.10.2。
HTTPS是如何保证数据传输的安全,整体的流程是什么?(SSL是怎么工作保证安全的)
- 客户端向服务器端发起SSL连接请求;
- 服务器把公钥发送给客户端,并且服务器端保存着唯一的私钥
- 客户端用公钥对双方通信的对称秘钥进行加密,并发送给服务器端
- 服务器利用自己唯一的私钥对客户端发来的对称秘钥进行解密
- 进行数据传输,服务器和客户端双方用公有的相同的对称秘钥对数据进行加密解密,可以保证在数据收发过程中的安全,即是第三方获得数据包,也无法对其进行加密,解密和篡改。
以上是属于TLS 1.0版本的答案,使用RSA密钥交换算法。而TLS 1.2版本使用的是ECDHE_RSA密钥交换算法,其过程如下:
- 客户端和服务器各自选择一个 椭圆曲线私钥(随机数),并使用椭圆曲线算法生成对应的 椭圆曲线公钥。
- 在握手阶段,客户端和服务器互相交换 椭圆曲线公钥。
- 客户端和服务器各自使用 对方的椭圆曲线公钥 和 自己的椭圆曲线私钥,通过椭圆曲线的点运算生成一个 共享密钥。由于椭圆曲线的数学性质,这个共享密钥在双方都知道,但是不能被第三方计算出来。(共享密钥并非通过传输手段获得,避免中间人截取。)
- 客户端和服务器使用这个共享密钥进行 对称加密通信。
在浏览器地址栏输入一个URL后回车,背后都发生了什么?
查浏览器缓存,检查域名是否在缓存中,如果没有则调用 gethostbyname (不同操作系统函数名也不同)进行查询。
如果 gethostbyname 没有这个域名的缓存记录,也没有在 hosts 里找到,它将会向 DNS 服务器发送一条 DNS 查询请求。查询本地DNS服务器,如果DNS服务器和我们的主机在一个子网内采用ARP地址解析协议进行ARP查询;如果不在一个子网那就需要对默认网关进行DNS查询,如果还找不到会一直向上找根DNS服务器,直到最终拿到IP地址(全球400多个根DNS服务器,由13个不同的组织管理)
拿到服务器的ip以及端口号后,浏览器会建立一个TCP连接,连接建立成功之后如果使用的是http协议的话直接返回网页需要的数据;如果是https协议的话,服务器会返回一个5开头的的重定向消息,告诉我们用的是https,那就是说IP没变,但是端口号从80变成443了(http默认端口是80,https默认端口是443).然后四次挥手断开连接,再进行一边上述操作,但是端口从80变为443,还会采用SSL的加密技术来保证传输数据的安全性,保证数据传输过程中不被修改或者替换之类的,沟通好双方使用的认证算法,加密和检验算法,在此过程中也会检验对方的CA安全证书。确认无误后,开始通信,然后服务器就会返回你所要访问的网址的一些数据,然后浏览器会对页面进行需求渲染。
谈谈DNS解析过程,具体一点
先在浏览器找之前有没有缓存过的域名所对应的ip地址,有的话,直接跳过dns解析了,若是没有,就会找硬盘的hosts文件,看看有没有,有的话,直接找到hosts文件里面的ip。
如果本地的hosts文件没有能得到对应的ip地址,浏览器会发出一个dns请求到本地dns服务器,本地dns服务器一般都是你的网络接入服务器商提供,比如中国电信,中国移动等。
查询你输入的网址的DNS请求到达本地DNS服务器之后,本地DNS服务器会首先查询它的缓存记录,如果缓存中有此条记录,就可以直接返回结果,此过程是递归查询。
如果没有,本地DNS服务器继续向域服务器发出请求,比如查询google.com,请求的对象是.com域服务器。.com域服务器收到请求之后,也不会直接返回域名和IP地址的对应关系,而是告诉本地DNS服务器,你的域名的解析服务器的地址。
最后,本地DNS服务器向域名的解析服务器发出请求,这时就能收到一个域名和IP地址对应关系,本地DNS服务器不仅要把IP地址返回给用户电脑,还要把这个对应关系保存在缓存中,以备下次别的用户查询时,可以直接返回结果,加快网络访问。
DNS负载均衡是什么策略?
当一个网站有足够多的用户的时候,假如每次请求的资源都位于同一台机器上面,那么这台机器随时可能会崩掉。处理办法就是用DNS负载均衡技术,它的原理是在DNS服务器中为同一个主机名配置多个IP地址,在应答DNS查询时,DNS服务器对每个查询将以DNS文件中主机记录的IP地址按顺序返回不同的解析结果,将客户端的访问引导到不同的机器上去,使得不同的客户端访问不同的服务器,从而达到负载均衡的目的。例如可以根据每台机器的负载量,该机器离用户地理位置的距离等等。
HTTPS和HTTP的区别
- HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全, HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。
- https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用
- http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443
什么是SSL/TLS ?
SSL代表安全套接字层。它是一种用于加密和验证应用程序(如浏览器)和Web服务器之间发送的数据的协议。 身份验证 , 加密Https的加密机制是一种共享密钥加密和公开密钥加密并用的混合加密机制。
SSL/TLS协议作用:认证用户和服务,加密数据,维护数据的完整性的应用层协议加密和解密需要两个不同的密钥,故被称为非对称加密;
对称加密:优点在于加密、解密效率通常比较高 ,HTTPS 是基于非对称加密的, 公钥是公开的.
Cookie是什么?
HTTP 协议是无状态的,主要是为了让 HTTP 协议尽可能简单,使得它能够处理大量事务,HTTP/1.1 引入 Cookie 来保存状态信息。
Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器之后向同一服务器再次发起请求时被携带上,用于告知服务端两个请求是否来自同一浏览器。由于之后每次请求都会需要携带 Cookie 数据,因此会带来额外的性能开销(尤其是在移动环境下)。
Cookie 曾一度用于客户端数据的存储,因为当时并没有其它合适的存储办法而作为唯一的存储手段,但现在随着现代浏览器开始支持各种各样的存储方式,Cookie 渐渐被淘汰。新的浏览器 API 已经允许开发者直接将数据存储到本地,如使用 Web storage API(本地存储和会话存储)或 IndexedDB。
Cookie有什么用途?
- 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
- 个性化设置(如用户自定义设置、主题等)
- 浏览器行为跟踪(如跟踪分析用户行为等)
Session 的工作原理是什么?
session 的工作原理是客户端登录完成之后,服务器会创建对应的 session,session 创建完之后,会把 session 的 id 发送给客户端,客户端再存储到浏览器中。这样客户端每次访问服务器时,都会带着 sessionid,服务器拿到 sessionid 之后,在内存找到与之对应的 session 这样就可以正常工作了。
Cookie与Session的对比
Cookie
Cookie是客户端保持状态的方法。
Cookie简单的理解就是存储由服务器发至客户端并由客户端保存的一段字符串。为了保持会话,服务器可以在响应客户端请求时将Cookie字符串放在Set-Cookie下,客户机收到Cookie之后保存这段字符串,之后再请求时候带上Cookie就可以被识别。
除了上面提到的这些,Cookie在客户端的保存形式可以有两种,一种是会话Cookie一种是持久Cookie,会话Cookie就是将服务器返回的Cookie字符串保持在内存中,关闭浏览器之后自动销毁,持久Cookie则是存储在客户端磁盘上,其有效时间在服务器响应头中被指定,在有效期内,客户端再次请求服务器时都可以直接从本地取出。需要说明的是,存储在磁盘中的Cookie是可以被多个浏览器代理所共享的。
Session
Session是服务器保持状态的方法。
首先需要明确的是,Session保存在服务器上,可以保存在数据库、文件或内存中,每个用户有独立的Session用户在客户端上记录用户的操作。我们可以理解为每个用户有一个独一无二的Session ID作为Session文件的Hash键,通过这个值可以锁定具体的Session结构的数据,这个Session结构中存储了用户操作行为。
当服务器需要识别客户端时就需要结合Cookie了。每次HTTP请求的时候,客户端都会发送相应的Cookie信息到服务端。实际上大多数的应用都是用Cookie来实现Session跟踪的,第一次创建Session的时候,服务端会在HTTP协议中告诉客户端,需要在Cookie里面记录一个Session ID,以后每次请求把这个会话ID发送到服务器,我就知道你是谁了。如果客户端的浏览器禁用了Cookie,会使用一种叫做URL重写的技术来进行会话跟踪,即每次HTTP交互,URL后面都会被附加上一个诸如sid=xxxxx这样的参数,服务端据此来识别用户,这样就可以帮用户完成诸如用户名等信息自动填入的操作了。
Cookies和Session区别是什么?
- cookie:存放在客户端,session:存放在服务端。Session存储的数据比较安全
- 存储的数据类型不同 两者都是key-value的结构,但针对value的类型是有差异的 cookie:value只能是字符串类型,session:value是Object类型
- 存储的数据大小限制不同 cookie:大小受浏览器的限制,很多是是4K的大小, session:理论上受当前内存的限制
- 生命周期的控制:cookie的生命周期是累计的,从创建时,就开始计时,20分钟后,cookie生命周期结束;session的生命周期是间隔的,从创建时,开始计时如在20分钟,没有访问session,那么session生命周期被销毁
SQL注入攻击了解吗?
攻击者在HTTP请求中注入恶意的SQL代码,服务器使用参数构建数据库SQL命令时,恶意SQL被一起构造,并在数据库中执行。 用户登录,输入用户名 lianggzone,密码 ‘ or ‘1’=’1 ,如果此时使用参数构造的方式,就会出现 select * from user where name = ‘lianggzone’ and password = ‘’ or ‘1’=‘1’ 不管用户名和密码是什么内容,使查询出来的用户列表不为空。
如何防范SQL注入攻击使用预编译的PrepareStatement是必须的,但是一般我们会从两个方面同时入手。
Web端
- 有效性检验。
- 限制字符串输入的长度。
服务端
- 不用拼接SQL字符串。
- 使用预编译的PrepareStatement。
- 有效性检验。(为什么服务端还要做有效性检验?第一准则,外部都是不可信的,防止攻击者绕过Web端请求)
- 过滤SQL需要的参数中的特殊字符。比如单引号、双引号。
什么是RARP?工作原理
概括: 反向地址转换协议,网络层协议,RARP与ARP工作方式相反。 RARP使只知道自己硬件地址的主机能够知道其IP地址。RARP发出要反向解释的物理地址并希望返回其IP地址,应答包括能够提供所需信息的RARP服务器发出的IP地址。
工作原理:
- 网络上的每台设备都会有一个独一无二的硬件地址,通常是由设备厂商分配的MAC地址。主机从网卡上读取MAC地址,然后在网络上发送一个RARP请求的广播数据包,请求RARP服务器回复该主机的IP地址。
- RARP服务器收到了RARP请求数据包,为其分配IP地址,并将RARP回应发送给主机。
- PC1收到RARP回应后,就使用得到的IP地址进行通讯。
端口有效范围是多少到多少?
0-1023为知名端口号,比如其中HTTP是80,FTP是20(数据端口)、21(控制端口)
UDP和TCP报头使用两个字节存放端口号,所以端口号的有效范围是从0到65535。动态端口的范围是从1024到65535
为何需要把 TCP/IP 协议栈分成 5 层(或7层)?开放式回答。
为了更好的管理和维护,将协议分层,每一层都有自己的功能,每一层都可以独立的进行修改,而不会影响到其他层。
DNS查询方式有哪些
递归解析
当局部DNS服务器自己不能回答客户机的DNS查询时,它就需要向其他DNS服务器进行查询。此时有两种方式。局部DNS服务器自己负责向其他DNS服务器进行查询,一般是先向该域名的根域服务器查询,再由根域名服务器一级级向下查询。最后得到的查询结果返回给局部DNS服务器,再由局部DNS服务器返回给客户端。
迭代解析
当局部DNS服务器自己不能回答客户机的DNS查询时,也可以通过迭代查询的方式进行解析。局部DNS服务器不是自己向其他DNS服务器进行查询,而是把能解析该域名的其他DNS服务器的IP地址返回给客户端DNS程序,客户端DNS程序再继续向这些DNS服务器进行查询,直到得到查询结果为止。也就是说,迭代解析只是帮你找到相关的服务器而已,而不会帮你去查。比如说:baidu.com的服务器ip地址在192.168.4.5这里,你自己去查吧,本人比较忙,只能帮你到这里了。
使用 Session 的过程是怎样的?
过程如下:
- 用户进行登录时,用户提交包含用户名和密码的表单,放入 HTTP 请求报文中;
- 服务器验证该用户名和密码,如果正确则把用户信息存储到 Redis 中,它在 Redis 中的 Key 称为 Session ID;
- 服务器返回的响应报文的 Set-Cookie 首部字段包含了这个 Session ID,客户端收到响应报文之后将该 Cookie 值存入浏览器中;
- 客户端之后对同一个服务器进行请求时会包含该 Cookie 值,服务器收到之后提取出 Session ID,从 Redis 中取出用户信息,继续之前的业务操作。
注意:Session ID 的安全性问题,不能让它被恶意攻击者轻易获取,那么就不能产生一个容易被猜到的 Session ID 值。此外,还需要经常重新生成 Session ID。在对安全性要求极高的场景下,例如转账等操作,除了使用 Session 管理用户状态之外,还需要对用户进行重新验证,比如重新输入密码,或者使用短信验证码等方式。
Session和cookie应该如何去选择(适用场景)?
- Cookie 只能存储 ASCII 码字符串,而 Session 则可以存储任何类型的数据,因此在考虑数据复杂性时首选 Session;
- Cookie 存储在浏览器中,容易被恶意查看。如果非要将一些隐私数据存在 Cookie 中,可以将 Cookie 值进行加密,然后在服务器进行解密;
- 对于大型网站,如果用户所有的信息都存储在 Session 中,那么开销是非常大的,因此不建议将所有的用户信息都存储到 Session 中。
DDos 攻击了解吗?
客户端向服务端发送请求链接数据包,服务端向客户端发送确认数据包,客户端不向服务端发送确认数据包,服务器一直等待来自客户端的确认.没有彻底根治的办法,除非不使用TCP
DDos 预防:
- 限制同时打开SYN半链接的数目
- 缩短SYN半链接的Time out 时间
- 关闭不必要的服务
MTU和MSS分别是什么?
MTU:maximum transmission unit,最大传输单元,由硬件规定,如以太网的MTU为1500字节。
MSS:maximum segment size,最大分节大小,为TCP数据包每次传输的最大数据分段大小,一般由发送端向对端TCP通知对端在每个分节中能发送的最大TCP数据。MSS值为MTU值减去IPv4 Header(20 Byte)和TCP header(20 Byte)得到。
HTTP中有个缓存机制,但如何保证缓存是最新的呢?(缓存过期机制)
max-age 指令出现在请求报文,并且缓存资源的缓存时间小于该指令指定的时间,那么就能接受该缓存。
max-age 指令出现在响应报文,表示缓存资源在缓存服务器中保存的时间。
1 |
|
Expires 首部字段也可以用于告知缓存服务器该资源什么时候会过期。
1 |
|
- 在 HTTP/1.1 中,会优先处理 max-age 指令;
- 在 HTTP/1.0 中,max-age 指令会被忽略掉。
TCP头部中有哪些信息?
- 源端口 目标端口
- 序号(32bit):传输方向上字节流的字节编号。初始时序号会被设置一个随机的初始值(ISN),之后每次发送数据时,序号值 = ISN + 数据在整个字节流中的偏移。假设A -> B且ISN = 1024,第一段数据512字节已经到B,则第二段数据发送时序号为1024 + 512。用于解决网络包乱序问题。
- 确认号(32bit):接收方对发送方TCP报文段的响应,其值是收到的序号值 + 1。
- 首部长(4bit):标识首部有多少个4字节 * 首部长,最大为15,即60字节。
- 标志位(6bit):
- URG:标志紧急指针是否有效。
- ACK:标志确认号是否有效(确认报文段)。用于解决丢包问题。
- PSH:提示接收端立即从缓冲读走数据。
- RST:表示要求对方重新建立连接(复位报文段)。
- SYN:表示请求建立一个连接(连接报文段)。
- FIN:表示关闭连接(断开报文段)。
- 窗口(16bit):接收窗口。用于告知对方(发送方)本方的缓冲还能接收多少字节数据。用于解决流控。
- 校验和(16bit):接收端用CRC检验整个报文段有无损坏。
常见TCP的连接状态有哪些?
- CLOSED:初始状态。
- LISTEN:服务器处于监听状态。
- SYN_SEND:客户端socket执行CONNECT连接,发送SYN包,进入此状态。
- SYN_RECV:服务端收到SYN包并发送服务端SYN包,进入此状态。
- ESTABLISH:表示连接建立。客户端发送了最后一个ACK包后进入此状态,服务端接收到ACK包后进入此状态。
- FIN_WAIT_1:终止连接的一方(通常是客户机)发送了FIN报文后进入。等待对方FIN。
- CLOSE_WAIT:(假设服务器)接收到客户机FIN包之后等待关闭的阶段。在接收到对方的FIN包之后,自然是需要立即回复ACK包的,表示已经知道断开请求。但是本方是否立即断开连接(发送FIN包)取决于是否还有数据需要发送给客户端,若有,则在发送FIN包之前均为此状态。
- FIN_WAIT_2:此时是半连接状态,即有一方要求关闭连接,等待另一方关闭。客户端接收到服务器的ACK包,但并没有立即接收到服务端的FIN包,进入FIN_WAIT_2状态。
- LAST_ACK:服务端发动最后的FIN包,等待最后的客户端ACK响应,进入此状态。
- TIME_WAIT:客户端收到服务端的FIN包,并立即发出ACK包做最后的确认,在此之后的2MSL时间称为TIME_WAIT状态。
网络的七层/五层模型主要的协议有哪些?
TCP是什么?
TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
应用层常见协议知道多少?了解几个?
协议 | 名称 | 默认端口 | 底层协议 |
---|---|---|---|
HTTP | 超文本传输协议 | 80 | TCP |
HTTPS | 安全超文本传输协议 | 443 | TCP |
Telnet | 远程登录服务 | 23 | TCP |
FTP | 文件传输协议 | 20传输/21连接 | TCP |
TFTP | 简单文件传输协议 | 69 | UDP |
SMTP | 简单邮件传输协议 | 25 | TCP |
POP3 | 邮局协议 | 110 | TCP |
DNS | 域名系统 | 53 | 服务器间进行域传输的时候用TCP,客户端查询DNS服务器时用 UDP |
浏览器在与服务器建立了一个 TCP 连接后是否会在一个 HTTP 请求完成后断开?什么情况下会断开?
在 HTTP/1.0 中,一个服务器在发送完一个 HTTP 响应后,会断开 TCP 链接。但是这样每次请求都会重新建立和断开 TCP 连接,代价过大。所以虽然标准中没有设定,某些服务器对 Connection: keep-alive 的 Header 进行了支持。意思是说,完成这个 HTTP 请求之后,不要断开 HTTP 请求使用的 TCP 连接。这样的好处是连接可以被重新使用,之后发送 HTTP 请求的时候不需要重新建立 TCP 连接,以及如果维持连接,那么 SSL 的开销也可以避免。
HTTP/1.1 就把 Connection 头写进标准,并且默认开启持久连接,除非请求中写明 Connection: close,那么浏览器和服务器之间是会维持一段时间的 TCP 连接,不会一个请求结束就断掉。
默认情况下建立 TCP 连接不会断开,只有在请求报头中声明 Connection: close 才会在请求完成后关闭连接。
三次握手相关内容
- 初始状态:客户端处于 closed(关闭)状态,服务器处于 listen(监听) 状态。
- 第一次握手:客户端发送请求报文将 SYN = 1同步序列号和初始化序列号seq = x发送给服务端,发送完之后客户端处于SYN_Send状态。(验证了客户端的发送能力和服务端的接收能力)
- 第二次握手:服务端受到 SYN 请求报文之后,如果同意连接,会以自己的同步序列号SYN(服务端) = 1、初始化序列号 seq = y和确认序列号(期望下次收到的数据包)ack = x+ 1 以及确认号ACK = 1报文作为应答,服务器为SYN_Receive状态。(问题来了,两次握手之后,站在客户端角度上思考:我发送和接收都ok,服务端的发送和接收也都ok。但是站在服务端的角度思考:哎呀,我服务端接收ok,但是我不清楚我的发送ok不ok呀,而且我还不知道你接受能力如何呢?所以老哥,你需要给我三次握手来传个话告诉我一声。你要是不告诉我,万一我认为你跑了,然后我可能出于安全性的考虑继续给你发一次,看看你回不回我。)
- 第三次握手: 客户端接收到服务端的 SYN + ACK之后,知道可以下次可以发送了下一序列的数据包了,然后发送同步序列号 ack = y + 1和数据包的序列号 seq = x + 1以及确认号ACK = 1确认包作为应答,客户端转为established状态。(分别站在双方的角度上思考,各自ok)
什么是半连接队列?
服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时双方还没有完全建立其连接,服务器会把此种状态下请求连接放在一个队列里,我们把这种队列称之为半连接队列。
当然还有一个全连接队列,就是已经完成三次握手,建立起连接的就会放在全连接队列中。如果队列满了就有可能会出现丢包现象。
这里在补充一点关于SYN-ACK 重传次数的问题: 服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传。如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。 注意,每次重传等待的时间不一定相同,一般会是指数增长,例如间隔时间为 1s,2s,4s,8s......
ISN(Initial Sequence Number)是固定的吗?
当一端为建立连接而发送它的SYN时,它为连接选择一个初始序号。ISN随时间而变化,因此每个连接都将具有不同的ISN,ISN是一个有可以看作是一个32比特的计数器,但并不是简单的计数器,大概每4ms加1 。
info
ISN = M + F(localhost, localport, remotehost, remoteport)(M为计数器),ISN应该由这个公式确定,F为哈希算法,不是一个简单计数器。
这样选择序号的目的在于防止在网络中被延迟的分组在以后又被传送,而导致某个连接的一方对它做错误的解释。
三次握手的其中一个重要功能是客户端和服务端交换 ISN(Initial Sequence Number),以便让对方知道接下来接收数据的时候如何按序列号组装数据。如果 ISN 是固定的,攻击者很容易猜出后续的确认号,因此 ISN 是动态生成的。
三次握手过程中可以携带数据吗?
第三次握手的时候,可以携带数据。但是,第一次、第二次握手不可以携带数据。
为什么这样呢?大家可以想一个问题,假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据。因为攻击者根本就不理服务器的接收、发送能力是否正常,然后疯狂着重复发 SYN 报文的话,这会让服务器花费很多时间、内存空间来接收这些报文。
也就是说,第一二次握手不可以放数据,其中一个简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTABLISHED 状态。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据也没啥毛病。
SYN攻击是什么?
服务器端的资源分配是在二次握手时分配的,而客户端的资源是在完成三次握手时分配的,所以服务器容易受到SYN洪泛攻击。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。
检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。在 Linux/Unix 上可以使用系统自带的 netstats 命令来检测 SYN 攻击。
1 |
|
常见的防御 SYN 攻击的方法有如下几种:
- 缩短超时(SYN Timeout)时间
- 增加最大半连接数
- 过滤网关防护
- SYN cookies技术
四次挥手相关内容
刚开始双方都处于 ESTABLISHED 状态,假如是客户端先发起关闭请求。四次挥手的过程如下:
- 第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。即发出连接释放报文段(FIN=1,序号seq=u),并停止再发送数据,主动关闭TCP连接,进入FIN_WAIT1(终止等待1)状态,等待服务端的确认。
- 第二次挥手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 +1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了。 即服务端收到连接释放报文段后即发出确认报文段(ACK=1,确认号ack=u+1,序号seq=v),服务端进入CLOSE_WAIT(关闭等待)状态,此时的TCP处于半关闭状态,客户端到服务端的连接释放。客户端收到服务端的确认后,进入FIN_WAIT2(终止等待2)状态,等待服务端发出的连接释放报文段。
- 第三次挥手:如果服务端也想断开连接了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。 即服务端没有要向客户端发出的数据,服务端发出连接释放报文段(FIN=1,ACK=1,序号seq=w,确认号ack=u+1),服务端进入LAST_ACK(最后确认)状态,等待客户端的确认。
- 第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 +1 作为自己 ACK 报文的确认号值。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态,服务端收到 ACK 报文之后,就处于关闭连接了,处于 CLOSED 状态。 即客户端收到服务端的连接释放报文段后,对此发出确认报文段(ACK=1,seq=u+1,ack=w+1),客户端进入TIME_WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进入CLOSED状态。
收到一个FIN只意味着在这一方向上没有数据流动。客户端执行主动关闭并进入TIME_WAIT是正常的,服务端通常执行被动关闭,不会进入TIME_WAIT状态。
在socket编程中,任何一方执行close()操作即可产生挥手操作。
挥手为什么需要四次?
因为当服务端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当服务端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,"你发的FIN报文我收到了"。之后服务器端可能还有想要传输的数据,只有等到服务端所有的报文都发送完了,服务器端才发送FIN报文,因此不能一起发送。故需要四次挥手。
2MSL等待状态?
TIME_WAIT状态也称为2MSL等待状态。每个具体TCP实现必须选择一个报文段最大生存时间MSL(Maximum Segment Lifetime),它是任何报文段被丢弃前在网络内的最长时间。这个时间是有限的,因为TCP报文段以IP数据报在网络内传输,而IP数据报则有限制其生存时间的TTL字段。
对一个具体实现所给定的MSL值,处理的原则是:当TCP执行一个主动关闭,并发回最后一个ACK,该连接必须在TIME_WAIT状态停留的时间为2倍的MSL。这样可让TCP再次发送最后的ACK以防这个ACK丢失(另一端超时并重发最后的FIN)。
这种2MSL等待的另一个结果是这个TCP连接在2MSL等待期间,定义这个连接的插口(客户的IP地址和端口号,服务器的IP地址和端口号)不能再被使用。这个连接只能在2MSL结束后才能再被使用。
四次挥手释放连接时,等待2MSL的意义?
- 保证客户端发送的最后一个ACK报文段能够到达服务端。 这个ACK报文段有可能丢失,使得处于LAST-ACK状态的服务器收不到对已发送的FIN+ACK报文段的确认,服务端超时重传FIN+ACK报文段,而客户端能在2MSL时间内收到这个重传的FIN+ACK报文段,接着客户端重传一次确认,重新启动2MSL计时器,最后客户端和服务端都进入到CLOSED状态,若客户端在TIME-WAIT状态不等待一段时间,而是发送完ACK报文段后立即释放连接,则无法收到服务端重传的FIN+ACK报文段,所以不会再发送一次确认报文段,则服务端无法正常进入到CLOSED状态。
- 防止“已失效的连接请求报文段”出现在本连接中。 客户端在发送完最后一个ACK报文段后,再经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,使下一个新的连接中不会出现这种旧的连接请求报文段。
TCP粘包问题是什么?你会如何去解决它?
TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
造成TCP粘包的原因:
- TCP连接复用
- TCP默认会使用Nagle算法,此算法会导致粘包问题
- 数据包过大
- 流量控制,拥塞控制也可能导致粘包
- 接收方不及时接收缓冲区的包,造成多个包接收
解决方案:
- Nagle算法问题导致的,需要结合应用场景适当关闭该算法
- 尾部标记序列。通过特殊标识符表示数据包的边界,例如或者一些隐藏字符
- 头部标记分步接收。在TCP报文的头部加上表示数据长度
- 应用层发送数据时定长发送
对称密钥加密的优点缺点?
对称密钥加密(Symmetric-Key Encryption),加密和解密使用同一密钥。
优点:运算速度快
缺点:无法安全地将密钥传输给通信方
非对称密钥加密你了解吗?优缺点?
非对称密钥加密,又称公开密钥加密(Public-Key Encryption),加密和解密使用不同的密钥。
公开密钥所有人都可以获得,通信发送方获得接收方的公开密钥之后,就可以使用公开密钥进行加密,接收方收到通信内容后使用私有密钥解密。
非对称密钥除了用来加密,还可以用来进行签名。因为私有密钥无法被其他人获取,因此通信发送方使用其私有密钥进行签名,通信接收方使用发送方的公开密钥对签名进行解密,就能判断这个签名是否正确。
优点:可以更安全地将公开密钥传输给通信发送方;
缺点:运算速度慢。
HTTPS是什么?
HTTPS 并不是新协议,而是让 HTTP 先和 SSL(Secure Sockets Layer)通信,再由 SSL 和 TCP 通信,也就是说 HTTPS 使用了隧道进行通信。通过使用 SSL,HTTPS 具有了加密(防窃听)、认证(防伪装)和完整性保护(防篡改)。
HTTP的缺点有哪些?
- 使用明文进行通信,内容可能会被窃听;
- 不验证通信方的身份,通信方的身份有可能遭遇伪装;
- 无法证明报文的完整性,报文有可能遭篡改。
HTTPS采用的加密方式有哪些?是对称还是非对称?
PS 采用混合的加密机制,使用非对称密钥加密用于传输对称密钥来保证传输过程的安全性,之后使用对称密钥加密进行通信来保证通信过程的效率。
为什么有的时候刷新页面不需要重新建立 SSL 连接?
TCP 连接有的时候会被浏览器和服务端维持一段时间,TCP 不需要重新建立,SSL 自然也会用之前的。
SSL中的认证中的证书是什么?了解过吗?
通过使用 证书 来对通信方进行认证。
数字证书认证机构(CA,Certificate Authority)是客户端与服务器双方都可信赖的第三方机构。
服务器的运营人员向 CA 提出公开密钥的申请,CA 在判明提出申请者的身份之后,会对已申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将该公开密钥放入公开密钥证书后绑定在一起。
进行 HTTPS 通信时,服务器会把证书发送给客户端。客户端取得其中的公开密钥之后,先使用数字签名进行验证,如果验证通过,就可以开始通信了。
HTTP如何禁用缓存?如何确认缓存?
HTTP/1.1 通过 Cache-Control 首部字段来控制缓存。
禁止进行缓存
no-store 指令规定不能对请求或响应的任何一部分进行缓存。
1 |
|
强制确认缓存
no-cache 指令规定缓存服务器需要先向源服务器验证缓存资源的有效性,只有当缓存资源有效时才能使用该缓存对客户端的请求进行响应。
1 |
|
GET与POST传递数据的最大长度能够达到多少呢?
get 是通过URL提交数据,因此GET可提交的数据量就跟URL所能达到的最大长度有直接关系。
很多文章都说GET方式提交的数据最多只能是1024字节,而实际上,URL不存在参数上限的问题,HTTP协议规范也没有对URL长度进行限制。
这个限制是特定的浏览器及服务器对它的限制,比如IE对URL长度的限制是2083字节(2K+35字节)。对于其他浏览器,如FireFox,Netscape等,则没有长度限制,这个时候其限制取决于服务器的操作系统;即如果url太长,服务器可能会因为安全方面的设置从而拒绝请求或者发生不完整的数据请求。
post 理论上讲是没有大小限制的,HTTP协议规范也没有进行大小限制,但实际上post所能传递的数据量大小取决于服务器的设置和内存大小。
因为我们一般post的数据量很少超过MB的,所以我们很少能感觉的到post的数据量限制,但实际中如果你上传文件的过程中可能会发现这样一个问题,即上传个头比较大的文件到服务器时候,可能上传不上去。
以php语言来说,查原因的时候你也许会看到有说PHP上传文件涉及到的参数PHP默认的上传有限定,一般这个值是2MB,更改这个值需要更改php.conf的post_max_size这个值。这就很明白的说明了这个问题了。
网络层常见协议?可以说一下吗?
协议 | 名称 | 作用 |
---|---|---|
IP | 网际协议 | IP协议不但定义了数据传输时的基本单元和格式,还定义了数据报的递交方法和路由选择 |
ICMP | Internet控制报文协议 | ICMP就是一个“错误侦测与回报机制”,其目的就是让我们能够检测网路的连线状况﹐也能确保连线的准确性,是ping和traceroute的工作协议 |
RIP | 路由信息协议 | 使用“跳数”(即metric)来衡量到达目标地址的路由距离 |
IGMP | Internet组管理协议 | 用于实现组播、广播等通信 |
TCP四大拥塞控制算法总结?*
四大算法
拥塞控制主要是四个算法:1)慢启动,2)拥塞避免,3)拥塞发生,4)快速恢复。这四个算法不是一天都搞出来的,这个四算法的发展经历了很多时间,到今天都还在优化中。
慢启动算法 – Slow Start
所谓慢启动,也就是TCP连接刚建立,一点一点地提速,试探一下网络的承受能力,以免直接扰乱了网络通道的秩序。
慢启动算法:
- 连接建好的开始先初始化拥塞窗口cwnd大小为1,表明可以传一个MSS大小的数据。
- 每当收到一个ACK,cwnd大小加一,呈线性上升。
- 每当过了一个往返延迟时间RTT(Round-Trip Time),cwnd大小直接翻倍,乘以2,呈指数让升。
- 还有一个ssthresh(slow start threshold),是一个上限,当cwnd >= ssthresh时,就会进入“拥塞避免算法”(后面会说这个算法)
拥塞避免算法 – Congestion Avoidance
如同前边说的,当拥塞窗口大小cwnd大于等于慢启动阈值ssthresh后,就进入拥塞避免算法。算法如下:
- 收到一个ACK,则cwnd = cwnd + 1 / cwnd
- 每当过了一个往返延迟时间RTT,cwnd大小加一。
过了慢启动阈值后,拥塞避免算法可以避免窗口增长过快导致窗口拥塞,而是缓慢的增加调整到网络的最佳值。
拥塞发生状态时的算法
一般来说,TCP拥塞控制默认认为网络丢包是由于网络拥塞导致的,所以一般的TCP拥塞控制算法以丢包为网络进入拥塞状态的信号。对于丢包有两种判定方式,一种是超时重传RTO[Retransmission Timeout]超时,另一个是收到三个重复确认ACK。
超时重传是TCP协议保证数据可靠性的一个重要机制,其原理是在发送一个数据以后就开启一个计时器,在一定时间内如果没有得到发送数据报的ACK报文,那么就重新发送数据,直到发送成功为止。
但是如果发送端接收到3个以上的重复ACK,TCP就意识到数据发生丢失,需要重传。这个机制不需要等到重传定时器超时,所以叫做快速重传,而快速重传后没有使用慢启动算法,而是拥塞避免算法,所以这又叫做快速恢复算法。
超时重传RTO[Retransmission Timeout]超时,TCP会重传数据包。TCP认为这种情况比较糟糕,反应也比较强烈:
- 由于发生丢包,将慢启动阈值ssthresh设置为当前cwnd的一半,即ssthresh = cwnd / 2.
- cwnd重置为1
- 进入慢启动过程
最为早期的TCP Tahoe算法就只使用上述处理办法,但是由于一丢包就一切重来,导致cwnd又重置为1,十分不利于网络数据的稳定传递。
所以,TCP Reno算法进行了优化。当收到三个重复确认ACK时,TCP开启快速重传Fast Retransmit算法,而不用等到RTO超时再进行重传:
- cwnd大小缩小为当前的一半
- ssthresh设置为缩小后的cwnd大小
- 然后进入快速恢复算法Fast Recovery
快速恢复算法 – Fast Recovery
TCP Tahoe是早期的算法,所以没有快速恢复算法,而Reno算法有。在进入快速恢复之前,cwnd和ssthresh已经被更改为原有cwnd的一半。快速恢复算法的逻辑如下:
- cwnd = cwnd + 3 MSS,加3 MSS的原因是因为收到3个重复的ACK。
- 重传DACKs指定的数据包。
- 如果再收到DACKs,那么cwnd大小增加一。
- 如果收到新的ACK,表明重传的包成功了,那么退出快速恢复算法。将cwnd设置为ssthresh,然后进入拥塞避免算法。
为何快速重传是选择3次重复ACK?
主要的考虑还是要区分包的丢失是由于链路故障还是乱序等其他因素引发。
两次duplicated ACK时很可能是乱序造成的!三次duplicated ACK时很可能是丢包造成的!四次duplicated ACK更更更可能是丢包造成的,但是这样的响应策略太慢。丢包肯定会造成三次duplicated ACK!综上是选择收到三个重复确认时窗口减半效果最好,这是实践经验。
在没有fast retransmit / recovery 算法之前,重传依靠发送方的retransmit timeout,就是在timeout内如果没有接收到对方的ACK,默认包丢了,发送方就重传,包的丢失原因
- 包checksum 出错
- 网络拥塞
- 网络断,包括路由重收敛,但是发送方无法判断是哪一种情况,于是采用最笨的办法,就是将自己的发送速率减半,即CWND 减为1/2,这样的方法对2是有效的,可以缓解网络拥塞,3则无所谓,反正网络断了,无论发快发慢都会被丢;但对于1来说,丢包是因为偶尔的出错引起,一丢包就对半减速不合理。
于是有了fast retransmit 算法,基于在反向还可以接收到ACK,可以认为网络并没有断,否则也接收不到ACK,如果在timeout 时间内没有接收到> 2 的duplicated ACK,则概率大事件为乱序,乱序无需重传,接收方会进行排序工作;
而如果接收到三个或三个以上的duplicated ACK,则大概率是丢包,可以逻辑推理,发送方可以接收ACK,则网络是通的,可能是1、2造成的,先不降速,重传一次,如果接收到正确的ACK,则一切OK,流速依然(包出错被丢)。
而如果依然接收到duplicated ACK,则认为是网络拥塞造成的,此时降速则比较合理。
对于FIN_WAIT_2,CLOSE_WAIT状态和TIME_WAIT状态?你知道多少?
FIN_WAIT_2:
- 半关闭状态。
- 发送断开请求一方还有接收数据能力,但已经没有发送数据能力。
CLOSE_WAIT状态:
- 被动关闭连接一方接收到FIN包会立即回应ACK包表示已接收到断开请求。
- 被动关闭连接一方如果还有剩余数据要发送就会进入CLOSE_WAIT状态。
TIME_WAIT状态:
- 又叫2MSL等待状态。
- 如果客户端直接进入CLOSED状态,如果服务端没有接收到最后一次ACK包会在超时之后重新再发FIN包,此时因为客户端已经CLOSED,所以服务端就不会收到ACK而是收到RST。所以TIME_WAIT状态目的是防止最后一次握手数据没有到达对方而触发重传FIN准备的。
- 在2MSL时间内,同一个socket不能再被使用,否则有可能会和旧连接数据混淆(如果新连接和旧连接的socket相同的话)。
你了解流量控制原理吗?
- 目的:接收方通过TCP头窗口字段告知发送方本方可接收的最大数据量,用以解决发送速率过快导致接收方不能接收的问题。所以流量控制是点对点控制。
- TCP是双工协议,双方可以同时通信,所以发送方接收方各自维护一个发送窗和接收窗。
- 发送窗:用来限制发送方可以发送的数据大小,其中发送窗口的大小由接收端返回的TCP报文段中窗口字段来控制,接收方通过此字段告知发送方自己的缓冲(受系统、硬件等限制)大小。
- 接收窗:用来标记可以接收的数据大小。
- TCP是流数据,发送出去的数据流可以被分为以下四部分:已发送且被确认部分 | 已发送未被确认部分 | 未发送但可发送部分 | 不可发送部分,其中发送窗 = 已发送未确认部分 + 未发但可发送部分。接收到的数据流可分为:已接收 | 未接收但准备接收 | 未接收不准备接收。接收窗 = 未接收但准备接收部分。
- 发送窗内数据只有当接收到接收端某段发送数据的ACK响应时才移动发送窗,左边缘紧贴刚被确认的数据。接收窗也只有接收到数据且最左侧连续时才移动接收窗口。
建立TCP服务器的各个系统调用过程是怎样的?
![TCP的系统调用过程](/img/C++八股文/计网/TCP系统调用流程.png)
![TCP的系统调用过程](/img/C++八股文/计网/TCP系统调用流程-1.png)
TCP 协议如何保证可靠传输?
首部校验 这个校验机制能够确保数据传输不会出错吗? 答案是不能。
解决方案:
传输之前先使用MD5加密数据获得摘要,跟数据一起发送到服务端,服务端接收之后对数据也进行MD5加密,如果加密结果和摘要一致,则认为没有问题
UDP是什么?
提供无连接的,尽最大努力的数据传输服务(不保证数据传输的可靠性)。
TCP和UDP的区别
- TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
- TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
- TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的, UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
- 每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
- TCP首部开销20字节;UDP的首部开销小,只有8个字节
- TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道
- UDP是面向报文的,发送方的UDP对应用层交下来的报文,不合并,不拆分,只是在其上面加上首部后就交给了下面的网络层,论应用层交给UDP多长的报文,它统统发送,一次发送一个。而对接收方,接到后直接去除首部,交给上面的应用层就完成任务了。因此,它需要应用层控制报文的大小;TCP是面向字节流的,它把上面应用层交下来的数据看成无结构的字节流会发送,可以想象成流水形式的,发送方TCP会将数据放入“蓄水池”(缓存区),等到可以发送的时候就发送,不能发送就等着TCP会根据当前网络的拥塞状态来确定每个报文段的大小。
封包和拆包你听说过吗?它是基于TCP还是UDP的?
封包和拆包都是基于TCP的概念。因为TCP是无边界的流传输,所以需要对TCP进行封包和拆包,确保发送和接收的数据不粘连。
- 封包:封包就是在发送数据报的时候为每个TCP数据包加上一个包头,将数据报分为包头和包体两个部分。包头是一个固定长度的结构体,里面包含该数据包的总长度。
- 拆包:接收方在接收到报文后提取包头中的长度信息进行截取。
TCP和UPD的特点
UDP特点
- UDP是无连接的;
- UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态(这里面有许多参数);
- UDP是面向报文的;
- UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等);
- UDP支持一对一、一对多、多对一和多对多的交互通信;
- UDP的首部开销小,只有8个字节,比TCP的20个字节的首部要短。
TCP特点
- TCP是面向连接的。
- 每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的(一对一);
- TCP提供可靠交付的服务。通过TCP连接传送的数据,无差错、不丢失、不重复、并且按序到达;
- TCP提供全双工通信。TCP允许通信双方的应用进程在任何时候都能发送数据。TCP连接的两端都设有发送缓存和接收缓存,用来临时存放双方通信的数据;
- 面向字节流。TCP中的“流”(stream)指的是流入进程或从进程流出的字节序列。“面向字节流”的含义是:虽然应用程序和TCP的交互是一次一个数据块(大小不等),但TCP把应用程序交下来的数据仅仅看成是一连串的无结构的字节流。
TCP对应的应用层协议有哪些?
- FTP:定义了文件传输协议,使用21端口.
- Telnet:它是一种用于远程登陆的端口,23端口
- SMTP:定义了简单邮件传送协议,服务器开放的是25号端口。
- POP3:它是和SMTP对应,POP3用于接收邮件。
UDP对应的应用层协议
- DNS:用于域名解析服务,用的是53号端口
- SNMP:简单网络管理协议,使用161号端口
- TFTP(Trival File Transfer Protocal):简单文件传输协议,69
数据链路层常见协议?可以说一下吗?
协议 | 名称 | 作用 |
---|---|---|
ARP | 地址解析协议 | 根据IP地址获取物理地址 |
RARP | 逆地址解析协议 | 根据物理地址获取IP地址 |
PPP | 点对点协议 | 在两点之间建立可靠的通信链路 |
Ping命令基于什么协议?原理是什么?
ping是基于网络层的ICMP协议实现的。通过向对方发送一个ICMP回送请求报文,如果对方主机可达的话会收到该报文,并响应一个ICMP回送回答报文。
ICMP协议类型
ICMP报文分为两个种类:
- ICMP差错报告报文,常见的有
- 终点不可达
- 时间超过
- 参数问题
- 改变路由
- ICMP询问报文
- 回送请求和回答:向特定主机发出回送请求报文,收到回送请求报文的主机响应回送回答报文。
- 时间戳请求和回答:询问对方当前的时间,返回的是一个32位的时间戳。
在进行UDP编程的时候,一次发送多少bytes好?
当然,这个没有唯一答案,相对于不同的系统,不同的要求,其得到的答案是不一样的。
我这里仅对像ICQ一类的发送聊天消息的情况作分析,对于其他情况,你或许也能得到一点帮助:首先,我们知道,TCP/IP通常被认为是一个四层协议系统,包括链路层,网络层,运输层,应用层.UDP属于运输层,
下面我们由下至上一步一步来看:以太网(Ethernet)数据帧的长度必须在46-1500字节之间,这是由以太网的物理特性决定的.这个1500字节被称为链路层的MTU(最大传输单元).但这并不是指链路层的长度被限制在1500字节,其实这这个MTU指的是链路层的数据区.并不包括链路层的首部和尾部的18个字节.
所以,事实上,这个1500字节就是网络层IP数据报的长度限制。因为IP数据报的首部为20字节,所以IP数据报的数据区长度最大为1480字节.而这个1480字节就是用来放TCP传来的TCP报文段或UDP传来的UDP数据报的.又因为UDP数据报的首部8字节,所以UDP数据报的数据区最大长度为1472字节.这个1472字节就是我们可以使用的字节数。
当我们发送的UDP数据大于1472的时候会怎样呢? 这也就是说IP数据报大于1500字节,大于MTU.这个时候发送方IP层就需要分片(fragmentation). 把数据报分成若干片,使每一片都小于MTU.而接收方IP层则需要进行数据报的重组. 这样就会多做许多事情,而更严重的是,由于UDP的特性,当某一片数据传送中丢失时,接收方便 无法重组数据报.将导致丢弃整个UDP数据报。
因此,在普通的局域网环境下,我建议将UDP的数据控制在1472字节以下为好.
进行Internet编程时则不同,因为Internet上的路由器可能会将MTU设为不同的值. 如果我们假定MTU为1500来发送数据的,而途经的某个网络的MTU值小于1500字节,那么系统将会使用一系列的机 制来调整MTU值,使数据报能够顺利到达目的地,这样就会做许多不必要的操作.
鉴于Internet上的标准MTU值为576字节,所以我建议在进行Internet的UDP编程时. 最好将UDP的数据长度控件在576-8-20=548字节以内
TCP实现流量控制的机制?
流量控制是为了控制发送方发送速率,保证接收方来得及接收。TCP 利用滑动窗口实现流量控制。
TCP 中采用滑动窗口来进行传输控制,滑动窗口的大小意味着接收方还有多大的缓冲区可以用于接收数据。发送方可以通过滑动窗口的大小来确定应该发送多少字节的数据。当滑动窗口为 0 时,发送方一般不能再发送数据报,但有两种情况除外,一种情况是可以发送紧急数据。例如,允许用户终止在远端机上的运行进程。另一种情况是发送方可以发送一个 1 字节的数据报来通知接收方重新声明它希望接收的下一字节及发送方的滑动窗口大小。
可以解释一下RTO,RTT和超时重传分别是什么吗?
- RTO:从上一次发送数据,因为长期没有收到ACK响应,到下一次重发之间的时间。就是重传间隔。
- 通常每次重传RTO是前一次重传间隔的两倍,计量单位通常是RTT。例:1RTT,2RTT,4RTT,8RTT......
- 重传次数到达上限之后停止重传。
- RTT:数据从发送到接收到对方响应之间的时间间隔,即数据报在网络中一个往返用时。大小不稳定。
- 超时重传:发送端发送报文后若长时间未收到确认的报文则需要重发该报文。可能有以下几种情况:
- 发送的数据没能到达接收端,所以对方没有响应。
- 接收端接收到数据,但是ACK报文在返回过程中丢失。
- 接收端拒绝或丢弃数据。
XSS攻击是什么?(低频)
跨站点脚本攻击,指攻击者通过篡改网页,嵌入恶意脚本程序,在用户浏览网页时,控制用户浏览器进行恶意操作的一种攻击方式。
如何防范XSS攻击?
- 前端,服务端,同时需要字符串输入的长度限制。
- 前端,服务端,同时需要对HTML转义处理。将其中的”<”,”>”等特殊字符进行转义编码。 防 XSS 的核心是必须对输入的数据做过滤处理。
CSRF攻击?
跨站点请求伪造,指攻击者通过跨站请求,以合法的用户的身份进行非法操作。可以这么理解CSRF攻击:攻击者盗用你的身份,以你的名义向第三方网站发送恶意请求。CRSF能做的事情包括利用你的身份发邮件,发短信,进行交易转账,甚至盗取账号信息。
如何防范CSRF攻击?
- 安全框架,例如Spring Security。
- token机制。在HTTP请求中进行token验证,如果请求中没有token或者token内容不正确,则认为CSRF攻击而拒绝该请求。
- 验证码。通常情况下,验证码能够很好的遏制CSRF攻击,但是很多情况下,出于用户体验考虑,验证码只能作为一种辅助手段,而不是最主要的解决方案。
- referer识别。在HTTP
Header中有一个字段Referer,它记录了HTTP请求的来源地址。如果Referer是其他网站,就有可能是CSRF攻击,则拒绝该请求。但是,服务器并非都能取到Referer。很多用户出于隐私保护的考虑,限制了Referer的发送。在某些情况下,浏览器也不会发送Referer,例如HTTPS跳转到HTTP。
- 验证请求来源地址;
- 关键操作添加验证码;
- 在请求地址添加 token 并验证。
文件上传漏洞是如何发生的?如何防范文件上传漏洞?
文件上传漏洞,指的是用户上传一个可执行的脚本文件,并通过此脚本文件获得了执行服务端命令的能力。 许多第三方框架、服务,都曾经被爆出文件上传漏洞,比如很早之前的Struts2,以及富文本编辑器等等,可被攻击者上传恶意代码,有可能服务端就被人黑了。
如何防范文件上传漏洞?
- 判断文件类型。在判断文件类型的时候,可以结合使用MIME Type,后缀检查等方式。因为对于上传文件,不能简单地通过后缀名称来判断文件的类型,因为攻击者可以将可执行文件的后缀名称改为图片或其他后缀类型,诱导用户执行。
- 对上传的文件类型进行白名单校验,只允许上传可靠类型。
- 上传的文件需要进行重新命名,使攻击者无法猜想上传文件的访问路径,将极大地增加攻击成本,同时向shell.php.rar.ara这种文件,因为重命名而无法成功实施攻击。
- 限制上传文件的大小。
- 单独设置文件服务器的域名。
如何区分流量控制和拥塞控制?
流量控制和拥塞控制是网络通信中两个重要的概念,它们的主要区别在于目标和作用对象。
流量控制:
- 作用对象:主要针对发送者和接收者之间的数据流量进行控制。
- 目标:控制发送者的发送速度,使得接收者来得及接收,防止分组丢失。
- 实现原理:通过滑动窗口协议实现,接收方告知发送方自己的窗口大小,发送方立刻更改即可实现流量控制。
拥塞控制:
- 作用对象:主要针对网络中的节点和链路进行控制。
- 目标:防止过多的数据注入到网络中,避免出现网络负载过大的情况。
- 实现原理:常用的方法有慢开始、拥塞避免、快重传、快速恢复。发送方会维持一个拥塞窗口(动态变化),拥塞窗口的大小代表着网络的拥塞程度。
总的来说,流量控制是为了防止接收方被淹没,而拥塞控制是为了防止网络被淹没。这两种控制机制共同保证了网络通信的稳定和高效。
常见的HTTP状态码有哪些?
状态码 | 类别 | 含义 |
---|---|---|
1xx | Informational(信息性状态码) | 接收的请求正在处理 |
2xx | Success(成功状态码) | 请求正常处理完毕 |
3xx | Redirection(重定向状态码) | 需要进行附加操作以完成请求 |
4xx | Client Error(客户端错误状态码) | 服务器无法处理请求 |
5xx | Server Error(服务器错误状态码) | 服务器处理请求出错 |
1xx 信息
100 Continue :表明到目前为止都很正常,客户端可以继续发送请求或者忽略这个响应。
2xx 成功
- 200 OK
- 204 No Content :请求已经成功处理,但是返回的响应报文不包含实体的主体部分。一般在只需要从客户端往服务器发送信息,而不需要返回数据时使用。
- 206 Partial Content :表示客户端进行了范围请求,响应报文包含由 Content-Range 指定范围的实体内容。
3xx 重定向
- 301 Moved Permanently :永久性重定向
- 302 Found :临时性重定向
- 303 See Other :和 302 有着相同的功能,但是 303 明确要求客户端应该采用 GET 方法获取资源。
- 304 Not Modified :如果请求报文首部包含一些条件,例如:If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since,如果不满足条件,则服务器会返回 304 状态码。
- 307 Temporary Redirect :临时重定向,与 302 的含义类似,但是 307 要求浏览器不会把重定向请求的 POST 方法改成 GET 方法。
4xx 客户端错误
- 400 Bad Request :请求报文中存在语法错误。
- 401 Unauthorized :该状态码表示发送的请求需要有认证信息(BASIC 认证、DIGEST 认证)。如果之前已进行过一次请求,则表示用户认证失败。
- 403 Forbidden :请求被拒绝。
- 404 Not Found
5xx 服务器错误
- 500 Internal Server Error :服务器正在执行请求时发生错误。
- 503 Service Unavailable :服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。
三次握手过程中bind()、listen()、accept()哪个环节?
bind()
: 该函数用于将一个本地地址绑定到套接字,指定套接字使用的IP地址和端口号。这对应于第一次握手中客户端发送SYN请求的时候,客户端选择一个本地端口并将其绑定到目标IP地址上。listen()
: 该函数使套接字进入监听状态,等待客户端的连接请求。这对应于第一次握手中服务端收到客户端的SYN请求,服务端准备接受连接。accept()
: 该函数用于接受客户端的连接请求,创建一个新的套接字用于与客户端通信。这对应于第二次握手中服务端发送SYN-ACK,表示接受连接。connect()
: 该函数用于发起到远程套接字的连接请求。这对应于第三次握手中客户端接收到服务端的SYN-ACK后,发送ACK表示连接建立成功。
socket端口复用
C++可以使用setsockopt
函数,并将SO_REUSEADDR
选项设置为1
。这样可以允许多个socket绑定到同一端口上。
HTTP对文件的分段是怎么设计的?
- 分块传输标识:
在HTTP响应的头部,通过设置
Transfer-Encoding: chunked
来表示服务器将采用分块传输的方式。这告诉客户端,响应实体主体将以块的形式进行传输。 - 数据块格式: 每个数据块由两部分组成,分别是十六进制的块大小和块数据。块大小指示了当前块包含的数据的字节数,然后是一个CRLF(回车换行)标志,接着是实际的数据,再以CRLF标志结束。
- 最后的块: 为了表示数据传输的结束,使用一个零大小的块("0")。这表明没有更多的块要传输,标志着实体主体的结束。
下面是一个简单的示例,展示了一个包含两个分块的HTTP响应:
1 |
|
在这个例子中,第一个块大小为7(十进制),包含字符串"Hello, ";第二个块大小为6,包含字符串"world!";最后的块为0,表示传输结束。
RPC协议
RPC(Remote Procedure Call)远程过程调用协议是一个用于建立适当框架的协议。从本质上讲,它使一台机器上的程序能够调用另一台机器上的子程序,而不会意识到它是远程的。
为什么会有RPC
大多数独立的应用程序并没有那么多地使用消息传递技术。一般来说,首选的机制是函数(或方法或过程)的调用。RPC 就是将这种编程方式引入网络世界的一种尝试。
RPC如何工作
![See the source image](/img/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/17dffc912301f96a0d2c7b6f55255365.png)
常见的网络攻击方式有哪些
- SQL注入攻击
- DDoS攻击
- 中间人攻击
- 暴力破解
- 网络钓鱼
- 零日攻击