TCP/IP的三次握手以及四次挥手
TCP/IP的三次握手以及四次挥手
TCP:传输控制协议、面向连接网络协议
优点:数据传输可靠性高
缺点:数据通讯效率低
应用:文件传输 邮件传输 网站页面数据传输
举例:
A主机 向 B主机 传输数据
B主机收到后会有一个确认机制,会向A主机进行回复确认
UDP :用户报文协议 无;连接网络协议
优点:数据通讯效率高 没有确认机制
缺点:数据安全性无法保证
应用:DNS解析服务 视频数据传输 语音数据传输
举例:
A主机向B主机发送数据包,A主机不会管B主机有没有收到。
TCP三次握手过程
TCP报文结构:如何包装和封装数据
控制字段:对网络通讯有控制管理作用 0关闭 1开启
syn:请求建立连接字段
fin:请求断开连接字段
ack:传输的数据确认控制字段
端口号:22(ssh) 23(telnet) 20(FTP) 21(FTP) 80(网站) 25 111 873 3306(数据库) 3389
端口号范围:1~65535(tcp udp都不使用0号端口)
总结:
第一次握手:
发送请求连接控制字段syn , 请求建立连接 (客户端 --- 服务端)
根据数据包编号发送数据 seq=x
第二次握手:
发送确认控制字段ack 和 请求连接控制字段 syn (服务端 --- 客户端)
根据数据包编号进行确认 ack=x+1
根据数据包编号发送数据 seq=y
第三次握手:
发送确认控制字段ack (客户端 --- 服务端)
根据数据包编号进行确认 ack=y+1
根据数据包编号发送数据 seq=x+1
syn位:请求建立连接字段
fin位:请求断开连接字段
ack位:传输的数据确认控制字段
为了保证将大的数据进行分割后的传输
seq号 序列号:数据编号 便于重组数据
ack 确号 认号:确认下一次发送数据包编号
控制字段:对网络通讯有控制管理作用 0关闭 1开启
(A)不要将确认序号Ack与标志位中的ACK搞混了。
(B)确认方Ack=发起方seq+1,两端配对。
建立连接以后 传输数据时就一直带着控制字段了,ack=1
序列号:数据编号 便于重组数据
确认号:确认下一次发送数据包编号
TCP四次挥手过程
总结:
第一次挥手:
发送请求断开控制字段fin 和 确认控制字段 (客户端 --- 服务端)
第二次挥手:
发送确认控制字段ack (服务端 --- 客户端)
第三次挥手:
发送请求断开控制字段fin 和 确认控制字段 (服务端 --- 客户端)
第四次握手:
发送确认控制字段ack (客户端 --- 服务端)
提问:为什么TCP握手是三次,挥手是四次?
解答:因为挥手时需要数据传输确认阶段
有没有可能三次挥手?
有可能,是因为省略了第二次挥手
抓取三次握手的包:
抓取四次挥手的包:
抓取三次挥手数据包:
TCP/IP模型和OSI7层模型的对比
TCP十一种状态集
应用:高并发网络场景时,linux系统中的网络优化
十一种状态集说明:
三次握手 (五种状态)
客户端初始状态:closed
服务端初始状态:closed---listen
第一次握手:发送syn信息 客户端----服务端
客户端 closed --- syn_sent
第二次握手 发送syn ack信息 服务端---客户端
服务端状态: listen---syn_rcvd
第三次握手:发送ack信息 客户端--服务端
客户端状态:syn_sent ---- established
服务端状态 syn_rcvd --- established
四次挥手(六种状态)
客户端初始化状态:established
服务端初始化状态:established
正常情况:
第一次挥手:发送fin ack 信息 客户端---服务端
客户端:fin_wait1
第二次挥手:发送ack信息 服务端---客户端
服务端状态:established ---- close_wait
客户端状态:fin_wait1 --- fin_wait2
第三次挥手:发送fin ack信息 服务端---客户端
服务端状态:close_wait --- last_ack
第四次挥手:发送ack信息 客户端---服务端
客户端状态:fin_wait2 -- time_wait
服务端状态:last_ack ---closed
特殊情况:
第一次挥手: 发送fin ack信息 客户端 --- 服务端
客户端状态:established ---> fin_wait1
第二次挥手:发送fin ack信息 服务端 --- 客户端
客户端状态:fin_wait1 ---> closing
服务端状态:close_wait ---> last_ack
第四次挥手:发送ack信息 客户端 --- 服务端
客户端状态:closing ---> time_wait ---> closed
服务端状态:last_ack ---> closed
LISTEN - 侦听来自远方TCP端口的连接请求;
SYN-SENT -在发送连接请求后等待匹配的连接请求;
SYN-RECEIVED - 在收到和发送一个连接请求后等待对连接请求的确认;
ESTABLISHED- 代表一个打开的连接,数据可以传送给用户;
FIN-WAIT-1 - 等待远程TCP的连接中断请求,或先前的连接中断请求的确认;
FIN-WAIT-2 - 从远程TCP等待连接中断请求;
CLOSE-WAIT - 等待从本地用户发来的连接中断请求;
CLOSING -等待远程TCP对连接中断的确认;
LAST-ACK - 等待原来发向远程TCP的连接中断请求的确认;
TIME-WAIT -等待足够的时间以确保远程TCP接收到连接中断请求的确认;
CLOSED - 没有任何连接状态;
每一个应用层(TCP/IP参考模型的最高层)协议一般都会使用到两个传输层协议之一:
运行在TCP协议
上的协议:
HTTP(Hypertext Transfer Protocol,超文本传输协议)
,主要用于普通浏览。
HTTPS(HTTP over SSL,安全超文本传输协议),HTTP
协议的安全版本。
FTP(File Transfer Protocol,文件传输协议)
,用于文件传输。
POP3(Post Office Protocol, version 3,邮局协议)
,收邮件用。
SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)
,用来发送电子邮件。
TELNET(Teletype over the Network,网络电传)
,通过一个终端(terminal)
登陆到网络。
SSH(Secure Shell,用于替代安全性差的TELNET),
用于加密安全登陆用。
运行在UDP协议
上的协议:
BOOTP(Boot Protocol,启动协议)
,应用于无盘设备。
NTP(Network Time Protocol,网络时间协议
),用于网络同步。
DHCP(Dynamic Host Configuration Protocol,动态主机配置协议)
,动态配置IP地址。
运行在TCP
和UDP
协议上:
DNS(Domain Name Service,域名服务)
,用于完成地址查找,邮件转发等工作。
常见面试题
为什么TCP连接的时候是3次?2次不可以吗?
因为需要考虑连接时丢包的问题,如果只握手2次,第二次握手时如果服务端发给客户端的确认报文段丢失,此时服务端已经准备好了收发数(可以理解服务端已经连接成功)据,而客户端一直没收到服务端的确认报文,所以客户端就不知道服务端是否已经准备好了(可以理解为客户端未连接成功),这种情况下客户端不会给服务端发数据,也会忽略服务端发过来的数据。
如果是三次握手,即便发生丢包也不会有问题,比如如果第三次握手客户端发的确认ack报文丢失,服务端在一段时间内没有收到确认ack报文的话就会重新进行第二次握手,也就是服务端会重发SYN报文段,客户端收到重发的报文段后会再次给服务端发送确认ack报文。
为什么TCP连接的时候是3次,关闭的时候却是4次?
因为只有在客户端和服务端都没有数据要发送的时候才能断开TCP。而客户端发出FIN报文时只能保证客户端没有数据发了,服务端还有没有数据发客户端是不知道的。而服务端收到客户端的FIN报文后只能先回复客户端一个确认报文来告诉客户端我服务端已经收到你的FIN报文了,但我服务端还有一些数据没发完,等这些数据发完了服务端才能给客户端发FIN报文(所以不能一次性将确认报文和FIN报文发给客户端,就是这里多出来了一次)。
为什么客户端发出第四次挥手的确认报文后要等2MSL的时间才能释放TCP连接?
这里同样是要考虑丢包的问题,如果第四次挥手的报文丢失,服务端没收到确认ack报文就会重发第三次挥手的报文,这样报文一去一回最长时间就是2MSL,所以需要等这么长时间来确认服务端确实已经收到了。
如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP设有一个保活计时器,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
什么是HTTP,HTTP 与 HTTPS 的区别
HTTP 是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范
常用HTTP状态码
HTTP状态码表示客户端HTTP请求的返回结果、标识服务器处理是否正常、表明请求出现的错误等。
状态码的类别:
常用HTTP状态码
GET和POST区别
说道GET和POST,就不得不提HTTP协议,因为浏览器和服务器的交互是通过HTTP协议执行的,而GET和POST也是HTTP协议中的两种方法。
HTTP全称为Hyper Text Transfer Protocol,中文翻译为超文本传输协议,目的是保证浏览器与服务器之间的通信。HTTP的工作方式是客户端与服务器之间的请求-应答协议。
HTTP协议中定义了浏览器和服务器进行交互的不同方法,基本方法有4种,分别是GET,POST,PUT,DELETE。这四种方法可以理解为,对服务器资源的查,改,增,删。
GET:从服务器上获取数据,也就是所谓的查,仅仅是获取服务器资源,不进行修改。
POST:向服务器提交数据,这就涉及到了数据的更新,也就是更改服务器的数据。
PUT:英文含义是放置,也就是向服务器新添加数据,就是所谓的增。
DELETE:从字面意思也能看出,这种方式就是删除服务器数据的过程。
GET和POST区别
1.Get是不安全的,因为在传输过程,数据被放在请求的URL中;Post的所有操作对用户来说都是不可见的。 但是这种做法也不时绝对的,大部分人的做法也是按照上面的说法来的,但是也可以在get请求加上 request body,给 post请求带上 URL 参数。
2.Get请求提交的url中的数据最多只能是2048字节,这个限制是浏览器或者服务器给添加的,http协议并没有对url长度进行限制,目的是为了保证服务器和浏览器能够正常运行,防止有人恶意发送请求。Post请求则没有大小限制。
3.Get限制Form表单的数据集的值必须为ASCII字符;而Post支持整个ISO10646字符集。
4.Get执行效率却比Post方法好。Get是form提交的默认方法。
5.GET产生一个TCP数据包;POST产生两个TCP数据包。
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
什么是对称加密与非对称加密
对称密钥加密是指加密和解密使用同一个密钥的方式,这种方式存在的最大问题就是密钥发送问题,即如何安全地将密钥发给对方;
而非对称加密是指使用一对非对称密钥,即公钥和私钥,公钥可以随意发布,但私钥只有自己知道。发送密文的一方使用对方的公钥进行加密处理,对方接收到加密信息后,使用自己的私钥进行解密。
由于非对称加密的方式不需要发送用来解密的私钥,所以可以保证安全性;但是和对称加密比起来,非常的慢
什么是HTTP2
HTTP2 可以提高了网页的性能。
在 HTTP1 中浏览器限制了同一个域名下的请求数量(Chrome 下一般是六个),当在请求很多资源的时候,由于队头阻塞当浏览器达到最大请求数量时,剩余的资源需等待当前的六个请求完成后才能发起请求。
HTTP2 中引入了多路复用的技术,这个技术可以只通过一个 TCP 连接就可以传输所有的请求数据。多路复用可以绕过浏览器限制同一个域名下的请求数量的问题,进而提高了网页的性能。
Session、Cookie和Token的主要区别
HTTP协议本身是无状态的。什么是无状态呢,即服务器无法判断用户身份。
什么是cookie
cookie是由Web服务器保存在用户浏览器上的小文件(key-value格式),包含用户相关的信息。客户端向服务器发起请求,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户身份。
什么是session
session是依赖Cookie实现的。session是服务器端对象
session 是浏览器和服务器会话过程中,服务器分配的一块储存空间。服务器默认为浏览器在cookie中设置 sessionid,浏览器在向服务器请求过程中传输 cookie 包含 sessionid ,服务器根据 sessionid 获取出会话中存储的信息,然后确定会话的身份信息。
cookie与session区别
存储位置与安全性:cookie数据存放在客户端上,安全性较差,session数据放在服务器上,安全性相对更高;
存储空间:单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie,session无此限制
占用服务器资源:session一定时间内保存在服务器上,当访问增多,占用服务器性能,考虑到服务器性能方面,应当使用cookie。
什么是Token
Token的引入:Token是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,Token便应运而生。
Token的定义:Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。
使用Token的目的:Token的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。
Token 是在服务端产生的。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端。前端可以在每次请求的时候带上 Token 证明自己的合法地位
session与token区别
session机制存在服务器压力增大,CSRF跨站伪造请求攻击,扩展性不强等问题;
session存储在服务器端,token存储在客户端
token提供认证和授权功能,作为身份认证,token安全性比session好;
session这种会话存储方式方式只适用于客户端代码和服务端代码运行在同一台服务器上,token适用于项目级的前后端分离(前后端代码运行在不同的服务器下)
Servlet是线程安全的吗
Servlet不是线程安全的,多线程并发的读写会导致数据不同步的问题。
解决的办法是尽量不要定义name属性,而是要把name变量分别定义在doGet()和doPost()方法内。虽然使用synchronized(name){}语句块可以解决问题,但是会造成线程的等待,不是很科学的办法。
注意:多线程的并发的读写Servlet类属性会导致数据不同步。但是如果只是并发地读取属性而不写入,则不存在数据不同步的问题。因此Servlet里的只读属性最好定义为final类型的。
Servlet接口中有哪些方法及Servlet生命周期探秘
在Java Web程序中,Servlet
主要负责接收用户请求HttpServletRequest
,在doGet()
,doPost()
中做相应的处理,并将回应HttpServletResponse反馈给用户。Servlet可以设置初始化参数,供Servlet内部使用。
ervlet接口定义了5个方法,其中前三个方法与Servlet生命周期相关:
void init(ServletConfig config) throws ServletException
void service(ServletRequest req, ServletResponse resp) throws ServletException, java.io.IOException
void destory()
java.lang.String getServletInfo()
ServletConfig getServletConfig()
生命周期
Web容器加载Servlet并将其实例化后,Servlet生命周期开始,容器运行其init()方法进行Servlet的初始化;
请求到达时调用Servlet的service()方法,service()方法会根据需要调用与请求对应的doGet或doPost等方法;
当服务器关闭或项目被卸载时服务器会将Servlet实例销毁,此时会调用Servlet的destroy()方法。
init方法和destory方法只会执行一次,service方法客户端每次请求Servlet都会执行。Servlet中有时会用到一些需要初始化与销毁的资源,因此可以把初始化资源的代码放入init方法中,销毁资源的代码放入destroy方法中,这样就不需要每次处理客户端的请求都要初始化与销毁资源。
如果客户端禁止 cookie 能实现 session 还能用吗?
Cookie 与 Session,一般认为是两个独立的东西,Session采用的是在服务器端保持状态的方案,而Cookie采用的是在客户端保持状态的方案。
但为什么禁用Cookie就不能得到Session呢?因为Session是用Session ID来确定当前对话所对应的服务器Session,而Session ID是通过Cookie来传递的,禁用Cookie相当于失去了Session ID,也就得不到Session了。
假定用户关闭Cookie的情况下使用Session,其实现途径有以下几种:
手动通过URL传值、隐藏表单传递Session ID。
用文件、数据库等形式保存Session ID,在跨页过程中手动调用。