搞定下面这些面试题,2021春招月薪过5万(猛!) | 阿里、京东、美团、头条… 随意挑、横着走!!! |
---|---|
Java基础 | |
JVM面试题(史上最强、持续更新、吐血推荐) | https://www.cnblogs.com/crazymakercircle/p/14365820.html |
Java基础面试题(史上最全、持续更新、吐血推荐) | https://www.cnblogs.com/crazymakercircle/p/14366081.html |
死锁面试题(史上最强、持续更新) | https://www.cnblogs.com/crazymakercircle/p/14323919.html |
多线程、线程池、内置锁 面试题 (史上最强、持续更新) | https://www.cnblogs.com/crazymakercircle/p/13903850.html |
JUC并发包与容器类 - 面试题(史上最强、持续更新) | https://www.cnblogs.com/crazymakercircle/p/13904029.html |
SpringBoot - 面试题(史上最强、持续更新) | https://www.cnblogs.com/crazymakercircle/p/14365487.html |
Linux面试题(史上最全、持续更新、吐血推荐) | https://www.cnblogs.com/crazymakercircle/p/14366893.html |
网络协议面试题(史上最全、持续更新、吐血推荐) | https://www.cnblogs.com/crazymakercircle/p/14370335.html |
分布式、高并发、设计模式、架构 | |
Zookeeper 面试题(史上最强、持续更新) | https://www.cnblogs.com/crazymakercircle/p/13900183.html |
Mysql 面试题(史上最强、持续更新) | https://www.cnblogs.com/crazymakercircle/p/13900186.html |
Redis 面试题 - 收藏版(史上最强、持续更新) | https://www.cnblogs.com/crazymakercircle/p/13900198.html |
SpringCloud 面试题 - 收藏版(史上最强、持续更新) | https://www.cnblogs.com/crazymakercircle/p/13900212.html |
Netty 面试题 (史上最强、持续更新) | https://www.cnblogs.com/crazymakercircle/p/13903625.html |
消息队列、RabbitMQ、Kafka、RocketMQ面试题 (史上最全、持续更新) | https://www.cnblogs.com/crazymakercircle/p/14367425.html |
设计模式面试题 (史上最全、持续更新、吐血推荐) | https://www.cnblogs.com/crazymakercircle/p/14367101.html |
架构设计面试题 (史上最全、持续更新、吐血推荐) | https://www.cnblogs.com/crazymakercircle/p/14367907.html |
(1)、解析域名。
(2)、发起TCP的3次握手。
(3)、建立TCP请求后发起HTTP请求。
(4)、服务器相应HTTP请求。
(5)、浏览器得到HTML代码,进行解析和处理JSON数据,并请求HTML代码中的静态资源(JS、CSS、图片等)。
(6)、浏览器对页面进行渲染。
★ GET:获取资源。
★ POST:表单提交。
★ HEAD:获取报头信息,HEAD 方法与 GET 方法类似,但并不会返回响应主体。
★ PUT 与PATCH:更新资源,PUT 对后台来说 PUT 方法的参数是一个完整的资源对象,它包含了对象的所有字段,PATCH 对后台来说 PATCH 方法的参数只包含我们需要修改的资源对象的字段。
★ DELETE:删除资源。
★ OPTIONS:获取目标资源所支持的通信选项,使用 OPTIONS 方法对服务器发起请求,以检测服务器支持哪些 HTTP 方法。
加密方式: 1)、对称密码算法:指加密和解密使用相同的密钥,速度高,可加密内容较大,用来加密会话过程中的消息。典型算法DES、AES、RC5、IDEA(分组加密)RC4。
2)、非对称密码算法:又称为公钥加密算法,是指加密和解密使用不同的密钥,加密速度较慢,但能提供更好的身份认证技术,用来加密对称加密的密钥(公开的密钥用于加密,私有的密钥用于解密)典型的算法RSA、DSA、DH。
3)、散列算法:将文件内容通过此算法加密变成固定长度的值(散列值),这个过程可以使用密钥也可以不使用。这种散列变化是不可逆的,也就是说不能从散列值编程原文,因此散列变化通道常用语验证原文是否被篡改。典型的算法MD5、SHA、BASE64、CRC等。
HTTP 的URL 以http:// 开头,而HTTPS 的URL 以https:// 开头
HTTP 是不安全的,而 HTTPS 是安全的
HTTP 标准端口是80 ,而 HTTPS 的标准端口是443
在OSI 网络模型中,HTTP工作于应用层,而HTTPS 的安全传输机制工作在传输层
HTTP 无法加密,而HTTPS 对传输的数据进行加密
HTTP无需证书,而HTTPS 需要CA机构颁发的SSL证书
无状态协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息
也就是说,当客户端一次HTTP请求完成以后,客户端再发送一次HTTP请求,HTTP并不知道当前客户端是一个”老用户“。
可以使用Cookie来解决无状态的问题,Cookie就相当于一个通行证,第一次访问的时候给客户端发送一个Cookie,当客户端再次来的时候,拿着Cookie(通行证),那么服务器就知道这个是”老用户“
URI,是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源。
Web上可用的每种资源如HTML文档、图像、视频片段、程序等都是一个来URI来定位的
URI一般由三部组成:
①访问资源的命名机制
②存放资源的主机名
③资源自身的名称,由路径表示,着重强调于资源。
URL是uniform resource locator,统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。
URL是Internet上用来描述信息资源的字符串,主要用在各种WWW客户程序和服务器程序上,特别是著名的Mosaic。
采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。URL一般由三部组成:
①协议(或称为服务方式)
②存有该资源的主机IP地址(有时也包括端口号)
③主机资源的具体地址。如目录和文件名等
200:请求被正常处理
204:请求被受理但没有资源可以返回
206:客户端只是请求资源的一部分,服务器只对请求的部分资源执行GET方法,相应报文中通过Content-Range指定范围的资源。
301:永久性重定向
302:临时重定向
303:与302状态码有相似功能,只是它希望客户端在请求一个URI的时候,能通过GET方法重定向到另一个URI上
304:发送附带条件的请求时,条件不满足时返回,与重定向无关
307:临时重定向,与302类似,只是强制要求使用POST方法
400:请求报文语法有误,服务器无法识别
401:请求需要认证
403:请求的对应资源禁止被访问
404:服务器无法找到对应资源
500:服务器内部错误
503:服务器正忙
我下面就简要概括一下:
TCP复用:TCP连接复用是将多个客户端的HTTP请求复用到一个服务器端TCP连接上,而HTTP复用则是一个客户端的多个HTTP请求通过一个TCP连接进行处理。前者是负载均衡设备的独特功能;而后者是HTTP 1.1协议所支持的新功能
内容缓存:将经常用到的内容进行缓存起来,那么客户端就可以直接在内存中获取相应的数据了。
压缩:将文本数据进行压缩,减少带宽
SSL加速(SSL Acceleration):使用SSL协议对HTTP协议进行加密,在通道内加密并加速
TCP缓冲:通过采用TCP缓冲技术,可以提高服务器端响应时间和处理效率,减少由于通信链路问题给服务器造成的连接负担。
区别一:
get重点在从服务器上获取资源,post重点在向服务器发送数据;
区别二:
get传输数据是通过URL请求,以field(字段)= value的形式,置于URL后,并用"?“连接,多个请求数据间用”&"连接,如http://127.0.0.1/Test/login.action?name=admin&password=admin,这个过程用户是可见的;
post传输数据通过Http的post机制,将字段与对应值封存在请求实体中发送给服务器,这个过程对用户是不可见的;
区别三:
Get传输的数据量小,因为受URL长度限制,但效率较高;
Post可以传输大量数据,所以上传文件时只能用Post方式;
区别四:
get是不安全的,因为URL是可见的,可能会泄露私密信息,如密码等;
post较get安全性较高;
区别五:
get方式只能支持ASCII字符,向服务器传的中文字符可能会乱码。
post支持标准字符集,可以正确传递中文字符。
请求报文包含三部分:
a、请求行:包含请求方法、URI、HTTP版本信息
b、请求首部字段
c、请求内容实体
响应报文包含三部分:
a、状态行:包含HTTP版本、状态码、状态码的原因短语
b、响应首部字段
c、响应内容实体
(1)、Cookie保存在客户端,未设置存储时间的Cookie,关闭浏览器会话Cookie就会被删除;设置了存储时间的Cookie保存在用户设备的磁盘中知道过期,同时Cookie在客户端所以可以伪造,不是十分安全,敏感数据不易保存。Session保存在服务器端,存储在IIS的进程开辟的内存中,而Session过多会消耗服务器资源,所以尽量少使用Session。
(2)、Session是服务器用来跟踪用户的一种手段,每个Session都有一个唯一标识:session ID。当服务端生成一个Session时就会向客户端发送一个Cookie保存到客户端,这个Cookie保存的是Session的SessionId这样才能保证客户端发起请求后,用户能够与服务器端成千上万的Session进行匹配,同时也保证了不同页面之间传值的正确性.
(3)、存储数据类型不同:Session能够存储任意的JAVA对象,Cookie只能存储String类型的对象。
(4)、长于10K的数据,不要用到Cookies。
http的请求报文是什么样的?
请求报文有4部分组成:
请求报文有4部分组成:
HTTP/1.1 200 OK
。内容很多,重点看标『✨』内容
通用首部字段(General Header Fields):请求报文和响应报文两方都会使用的首部
请求首部字段(Reauest Header Fields):客户端向服务器发送请求的报文时使用的首部
响应首部字段(Response Header Fields):从服务器向客户端响应时使用的字段
实体首部字段(Entiy Header Fields):针对请求报文和响应报文的实体部分使用首部
内容很多,重点看标『✨』内容
2XX 成功
3XX 重定向
4XX 客户端错误
5XX 服务器错误
302是http1.0的协议状态码,在http1.1版本的时候为了细化302状态码又出来了两个303和307。
303明确表示客户端应当采用get方法获取资源,他会把POST请求变为GET请求进行重定向。 307会遵照浏览器标准,不会从post变为get。
在早期的HTTP/1.0中,每次http请求都要创建一个连接,而创建连接的过程需要消耗资源和时间,为了减少资源消耗,缩短响应时间,就需要重用连接。在后来的HTTP/1.0中以及HTTP/1.1中,引入了重用连接的机制,就是在http请求头中加入Connection: keep-alive来告诉对方这个请求响应完成后不要关闭,下一次咱们还用这个请求继续交流。协议规定HTTP/1.0如果想要保持长连接,需要在请求头中加上Connection: keep-alive。
keep-alive的优点:
帧:HTTP/2 数据通信的最小单位消息:指 HTTP/2 中逻辑上的 HTTP 消息。例如请求和响应等,消息由一个或多个帧组成。
流:存在于连接中的一个虚拟通道。流可以承载双向消息,每个流都有一个唯一的整数ID
HTTP/2 采用二进制格式传输数据,而非 HTTP 1.x 的文本格式,二进制协议解析起来更高效。
服务端可以在发送页面HTML时主动推送其它资源,而不用等到浏览器解析到相应位置,发起请求再响应。例如服务端可以主动把JS和CSS文件推送给客户端,而不需要客户端解析HTML时再发送这些请求。
服务端可以主动推送,客户端也有权利选择是否接收。如果服务端推送的资源已经被浏览器缓存过,浏览器可以通过发送RST_STREAM帧来拒收。主动推送也遵守同源策略,服务器不会随便推送第三方资源给客户端。
HTTP/1.x会在请求和响应中中重复地携带不常改变的、冗长的头部数据,给网络带来额外的负担。
你可以理解为只发送差异数据,而不是全部发送,从而减少头部的信息量
HTTP 1.x 中,如果想并发多个请求,必须使用多个 TCP 链接,且浏览器为了控制资源,还会对单个域名有 6-8个的TCP链接请求限制。
HTTP2中:
HTTPS ,实际就是在 TCP 层与 HTTP 层之间加入了 SSL/TLS 来为上层的安全保驾护航,主要用到对称加密、非对称加密、证书,等技术进行客户端与服务器的数据加密传输,最终达到保证整个通信的安全性。
https是安全版的http,因为http协议的数据都是明文进行传输的,所以对于一些敏感信息的传输就很不安全,HTTPS就是为了解决HTTP的不安全而生的。
过程比较复杂,我们得先理解两个概念
对称加密:即通信的双方都使用同一个秘钥进行加解密,比如特务接头的暗号,就属于对称加密
对称加密虽然很简单性能也好,但是无法解决首次把秘钥发给对方的问题,很容易被hacker拦截秘钥。
非对称加密:
非对称加密虽然安全性更高,但是带来的问题就是速度很慢,影响性能。
解决方案:
那么结合两种加密方式,将对称加密的密钥使用非对称加密的公钥进行加密,然后发送出去,接收方使用私钥进行解密得到对称加密的密钥,然后双方可以使用对称加密来进行沟通。
此时又带来一个问题,中间人问题:
如果此时在客户端和服务器之间存在一个中间人,这个中间人只需要把原本双方通信互发的公钥,换成自己的公钥,这样中间人就可以轻松解密通信双方所发送的所有数据。
所以这个时候需要一个安全的第三方颁发证书(CA),证明身份的身份,防止被中间人攻击。
证书中包括:签发者、证书用途、使用者公钥、使用者私钥、使用者的HASH算法、证书到期时间等
但是问题来了,如果中间人篡改了证书,那么身份证明是不是就无效了?这个证明就白买了,这个时候需要一个新的技术,数字签名。
数字签名就是用CA自带的HASH算法对证书的内容进行HASH得到一个摘要,再用CA的私钥加密,最终组成数字签名。
当别人把他的证书发过来的时候,我再用同样的Hash算法,再次生成消息摘要,然后用CA的公钥对数字签名解密,得到CA创建的消息摘要,两者一比,就知道中间有没有被人篡改了。
这个时候就能最大程度保证通信的安全了。
消息时的系统通信,通常基于网络协议实现。常见的协议包括TCP/IP,UDP/IP。
TCP/IP等协议用于数据传输,但要完成通信,还需要对数据进行处理。例如读取和写入数据。
I/O可以分为两种:同步IO和异步IO,同步I/O最常见的是 BIO(Blocking IO)、NIO(Non-Blocking IO)
BIO:是当发起I/O的读或写操作时,均为阻塞方式,直到应用程序读到了流或者将流写入数据。
NIO:基于事件驱动思想,常采用reactor(反应器)模式。当发起 IO请求时,应用程序是非阻塞的。当SOCKET有流可读或写的时候,
由操作系统通知应用程序,应用程序再将流读取到缓冲区或者写入系统。
AIO:同样基于事件驱动的思想,通常采用Proactor(前摄器模式)实现。对于读操作,操作系统将数据读到缓冲区,并通知应用程序,对于写操作,操作系统将write方法传递的流写入并主动通知
应用程序。它节省了NIO中遍历事件通知队列的代价。
阻塞 某个请求发出后,由于该请求操作需要的条件不满足,请求操作一直阻塞,不会返回,直到条件满足。
非阻塞 请求发出后,若该请求需要的条件不满足,则立即返回一个标志信息告知条件不满足,而不会一直等待。一般需要通过循环判断请求条件是否满足来获取请求结果。
这里注意比较NIO和AIO的不同,AIO是操作系统完成IO并通知应用程序,NIO是操作系统通知应用程序,由应用程序完成。
reactor 模型
当客户端请求抵达后,服务处理程序使用多路分配策略,由一个非阻塞的线程来接收所有的请求,然后派发这些请求至相关的工作线程进行处理
自上而下是:
应用层(数据):确定进程之间通信的性质以满足用户需要以及提供网络与用户应用
表示层(数据):主要解决用户信息的语法表示问题,如加密解密
会话层(数据):提供包括访问验证和会话管理在内的建立和维护应用之间通信的机制,如服务器验证用户登录便是由会话层完成的
传输层(段):实现网络不同主机上用户进程之间的数据通信,可靠
与不可靠的传输,传输层的错误检测,流量控制等
网络层(包):提供逻辑地址(IP)、选路,数据从源端到目的端的
传输
数据链路层(帧):将上层数据封装成帧,用MAC地址访问媒介,错误检测与修正
物理层(比特流):设备之间比特流的传输,物理接口,电气特性等
TCP/IP协议按照层次分为以下四层。应用层、传输层、网络层、数据链路层。
TCP(Transmission Control Protocol,传输控制协议)是面向连接的协议,也就是说,在收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来,其中的过程非常复杂,
TCP首部选项字段多达40B,一些常用的字段有:
1)选项结束字段(EOP,0x00),占1B,一个报文段仅用一次。放在末尾用于填充,用途是说明:首部已经没有更多的消息,应用数据在下一个32位字开始处
2)无操作字段(NOP, 0x01),占1B,也用于填充,放在选项的开头
3)MSS(最大报文段长度),格式如下:种类(1B,值为2),长度(1B,值为4),数值(2B)
用于在连接开始时确定MSS的大小,如果没有确定,就用默认的(一般实现是536B)
4)窗口扩大因子,格式如下:种类(1B,值为3),长度(1B,值为3),数值(1B)
新窗口值 = 首部窗口值 * 2的(扩大因子)次方
当通信双方认为首部的窗口值还不够大的时候,在连接开始时用这个来定义更大的窗口。仅在连接开始时有效。一经定义,通信过程中无法更改。
5)时间戳(应用测试RTT和防止序号绕回)
6)允许SACK和SACK选项
发送方:我要和你建立链接?
接收方:你真的要和我建立链接么?
发送方:我真的要和你建立链接,成功。
为了防止已失效的连接请求报文突然又传送到了服务端,因而产生错误。客户端发出的连接请求报文并未丢失,而是在某个网络节点长时间滞留了,以致延误到链接释放以后的某个时间才到达 Server 。
一、SYN洪泛攻击
服务器处于SYN_Wait的状态:
1)伪装的IP向服务器发送一个SYN请求建立连接,然后服务器向该IP回复SYN和ACK,但是找不到该IP对应的主机,当超时时服务器收不到ACK会重复发送。当大量的攻击者请求建立连接时,服务器就会存在大量未完成三次握手的连接,服务器主机backlog被耗尽而不能响应其它连接。即SYN泛洪攻击 (属于DOS的一种,发送大量的半连接请求,耗费CPU和内存资源,引起网络堵塞甚至系统瘫痪)
当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击.在Linux下可以如下命令检测是否被Syn攻击
netstat -n -p TCP | grep SYN_RECV
防范措施:
1、降低SYN timeout时间,使得主机尽快释放半连接的占用
2、采用SYN cookie设置,如果短时间内连续收到某个IP的重复SYN请求,则认为受到了该IP的攻击,丢弃来自该IP的后续请求报文
3、在网关处设置过滤,拒绝将一个源IP地址不属于其来源子网的包进行更远的路由
2)当一个主机向服务器发送SYN请求连接,服务器回复ACK和SYN后,攻击者截获ACK和SYN。然后伪装成原始主机继续与服务器进行通信。
二、DOS攻击 拒绝服务攻击
DDoS(分布式拒绝服务攻击)
DOS攻击利用合理的服务请求占用过多的服务资源,使正常用户的请求无法得到相应。
常见的DOS攻击有计算机网络带宽攻击和连通性攻击。
带宽攻击指以极大的通信量冲击网络,使得所有可用网络资源都被消耗殆尽,最后导致合法的用户请求无法通过。
连通性攻击指用大量的连接请求冲击计算机,使得所有可用的操作系统资源都被消耗殆尽,最终计算机无法再处理合法用户的请求。
三、死亡值ping
许多操作系统的TCP/IP协议栈规定ICMP包大小为64KB(网间控制报文),且在对包的标题头进行读取之后,要根据该标题头里包含的信息来为有效载荷生成缓冲区。
”死亡值ping”就是故意产生畸形的测试ping包,声称自己的尺寸超过ICMP上限,也就是加载的尺寸超过64KB上限,使未采取保护措施的网络系统出现内存分配错误,导致TCP/IP协议栈崩溃,最终接收方宕机。
四次挥手,简单来说,就是:
发送方:我要和你断开连接!
接收方:好的,断吧。
接收方:我也要和你断开连接!
发送方:好的,断吧。
TIME_WAIT状态存在有两个原因。
一、可靠终止TCP连接。如果最后一个ACK报文因为网络原因被丢弃,此时server因为没有收到ACK而超时重传FIN报文,处于TIME_WAIT状态的client可以继续对FIN报文做回复,向server发送ACK报文。
二、保证让迟来的TCP报文段有足够的时间被识别和丢弃。连接结束了,网络中的延迟报文也应该被丢弃掉,以免影响立刻建立的新连接。
为什么常说 TCP 有粘包和拆包的问题而不说 UDP ?
由前两节可知,UDP 是基于报文发送的,UDP首部采用了 16bit 来指示 UDP 数据报文的长度,因此在应用层能很好的将不同的数据报文区分开,从而避免粘包和拆包的问题。
而 TCP 是基于字节流的,虽然应用层和 TCP 传输层之间的数据交互是大小不等的数据块,但是 TCP 并没有把这些数据块区分边界,仅仅是一连串没有结构的字节流;另外从 TCP 的帧结构也可以看出,在 TCP 的首部没有表示数据长度的字段,基于上面两点,在使用 TCP 传输数据时,才有粘包或者拆包现象发生的可能。
什么是粘包、拆包?
假设 Client 向 Server 连续发送了两个数据包,用 packet1 和 packet2 来表示,那么服务端收到的数据可以分为三种情况,现列举如下:
第一种情况,接收端正常收到两个数据包,即没有发生拆包和粘包的现象。
第二种情况,接收端只收到一个数据包,但是这一个数据包中包含了发送端发送的两个数据包的信息,这种现象即为粘包。这种情况由于接收端不知道这两个数据包的界限,所以对于接收端来说很难处理。
第三种情况,这种情况有两种表现形式,如下图。接收端收到了两个数据包,但是这两个数据包要么是不完整的,要么就是多出来一块,这种情况即发生了拆包和粘包。这两种情况如果不加特殊处理,对于接收端同样是不好处理的。
为什么会发生 TCP 粘包、拆包?
粘包、拆包解决办法
由于 TCP 本身是面向字节流的,无法理解上层的业务数据,所以在底层是无法保证数据包不被拆分和重组的,这个问题只能通过上层的应用协议栈设计来解决,根据业界的主流协议的解决方案,归纳如下:
窗口是缓存的一部分,用来暂时存放字节流。发送方和接收方各有一个窗口,接收方通过 TCP 报文段中的窗口字段告诉发送方自己的窗口大小,发送方根据这个值和其它信息设置自己的窗口大小。
发送窗口内的字节都允许被发送,接收窗口内的字节都允许被接收。如果发送窗口左部的字节已经发送并且收到了确认,那么就将发送窗口向右滑动一定距离,直到左部第一个字节不是已发送并且已确认的状态;接收窗口的滑动类似,接收窗口左部字节已经发送确认并交付主机,就向右滑动接收窗口。
接收窗口只会对窗口内最后一个按序到达的字节进行确认,例如接收窗口已经收到的字节为 {31, 34, 35},其中 {31} 按序到达,而 {34, 35} 就不是,因此只对字节 31 进行确认。发送方得到一个字节的确认之后,就知道这个字节之前的所有字节都已经被接收。
流量控制是为了控制发送方发送速率,保证接收方来得及接收。
接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据。
实际上,为了避免此问题的产生,发送端主机会时不时的发送一个叫做窗口探测的数据段,此数据段仅包含一个字节来获取最新的窗口大小信息。
UDP(User Data Protocol,用户数据报协议),是与 TCP 相对应的协议。它是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去。
UDP 是无连接的。
UDP 使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态(这里面有许多参数)。
UDP 是面向报文的。
UDP 没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低。
TCP 是面向连接的;UDP 是无连接的。
TCP 是可靠的;UDP 是不可靠的。
TCP 只支持点对点通信;UDP 支持一对一、一对多、多对一、多对多的通信模式。
TCP 是面向字节流的;UDP 是面向报文的。
TCP 有拥塞控制机制;UDP 没有拥塞控制,适合媒体通信。
TCP 首部开销(20 个字节),比 UDP 的首部开销(8 个字节)要大。
用户数据报协议 UDP(User Datagram Protocol)
是无连接的,尽最大可能交付,没有拥塞控制,面向报文(对于应用程序传下来的报文不合并也不拆分,只是添加 UDP 首部),支持一对一、一对多、多对一和多对多的交互通信。
传输控制协议 TCP(Transmission Control Protocol)
是面向连接的,提供可靠交付,有流量控制,拥塞控制,提供全双工通信,面向字节流(把应用层传下来的报文看成字节流,把字节流组织成大小不等的数据块),每一条 TCP 连接只能是点对点的(一对一)。
UDP 首部字段如下:
UDP 首部字段只有 8 个字节,包括源端口、目的端口、长度、检验和。12 字节的伪首部是为了计算检验和临时添加的。
TCP 首部字段如下:
TCP 首部格式比 UDP 复杂。
**序号:**用于对字节流进行编号,例如序号为 301,表示第一个字节的编号为 301,如果携带的数据长度为 100 字节,那么下一个报文段的序号应为 401。
**确认号:**期望收到的下一个报文段的序号。例如 B 正确收到 A 发送来的一个报文段,序号为 501,携带的数据长度为 200 字节,因此 B 期望下一个报文段的序号为 701,B 发送给 A 的确认报文段中确认号就为 701。
**数据偏移:**指的是数据部分距离报文段起始处的偏移量,实际上指的是首部的长度。
**控制位:**八位从左到右分别是 CWR,ECE,URG,ACK,PSH,RST,SYN,FIN。
**CWR:**CWR 标志与后面的 ECE 标志都用于 IP 首部的 ECN 字段,ECE 标志为 1 时,则通知对方已将拥塞窗口缩小;
**ECE:**若其值为 1 则会通知对方,从对方到这边的网络有阻塞。在收到数据包的 IP 首部中 ECN 为 1 时将 TCP 首部中的 ECE 设为 1;
**URG:**该位设为 1,表示包中有需要紧急处理的数据,对于需要紧急处理的数据,与后面的紧急指针有关;
**ACK:**该位设为 1,确认应答的字段有效,TCP规定除了最初建立连接时的 SYN 包之外该位必须设为 1;
**PSH:**该位设为 1,表示需要将收到的数据立刻传给上层应用协议,若设为 0,则先将数据进行缓存;
**RST:**该位设为 1,表示 TCP 连接出现异常必须强制断开连接;
**SYN:**用于建立连接,该位设为 1,表示希望建立连接,并在其序列号的字段进行序列号初值设定;
**FIN:**该位设为 1,表示今后不再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换 FIN 位置为 1 的 TCP 段。
每个主机又对对方的 FIN 包进行确认应答之后可以断开连接。不过,主机收到 FIN 设置为 1 的 TCP 段之后不必马上回复一个 FIN 包,而是可以等到缓冲区中的所有数据都因为已成功发送而被自动删除之后再发 FIN 包;
**窗口:**窗口值作为接收方让发送方设置其发送窗口的依据。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。