文章目录
- (1)说说HTTP常用的状态码及其含义?
- (2)HTTP 常用的请求方式,区别和用途?
- (3)请简单说一下你了解的端口及对应的服务?
- (4)说下计算机网络体系结构?
- ISO七层模型:制定的一个用于计算机或通信系统间互联的标准体系。
- TCP/IP 四层模型
- 五层体系结构
- (5)如何理解HTTP协议的 “无连接,无状态” 特点?
- (6)从浏览器地址栏输入url到显示主页的过程
- (7)如果知道目标服务器的服务端口有没有开启?
- (8)POST和GET有哪些区别?
- (9)在交互过程中如果数据传送完了,还不想断开连接怎么办,怎么维持?
- (10)HTTP 如何实现长连接?在什么时候会超时?
- (11)HTTP 与 HTTPS 的区别
- (12)Https流程是怎样的?
- (13)说说HTTP的状态码,301和302的区别?
- (14)对称加密与非对称加密有什么区别?
- (15)怎么解决SQL注入?
- 如何预防SQL注入问题
- (16)说说DNS的解析过程?
- (17)什么是CSRF攻击,如何避免
- (18)聊聊五层计算机网络体系结构中,每一层对应的网络协议有哪些?
- (19)说说 WebSocket与socket的区别
- (20)为什么说UDP是不可靠的?UDP的优势在哪里?
- (21)说说TCP的重传机制
- (22)Http请求的过程与原理
- (23)forward和redirect的区别?
- (24)说说TCP是如何确保可靠性的呢?
- (25)Session和Cookie的区别?
- (26)IP地址有哪些分类?
- (27)为什么说TCP是可靠的?
- (28)有了IP地址,为什么还要用MAC地址?
- (29)TCP 和 UDP 分别对应的常见应用层协议有哪些?
- 基于TCP的应用层协议有:HTTP、FTP、SMTP、TELNET、SSH
- 基于UDP的应用层协议:DNS、TFTP、SNMP
- (30)如果服务器出现了大量CLOSE_WAIT状态如何解决
- (31)URI和URL的区别
- (32)ICMP协议的功能
- (33)TCP和UDP区别
- (34)请详细介绍一下TCP 的三次握手机制
- (35)TCP握手为什么是三次,为什么不能是两次?不能是四次?
- (36)说说TCP四次挥手过程
- (37)TCP挥手为什么需要四次呢?
- (38)TCP四次挥手过程中,为什么需要等待2MSL,才进入CLOSED关闭状态
- (39)TCP的粘包和拆包
- 所谓粘包拆包问题主要还是因为:
- (40)聊聊TCP的流量控制
(1)说说HTTP常用的状态码及其含义?
状态码 | 含义 |
---|---|
200 | 获取数据成功 |
201 | 创建数据成功、更新数据成功 |
204 | 删除数据成功 |
301 | 永久性重定向,会缓冲 |
302 | 临时性重定向,不会缓冲 |
400 | 客户端请求的语法错误 |
401 | 没有认证成功 |
403 | 认证成功,没有获取到权限 |
404 | 路由错误,请求资源不存在 |
405 | 客户端请求中的方法被禁止 |
406 | 请求格式错误 |
408 | 服务器等待客户端发送的请求时间过长,超时 |
500 | 服务端错误 |
501 | 服务器不具备完成请求的功能。例如,当服务器无法识别请求方法时,服务器可能会返回此代码 |
502 | 错误网关 |
503 | 由于超载或系统维护,服务器暂时的无法处理客户端的请求。通常,这只是一种暂时的状态 |
504 | 服务器作为网关或代理,未及时从上游服务器接收请求 |
505 | 服务器不支持请求中所使用的 HTTP 协议版本 |
(2)HTTP 常用的请求方式,区别和用途?
请求方式 | 用途 |
---|---|
GET | 向服务器端获取资源,包括获取列表数据和详情数据 |
POST | 向服务端发送创建资源的请求 |
PUT | 向服务端发送更新资源的请求 |
DELETE | 向服务端发送删除资源的请求 |
HEAD | 请求页面的首部,获取资源的元信息 |
OPTIONS | 返回所有的可用方法,常用于跨域 |
(3)请简单说一下你了解的端口及对应的服务?
端口 | 服务 |
---|---|
21 | FTP(文件传输协议) |
22 | ssh |
23 | 远程登录服务 |
25 | SMTP(邮件传输协议) |
53 | DNS域名服务器 |
80 | HTTP超文本传输协议 |
110 | POP3邮件协议3 |
443 | HTTPS |
1080 | sockets |
1521 | Oracle数据库默认端口 |
3306 | Mysql服务默认端口 |
(4)说下计算机网络体系结构?
ISO七层模型:制定的一个用于计算机或通信系统间互联的标准体系。
应用层:网络服务与最终用户的一个接口,常见的协议有:HTTP FTP SMTP SNMP DNS.
表示层:数据的表示、安全、压缩。确保一个系统的应用层所发送的信息可以被另一个系统的应用层读取。
会话层:建立、管理、终止会话,对应主机进程,指本地主机与远程主机正在进行的会话.
传输层:定义传输数据的协议端口号,以及流控和差错校验,协议有TCP UDP.
网络层:进行逻辑地址寻址,实现不同网络之间的路径选择,协议有ICMP IGMP IP等.
数据链路层:在物理层提供比特流服务的基础上,建立相邻结点之间的数据链路。
物理层:建立、维护、断开物理连接。
TCP/IP 四层模型
应用层:对应于OSI参考模型的(应用层、表示层、会话层)。
传输层: 对应OSI的传输层,为应用层实体提供端到端的通信功能,保证了数据包的顺序传送及数据的完整性。
网络层:对应于OSI参考模型的网络层,主要解决主机到主机的通信问题。
物理链路层:与OSI参考模型的数据链路层、物理层对应。
五层体系结构
应用层:对应于OSI参考模型的(应用层、表示层、会话层)。
传输层:对应OSI参考模型的的传输层
网络层:对应OSI参考模型的的网络层
数据链路层:对应OSI参考模型的的数据链路层
物理层:对应OSI参考模型的的物理层。
(5)如何理解HTTP协议的 “无连接,无状态” 特点?
无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。即我们给服务器发送 HTTP 请求之后,服务器根据请求,会给我们发送数据过来,但是,发送完,不会记录任何信息。
(6)从浏览器地址栏输入url到显示主页的过程
DNS解析,查找域名对应的IP地址。
与服务器通过三次握手,建立TCP连接
向服务器发送HTTP请求
服务器处理请求,返回网页内容
浏览器解析并渲染页面
TCP四次挥手,连接结束
(7)如果知道目标服务器的服务端口有没有开启?
使用telnet命令可以检查服务器上的端口有没有开启监听,比如telnet 192.168.100.196 7800,如果7800端口没有开启监听,则会提示连接失败。
(8)POST和GET有哪些区别?
POST | GET |
---|---|
向服务端发送请求,用于创建数据 | 向服务端发送请求,用于获取数据 |
安全(请求数据在请求体中) | 不安全(请求数据在URL中拼接) |
传输数据无大小限制 | 传输数据有大小限制 |
服务端获取请求数据用request.data | 服务端获取请求数据用request.GET.get()或者request.query_params.get() |
对应后端的action方法为create | 对应后端的action方法为list或者retrieve |
从请求到获取响应比get慢 | 从请求到获取响应比post快 |
(9)在交互过程中如果数据传送完了,还不想断开连接怎么办,怎么维持?
在 HTTP 中响应体的 Connection 字段指定为 keep-alive
(10)HTTP 如何实现长连接?在什么时候会超时?
通过在头部(请求和响应头)设置 Connection: keep-alive,HTTP1.0协议支持,但是默认关闭,从HTTP1.1协议以后,连接默认都是长连接
1、HTTP 一般会有 httpd 守护进程,里面可以设置 keep-alive timeout,当 tcp 链接闲置超过这个时间就会关闭,也可以在 HTTP 的 header 里面设置超时时间
2、TCP 的 keep-alive 包含三个参数,支持在系统内核的 net.ipv4 里面设置:当 TCP 链接之后,闲置了 tcp_keepalive_time,则会发生侦测包,如果没有收到对方的 ACK,那么会每隔 tcp_keepalive_intvl 再发一次,直到发送了 tcp_keepalive_probes,就会丢弃该链接。
(1)tcp_keepalive_intvl = 15
(2)tcp_keepalive_probes = 5
(3)tcp_keepalive_time = 1800
实际上 HTTP 没有长短链接,只有 TCP 有,TCP 长连接可以复用一个 TCP 链接来发起多次 HTTP 请求,这样可以减少资源消耗,比如一次请求 HTML,可能还需要请求后续的 JS/CSS/图片等
(11)HTTP 与 HTTPS 的区别
HTTP | HTTPS |
---|---|
超文本传输协议,是一个基于TCP/IP通信协议来传递明文数据的协议 | HTTPS 则是具有安全性的 SSL 加密传输协议。 |
端口80 | 端口443 |
HTTP 的连接很简单,是无状态的。不安全 | HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 HTTP 协议安全。 |
资源消耗较少 | 资源消耗较多 |
(12)Https流程是怎样的?
1、客户端向服务端发起建立HTTPS请求。
2、服务器向客户端发送数字证书。
3、客户端验证数字证书,证书验证通过后客户端生成会话密钥(双向验证则此处客户端也会向服务器发送证书)。
4、服务器生成会话密钥(双向验证此处服务端也会对客户端的证书验证)。
5、客户端与服务端开始进行加密会话。
(13)说说HTTP的状态码,301和302的区别?
程序方向来讲这两个状态码,实际上没有多大的区别,都是跳转的返回状态。
但从作用上来讲,301为永久重定向,302为临时重定向
(14)对称加密与非对称加密有什么区别?
对称加密指的就是加密和解密使用同一个秘钥,所以叫做对称加密。
非对称加密指的是:加密和解密使用不同的秘钥,一把作为公开的公钥,另一把作为私钥。
对称加密算法相比非对称加密算法来说,加解密的效率要高得多。但是缺陷在于对于秘钥的管理上,以及在非安全信道中通讯时,密钥交换的安全性不能保障。所以在实际的网络环境中,会将两者混合使用.
(15)怎么解决SQL注入?
SQL注入是一种代码注入技术,一般被应用于攻击web应用程序。它通过在web应用接口传入一些特殊参数字符,来欺骗应用服务器,执行恶意的SQL命令,以达到非法获取系统信息的目的。它目前是黑客对数据库进行攻击的最常用手段之一。
举个常见的业务场景:在web表单搜索框输入员工名字,然后后台查询出对应名字的员工。
这种场景下,一般都是前端页面,把一个名字参数username传到后台,然后后台通过SQL把结果查询出来
# 1、导入mysqlfrom pymysql import *# 2、创建数据库lianjieconn = connect(host='localhost', port=3306, user='root', db='ceshi_platform', charset='utf8')print(conn)# 3、打开游标cur=conn.cursor()# 4、执行sql语句# 让用户输入用户名和密码username=input('请输入用户名:')# 编写sql语句sql="select * from auth_user where username='%s'"%(username)print(sql)# 执行sql语句,返回查询到的记录条数rowcount,如果是rowcount不为0,则登录成功,否则登录失败rowcount = cur.execute(sql)if rowcount!=0:print('登录成功')else:print('登录失败')# 5、关闭游标cur.close()# 6、关闭连接conn.close()
执行结果:
请输入用户名:' or '1=1select * from auth_user where username='' or '1=1'登录成功
如何预防SQL注入问题
对sql语句进行参数化
# 1、导入mysqlfrom pymysql import *# 2、创建数据库lianjieconn = connect(host='localhost', port=3306, user='root', db='ceshi_platform', charset='utf8')print(conn)# 3、打开游标cur=conn.cursor()# 4、执行sql语句# 让用户输入用户名和密码username=input('请输入用户名:')# 编写sql语句sql="select * from auth_user where username=%s"params=(username,)print(sql)# 执行sql语句,返回查询到的记录条数rowcount,如果是rowcount不为0,则登录成功,否则登录失败rowcount = cur.execute(sql,params)if rowcount!=0:print('登录成功')else:print('登录失败')### 5、关闭游标cur.close()# 6、关闭连接conn.close()
执行结果:
请输入用户名:' or '1=1select * from auth_user where username=%s登录失败
(16)说说DNS的解析过程?
(1)操作系统先查本地 hosts文件 中是否有记录,如果有,则直接返回相对应映射的IP地址。
(2)如果本地hosts文件中没有配置,则主机向自己的本地DNS服务器发送查询报文,如果本地DNS服务器缓存中有,将直接返回结果。
(3)如果本地服务器缓存中没有,则从内置在内部的根DNS服务器列表(全球13台,固定的IP地址)中选一个发送查询报文。
(4)根服务器解析域名中的后缀名,告诉本地服务器负责该后缀名的所有顶级服务器列表。
(5)本地服务器选择其中一个顶级域服务器发送查询请求,顶级域服务器拿到域名后继续解析,返回对应域的所有权威服务器列表。
(6)本地服务器再向返回的权威服务器发送查询报文,最终会从某一个权威服务器上得到具体的 IP 地址。
(7)主机返回结果IP。
(17)什么是CSRF攻击,如何避免
CSRF,跨站请求伪造(英文全称是Cross-site request
forgery),是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。
Django预防CSRF攻击的方法是在用户提交的表单中加入一个csrftoken的隐含值,这个值和服务器中保存的csrftoken的值相同,这样做的原理如下:
1、在用户访问django的可信站点时,django反馈给用户的表单中有一个隐含字段csrftoken,这个值是在服务器端随机生成的,每一次提交表单都会生成不同的值
2、当用户提交django的表单时,服务器校验这个表单的csrftoken是否和自己保存的一致,来判断用户的合法性
3、当用户被csrf攻击从其他站点发送精心编制的攻击请求时,由于其他站点不可能知道隐藏的csrftoken字段的信息这样在服务器端就会校验失败,攻击被成功防御
(18)聊聊五层计算机网络体系结构中,每一层对应的网络协议有哪些?
HTTP | HTTPS |
---|---|
应用层 | HTTP(超文本传输协议) FTP(文本传输协议) SMTP(简单的邮件传输协议) DNS(域名系统) SSH(安全外壳协议) DHCP(动态主机配置协议) TELNET(远程登陆协议) |
传输层 | TCP UDP |
网络层 | IP(网际协议) ARP RARP ICMP IGMP OSPF BGF |
数据链路层 | ARQ PPP |
物理层 | 网线 |
(19)说说 WebSocket与socket的区别
Socket是传输控制层协议
websocket是应用层协议
(20)为什么说UDP是不可靠的?UDP的优势在哪里?
UDP是无连接的,在收发数据之前不需要建立连接,直接将数据丢到目标IP和端口上就可以了,不确定对端是否收到了数据,没有TCP中的ACK确认机制,也没有TCP中的丢包重传机制。所以,UDP是不可靠的。但UDP因为没有TCP的ACK确认机制,数据发送的实时性比较好。
(21)说说TCP的重传机制
对于TCP连接,数据发送方将数据发出去后,会启动一个定时器,等待接收端回ACK确认包,如果在指定的时间内没有收到ACK确认包,就会触发TCP的丢包重传机制。如果发送重传包后还是没收到ACK,下一次的重传时间间隔会加倍,当重传次数达到系统上限(Windows默认的上限是5次,Linux默认的上限是15次)后,协议栈就认为网络出故障了,协议栈会直接将对应的连接关闭了。
所以当网络出现故障时有数据交互,协议栈会在数十秒内检测到网路出现异常,就会直接将连接直接关闭掉
(22)Http请求的过程与原理
客户端进行DNS域名解析,得到对应的IP地址
根据这个IP,找到对应的服务器建立连接(三次握手)
建立TCP连接后发起HTTP请求(一个完整的http请求报文)
服务器响应HTTP请求,客户端得到html代码
客户端解析html代码,用html代码中的资源(如js,css,图片等等)渲染页面。
服务器关闭TCP连接(四次挥手)
(23)forward和redirect的区别?
直接转发方式(Forward) :客户端和浏览器只发出一次请求,Servlet、HTML、JSP或其它信息资源,由第二个信息资源响应该请求,在请求对象request中,保存的对象对于每个信息资源是共享的。
间接转发方式(Redirect) :实际是两次HTTP请求,服务器端在响应第一次请求的时候,让浏览器再向另外一个URL发出请求,从而达到转发的目的。
(24)说说TCP是如何确保可靠性的呢?
首先,TCP的连接是基于三次握手,而断开则是基于四次挥手。确保连接和断开的可靠性。
其次,TCP的可靠性,还体现在有状态;TCP会记录哪些数据发送了,哪些数据被接收了,哪些没有被接受,并且保证数据包按序到达,保证数据传输不出差错。
再次,TCP的可靠性,还体现在可控制。它有数据包校验、ACK应答、超时重传(发送方)、失序数据重传(接收方)、丢弃重复数据、流量控制(滑动窗口)和拥塞控制等机制。
(25)Session和Cookie的区别?
Cookie是保存在客户端的一小块文本串的数据。客户端向服务器发起请求时,服务端会向客户端发送一个Cookie,客户端就把Cookie保存起来。在客户端下次向同一服务器再发起请求时,Cookie被携带发送到服务器。服务器就是根据这个Cookie来确认身份的。
session指的就是服务器和客户端一次会话的过程。Session利用Cookie进行信息处理的,当用户首先进行了请求后,服务端就在用户浏览器上创建了一个Cookie,当这个Session结束时,其实就是意味着这个Cookie就过期了。Session对象存储着特定用户会话所需的属性及配置信息。
用户第一次请求服务器时,服务器根据用户提交的信息,创建对应的Session,请求返回时将此Session的唯一标识信息SessionID返回给浏览器,浏览器接收到服务器返回的SessionID信息后,会将此信息存入Cookie中,同时Cookie记录此SessionID是属于哪个域名。
当用户第二次访问服务器时,请求会自动判断此域名下是否存在Cookie信息,如果存在,则自动将Cookie信息也发送给服务端,服务端会从Cookie中获取SessionID,再根据 SessionID查找对应的 Session信息,如果没有找到,说明用户没有登录或者登录失效,如果找到Session证明用户已经登录可执行后面操作。
(26)IP地址有哪些分类?
一般可以这么认为,IP地址=网络号+主机号。
网络号:它标志主机所连接的网络地址表示属于互联网的哪一个网络。
主机号:它标志主机地址表示其属于该网络中的哪一台主机。
IP地址分为A,B,C,D,E五大类:
A类地址(1~126):以0开头,网络号占前8位,主机号占后面24位。
B类地址(128~191):以10开头,网络号占前16位,主机号占后面16位。
C类地址(192~223):以110开头,网络号占前24位,主机号占后面8位。
D类地址(224~239):以1110开头,保留位多播地址。
E类地址(240~255):以11110开头,保留位为将来使用
(27)为什么说TCP是可靠的?
TCP是基于连接的,在进行数据通信之前需要先通过三次握手建立TCP连接,TCP连接建立后才能收发数据。在收发数据时有个ACK确认机制,数据发送方在将数据发出后,需要等待对方的ACK包回应,收到ACK包才表示对方收到数据了,才会接着发下一包。
如果在指定的时间内没有收到对方的回应,则会触发丢包重传。正是三次握手、ACK确认、丢包重传等机制的存在,保证了TCP的可靠性。
(28)有了IP地址,为什么还要用MAC地址?
简而言之,标识网络中的一台计算机,比较常用的就是IP地址和MAC地址,但计算机的IP地址可由用户自行更改,管理起来就相对困难,而MAC地址不可更改,所以一般会把IP地址和MAC地址组合起来使用。
那只使用MAC地址不用IP地址行不行呢?不行的!因为最早就是MAC地址先出现的,并且当时并不用IP地址,只用MAC地址,后来随着网络中的设备越来越多,整个路由过程越来越复杂,便出现了子网的概念。对于目的地址在其他子网的数据包,路由只需要将数据包送到那个子网即可。
那为什么要用IP地址呢?是因为IP地址是和地域相关的,对于同一个子网上的设备,IP地址的前缀都是一样的,这样路由器通过IP地址的前缀就知道设备在在哪个子网上了,而只用MAC地址的话,路由器则需要记住每个MAC地址在哪个子网,这需要路由器有极大的存储空间,是无法实现的。
IP地址可以比作为地址,MAC地址为收件人,在一次通信过程中,两者是缺一不可的。
(29)TCP 和 UDP 分别对应的常见应用层协议有哪些?
基于TCP的应用层协议有:HTTP、FTP、SMTP、TELNET、SSH
HTTP:HyperText Transfer Protocol(超文本传输协议),默认端口80
FTP: File Transfer Protocol (文件传输协议), 默认端口(20用于传输数据,21用于传输控制信息)
SMTP: Simple Mail Transfer Protocol (简单邮件传输协议) ,默认端口25
TELNET: Teletype over the Network (网络电传), 默认端口23
SSH:Secure Shell(安全外壳协议),默认端口 22
基于UDP的应用层协议:DNS、TFTP、SNMP
DNS : Domain Name Service (域名服务),默认端口 53
TFTP: Trivial File Transfer Protocol (简单文件传输协议),默认端口69
SNMP:Simple Network Management Protocol(简单网络管理协议),通过UDP端口161接收,只有-Trap信息采用UDP端口162。
(30)如果服务器出现了大量CLOSE_WAIT状态如何解决
服务器端收到客户端发送的FIN后,TCP协议栈就会自动发送ACK,接着进入CLOSE_WAIT状态。
但是如果服务器端不执行socket的close()操作,那么就没法进入LAST_ACK,导致大量连接处于CLOSE_WAIT状态
所以,如果服务器出现了大量CLOSE_WAIT状态,一般是程序Bug,或者关闭socket不及时。
(31)URI和URL的区别
URI,全称是Uniform Resource Identifier),中文翻译是统一资源标志符,主要作用是唯一标识一个资源。
URL,全称是Uniform Resource Location),中文翻译是统一资源定位符,主要作用是提供资源的路径。打个经典比喻吧,URI像是身份证,可以唯一标识一个人,而URL更像一个住址,可以通过URL找到这个人。
(32)ICMP协议的功能
ICMP协议是一种面向无连接的协议,用于传输出错报告控制信息。
它是一个非常重要的协议,它对于网络安全具有极其重要的意义。它属于网络层协议,主要用于在主机与路由器之间传递控制信息,包括报告错误、交换受限控制和状态信息等。
当遇到IP数据无法访问目标、IP路由器无法按当前的传输速率转发数据包等情况时,会自动发送ICMP消息。
比如我们日常使用得比较多的ping,就是基于ICMP的。
(33)TCP和UDP区别
TCP | UDP |
---|---|
面向字节流 | 面向报文 |
面向连接 | 面向无连接 |
只能一对一 | 支持一对多 多对多 多对一交互通信 |
首部最小20字节,最大60字节 | 首部开销小,仅8字节 |
数据传输可靠,具有丢包重传,流量控制和拥塞阻塞 | 数据传输不可靠,会出现丢包,不使用流量控制和拥塞控制 |
使用于要求可靠传输的应用 | 适用于实时应用(IP电话,直播,视频会议) |
(34)请详细介绍一下TCP 的三次握手机制
三次握手(Three-way Handshake)其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。
第一次握手:保证了服务端可以接收到信息、客户端可以发送消息
第二次握手:保证了客户端知道服务端可以发送、接受消息,服务端知道客户端可以发送信息
第三次握手:保证了服务端知道客户端可以接收消息
(35)TCP握手为什么是三次,为什么不能是两次?不能是四次?
前两次握手客户端可以确认服务端的接收和发送是正常的(一个来回),但是服务端却不知道客户端的发送能力是否正常,那 TCP 的可靠性就无从谈起,所以需要第三次握手来确认双方的收发能力,以确保TCP连接的可靠性。
(36)说说TCP四次挥手过程
第一次挥手:客户端发送FIN标识到服务端,告知服务端我要释放连接
第二次挥手:服务端收到FIN标识,知道了客户端想断开连接,于是马上检查是否还有数据发送给客户端,如果还有数据没有发送,就发送ACK标识告诉客户端:等一会,你还有数据在我这里
第三次挥手:待所有数据发送完毕后,服务端发送FIN标识给客户端,告诉客户端,现在已经没有数据了,我要关闭连接啦
第四次挥手:客户端收到服务端的FIN标识,知道服务端现在就要关闭连接了,于是就发送ACK标识,告知服务端:我知道啦,你关吧
于是服务器关闭,客户端也关闭了
(37)TCP挥手为什么需要四次呢?
首先第四次挥手和第三次握手有异曲同工之妙,最终握手和挥手的目的都是让服务端知道,你发过来的报文我已经收到了。你的(服务端)发送功能没有出现故障。
如果没有第四次挥手,我们假设当服务端第二次发送报文之后,可以直接断开连接。若直接断开连接,由于某些原因,客户端可能并没有收到服务端发来的第二次报文,但是服务端自己认为客户端已经收到了,那么就有可能导致服务端在第一次和第二次发送报文的过程中,遗留的待传数据不完整。
因此第四次挥手是确保服务端—->客户端之间的传输是没有问题的。是一个必要的过程
(38)TCP四次挥手过程中,为什么需要等待2MSL,才进入CLOSED关闭状态
四次挥手中的2MSL的时间是从客户端接收到 FIN 后发送 ACK 开始计时的。如果在 TIME-WAIT 时间内,因为客户端的 ACK 没有传输到服务端,客户端又接收到了服务端重发的 FIN 报文,那么 2MSL 时间将重新计时。
比如如果服务端没有收到断开连接的最后的 ACK 报文,就会触发超时重发 FIN 报文,客户端接收到 FIN 后,会重发 ACK 给服务端, 一来一去正好 2 个 MSL。
(39)TCP的粘包和拆包
所谓粘包拆包问题主要还是因为:
1、接收方不知道消息之间的界限,不知道一个消息要提取多少字节的数据所造成的。 (服务器端出现黏包)
2、tcp在发送数据少且间隔时间短的数据时,会将几条和并一起发送。(客户端出现黏包)
目前比较合理的处理方法是:为字节流加上一个报头,告诉发送的字节流总大小,然后接收端来一个死循环接收完所有数据。用struck将序列化后的数据长度打包成4个字节(4个字节完全够用)。
使用struct模块可以用于将Python的值根据格式符,转换为C语言的结构(byte类型),便于数据流传输。
(40)聊聊TCP的流量控制
TCP 提供一种机制可以让发送端根据接收端的实际接收能力控制发送的数据量,这就是流量控制。
但是发送端不能疯狂地向接收端发送数据,因为接收端接收不过来的话,接收方只能把处理不过来的数据存在缓存区里。如果缓存区都满了,发送方还在疯狂发送数据的话,接收方只能把收到的数据包丢掉,这就浪费了网络资源。
TCP通过滑动窗口来控制流量,我们看下流量控制的简要流程吧:
首先双方三次握手,初始化各自的窗口大小,均为 400 个字节。
1.假如当前发送方给接收方发送了200个字节,那么,发送方的SND.NXT会右移200个字节,也就是说当前的可用窗口减少了200 个字节。
2.接受方收到后,放到缓冲队列里面,REV.WND =400-200=200字节,所以win=200字节返回给发送方。接收方会在 ACK 的报文首部带上缩小后的滑动窗口200字节
3.发送方又发送200字节过来,200字节到达,继续放到缓冲队列。不过这时候,由于大量负载的原因,接受方处理不了这么多字节,只能处理100字节,剩余的100字节继续放到缓冲队列。这时候,REV.WND = 400-200-100=100字节,即win=100返回发送方。
4.发送方继续干活,发送100字节过来,这时候,接受窗口win变为0。
5.发送方停止发送,开启一个定时任务,每隔一段时间,就去询问接受方,直到win大于0,才继续开始发送。