七层OSI模型
1.1 每层的作用
从下往上的顺序:
物理层 : 相当于网线 wifi 统一的规范, 比如网线接口型号等 虽然链路层的作用是将帧从一个端系统运输到另一个端系统,而物理层的作用是将帧中的一个个 比特
从一个节点运输到另一个节点,物理层的协议仍然使用链路层协议,这些协议与实际的物理传输介质有关,例如,以太网有很多物理层协议:关于双绞铜线、关于同轴电缆、关于光纤等等。
数据链路层: 定义如何格式化数据以便传输( 光纤用光信号 ), / 及如何控制对网络的访问 / 支持错误检测
网络层: 路由(通过本ip和目标ip规划出合适的路)和寻址(寻找ip地址) 路由数据包 / 选择传递数据的最佳路径 / 支持逻辑寻址和路径选择
像是提供了一张地图一样
传输层: 保证了端到端之间的通信
确保数据传输的可靠性 / 建立维护和终止虚拟电路
通过错误检测和恢复
信息流控制来保证可靠性
会话层: 保证主机间通信 : 建立, 管理, 终止程序间的会话 (如QQ/ VX)
表示层: 格式化数据 ( 加密等 ) , 协商用于应用层的数据传输语法
应用层: 为应用进程提供网络服务( 如: 电子邮件 / 文件传输 / 终端仿真 ) / 提供用户身份验证
数据封装流程
A发送消息, 在表示层加密并封装
(会话层)建立程序之间的连接
(传输层)建立端到端的连接 A和B的IP建立连接 加入传输层的头部
(网络层)找到一条路 传输信息 加入网络层头部(包含B的IP信息)
(数据链路层) 找到B的大概位置后, 找到B的mac地址 封装数据链路层头部( 包含B的具体位置 还有FCS校验, 容错校验 )
(物理层) 将封装好的一系列头部转化成二进制 通过网线传播
五层模型
应用层
应用层的任务是通过应用进程间的交互来完成特定网络应用。应用层协议定义的是应用进程间通讯和交互的规则。应用层交互的数据单元称为报文。
运输层
运输层的任务就是负责向两台主机中进程之间的通讯提供通用的数据传输服务。
- 传输控制协议TCP–提供面向连接的、可靠的数据传输服务、其数据传输的单位是报文段。
- 用户数据报协议UDP–提供无连接的、尽最大努力的数据传输服务(不保证数据传输的可靠性),其数据传输的单位是用户数据报。
网络层
网络层负责为分组交换网上的不同主机提供通讯服务。在发送数据时,网络层把运输层产生的报文段或者用户数据报封装成分组或包进行传送。分组也叫IP数据报。
网络层的另一个任务就是要选择合适的路由,使源主机运输层所传下来的分组,能够通过网络中的路由找到目的主机。
数据链路层
数据链路层常简称为链路层。我们知道,两台主机之间的数据传输,总是在一段一段的链路上传送的,这就需要使用专门的链路层协议。在两个相邻节点之间传送数据时,数据链路层将网络层交下来的IP数据报组装成帧,在两个相邻节点上传送帧。每一帧包括数据和必要的控制信息(如同步信息、地址信息、差错检测等)。
在接受数据时,控制信息使接收端能够知道一个帧从哪个比特开始和到哪个比特结束。这样,数据链路层在收到一个帧以后,就可从中提取出数据部分,上交给网络层。
控制信息还使接收端能够进行差错检测,如果出错那么直接丢弃这个帧。
物理层
在物理层上所传数据的单位是比特。传递信息所利用的物理媒体并不在物理层,而是在物理层下面。
ARP协议
地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议。
将ip地址解析成mac地址的协议
ARP原理
根据目标Ip地址借助ARP请求和ARP响应来确定目标的MAC地址原理:通过广播发送ARP请求,Ip地址一致的主机接收该请求,然后将自己的MAC地址加入的ARP响应包返回给源主机。要进行MAC地址缓存来避免占用网络流量
每个主机都会在自己的ARP缓冲区建立一个ARP列表,表示Ip地址和MAC地址的对应关系当源主机要发送数据时,首先检查ARP列表中是否有对应Ip地址的目标主机的MAC地址,若有,则直接发送,若无,则向本网段的所有主机发送ARP数据包,该数据包包括的内容有:源Ip地址,源MAC地址,目标主机Ip地址当本网络的所有主机收到该ARP数据包时,首先检查书包中的Ip地址是否是自己的Ip地址,若不是则丢弃,若是,则首先从数据包中取出源主机的IP和MAC地址写入自己的ARP列表中,若已存在,则覆盖;然后将自己的MAC地址写入ARP响应包中,告诉源主机自己的MAC地址源主机收到ARP响应包后,将目标主机的IP和MAC地址写入ARP列表中。若源主机一直没有收到ARP响应,则ARP查询失败(广播发送ARP请求,单播发送ARP响应) 此时,自己可以加上ARP攻击及免费ARP相关知识点(可自行搜索)
RARP协议
RARP以与ARP相反的方式工作。RARP发出要反向解析的物理地址并希望返回其对应的IP地址,应答包括由能够提供所需信息的RARP服务器发出的IP地址。
ATA协议
ATA协议定义了ATA主机控制器与ATA存储设备之间的接口标准
MAC地址
MAC地址也叫物理地址、硬件地址,由网络设备制造商生产时烧录在网卡(Network lnterface Card)的EPROM(一种闪存芯片,通常可以通过程序擦写)。IP地址与MAC地址在计算机里都是以二进制表示的,IP地址是32位的,而MAC地址则是48位的 [3] 。
HTTP协议
超文本传输协议 HTTP协议是建立在TCP协议之上的一种协议 位于应用层 规定了浏览器和服务器之间的信息传递规则,
HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此,HTTP协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。
HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。
因此HTTP连接是一种“短连接”
HTTP协议是无状态的协议。协议对于事务处理没有记忆能力,对同一个url请求没有上下文关系 这意味着每个请求都是独立的 服务器无法从连接上跟踪会话。所以cookie应运而生。
要保持客户端程序的在线状态,需要不断地向服务器发起连接请求。通常的 做法是即时不需要获得任何数据,客户端也保持每隔一段固定的时间向服务器发送一次“保持连接”的请求,服务器在收到该请求后对客户端进行回复,表明知道客户端“在线”。
若服务器长时间无法收到客户端的请求,则认为客户端“下线”
若客户端长时间无法收到服务器的回复,则认为网络已经断开
超文本传输协议可以进行文字分割:超文本(Hypertext)、传输(Transfer)、协议(Protocol)
什么是超文本
而随着互联网的高速发展,两台电脑之间能够进行数据的传输后,人们不满足只能在两台电脑之间传输文字,还想要传输图片、音频、视频,甚至点击文字或图片能够进行超链接
的跳转,那么文本的语义就被扩大了,这种语义扩大后的文本就被称为超文本(Hypertext)
。
什么是传输
那么我们上面说到,两台计算机之间会形成互联关系进行通信,我们存储的超文本会被解析成为二进制数据包,由传输载体(例如同轴电缆,电话线,光缆)负责把二进制数据包由计算机终端传输到另一个终端的过程称为传输(transfer)。
什么是协议
网络协议就是网络中(包括互联网)传递、管理信息的一些规范。如同人与人之间相互交流是需要遵循一定的规矩一样,计算机之间的相互通信需要共同遵守一定的规则,这些规则就称为网络协议。
那么我们就可以总结一下,什么是 HTTP?可以用下面这个经典的总结回答一下: HTTP 是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范
HTTP1.0 , 1.1和2.0区别和联系
HTTP1.0和HTTP1.1的区别
长连接(Persistent Connection)
HTTP1.1支持长连接和请求的流水线处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启长连接keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。HTTP1.0需要使用keep-alive参数来告知服务器端要建立一个长连接。
节约带宽
HTTP1.0中存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能。**HTTP1.1支持只发送header信息(**不带任何body信息),如果服务器认为客户端有权限请求服务器,则返回100,客户端接收到100才开始把请求body发送到服务器;如果返回401,客户端就可以不用发送请求body了节约了带宽。
HOST域
在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname),HTTP1.0没有host域。随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都支持host域,且请求消息中如果没有host域会报告一个错误(400 Bad Request)。
缓存处理
在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。
错误通知的管理
在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
HTTP1.1和HTTP2.0的区别
多路复用
HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级。HTTP1.1也可以多建立几个TCP连接,来支持处理更多并发的请求,但是创建TCP连接本身也是有开销的。
头部数据压缩
在HTTP1.1中,请求和响应都是由状态行、请求/响应头部、消息主体三部分组成。一般而言,消息主体都会经过gzip压缩,或者本身传输的就是压缩过后的二进制文件,但状态行和头部却没有经过任何压缩,直接以纯文本传输。随着Web功能越来越复杂,每个页面产生的请求数也越来越多,导致消耗在头部的流量越来越多,尤其是每次都要传输UserAgent、Cookie这类不会频繁变动的内容,完全是一种浪费。
HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快。
服务器推送
服务端推送是一种在客户端请求之前发送数据的机制。网页使用了许多资源:HTML、样式表、脚本、图片等等。在HTTP1.1中这些资源每一个都必须明确地请求。这是一个很慢的过程。浏览器从获取HTML开始,然后在它解析和评估页面的时候,增量地获取更多的资源。因为服务器必须等待浏览器做每一个请求,网络经常是空闲的和未充分使用的。
为了改善延迟,HTTP2.0引入了server push,它允许服务端推送资源给浏览器,在浏览器明确地请求之前,免得客户端再次创建连接发送请求到服务器端获取。这样客户端可以直接从本地加载这些资源,不用再通过网络。
HTTPS协议
安全套接字层超文本传输协议HTTPS,为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL/TLS协议,SSL/TLS依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。
HTTPS协议是由SSL/TLS+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全
HTTPS协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。
HTTPS和HTTP的主要区别
-
https协议需要到CA申请证书,一般免费证书较少,因而需要一定费用。
-
http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl/tls加密传输协议。
-
http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
-
http的连接很简单,是无状态的;HTTPS协议是由SSL/TLS+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
什么是“对称加密”?
所谓的“对称加密技术”,意思就是说:“加密”和“解密”使用【相同的】密钥。这个比较好理解。就好比你用 7zip 或 WinRAR 创建一个带密码(口令)的加密压缩包。当你下次要把这个压缩文件解开的时候,你需要输入【同样的】密码。在这个例子中,密码/口令就如同刚才说的“密钥”。
什么是“非对称加密”?
所谓的“非对称加密技术”,意思就是说:“加密”和“解密”使用【不同的】密钥。这玩意儿比较难理解,也比较难想到。当年“非对称加密”的发明,还被誉为“密码学”历史上的一次革命。
一般来说指:加密时使用公钥,解密时使用私钥
各自有什么优缺点?
“对称加密”的好处是性能较好,但由于要让客户端掌握密钥,需将密钥在网络上传输,故不安全
“非对称加密”的好处是限制了公钥的能力,即用公钥加密后只能在服务端用私钥解密,这样使得”解密的能力仅保留在服务端“,缺点也很明显,这样只能实现单向加密,客户端没有解密能力.另外由于”非对称加密”涉及到“复杂数学问题”,所以性能相对而言较差.
由于非对称加密的速度比较慢,所以它一般用于密钥交换,双方通过公钥算法协商出一份密钥,然后通过对称加密来通信。
HTTPS的握手图解
SSL和TLS的概念与区别
什么是SSL?
SSL(Secure Socket Layer,安全套接字层),为Netscape所研发,用以保障在Internet上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络上之传输过程中不会被截取。当前版本为3.0。它已被广泛地用于Web浏览器与服务器之间的身份认证和加密数据传输。
SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。SSL协议可分为两层: SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。 SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。
什么是TLS?
TLS(Transport Layer Security,传输层安全协议),用于两个应用程序之间提供保密性和数据完整性。
TLS 1.0是IETF(Internet Engineering Task Force,Internet工程任务组)制定的一种新的协议,它建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本,可以理解为SSL 3.1(可简单理解为同一事物不同阶段的不同称呼),它是写入了 RFC 的。该协议由两层组成: TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake)。较低的层为 TLS 记录协议,位于某个可靠的传输协议(例如 TCP)上面。
SSL和TLS的主要区别?
TLS的主要目标是使SSL更安全,并使协议的规范更精确和完善。另外,TLS版本号也与SSL的不同(TLS的版本1.0使用的版本号为SSLv3.1).
HTTP请求报文解剖
HTTP请求报文由3部分组成(请求行+请求头+请求体):
HTTP响应报文解剖
HTTP的响应报文也由三部分组成(响应行+响应头+响应体):
响应状态码
HTTP的响应状态码由5段组成:
类别 | 原因短语 | |
---|---|---|
1xx | Informational(信息性状态码) | 接受的请求正在处理 |
2xx | Success(成功状态码) | 请求正常处理完毕 |
3xx | Redirection(重定向) | 需要进行附加操作以完成请求 |
4xx | Client error(客户端错误) | 客户端请求出错,服务器无法处理请求 |
5xx | Server Error(服务器错误) | 服务器处理请求出错 |
各类别常见状态码:
2xx (3种)
200 OK:表示从客户端发送给服务器的请求被正常处理并返回;
204 No Content:表示客户端发送给客户端的请求得到了成功处理,但在返回的响应报文中不含实体的主体部分(没有资源可以返回);
206 Patial Content:表示客户端进行了范围请求,并且服务器成功执行了这部分的GET请求,响应报文中包含由Content-Range指定范围的实体内容。
3xx (5种)
301 Moved Permanently:永久性重定向,表示请求的资源被分配了新的URL,之后应使用更改的URL;
302 Found:临时性重定向,表示请求的资源被分配了新的URL,希望本次访问使用新的URL;
301与302的区别:前者是永久移动,后者是临时移动(之后可能还会更改URL)
303 See Other:表示请求的资源被分配了新的URL,应使用GET方法定向获取请求的资源;
302与303的区别:后者明确表示客户端应当采用GET方式获取资源
304 Not Modified:表示客户端发送附带条件(是指采用GET方法的请求报文中包含if-Match、If-Modified-Since、If-None-Match、If-Range、If-Unmodified-Since中任一首部)的请求时,服务器端允许访问资源,但是请求为满足条件的情况下返回改状态码;
307 Temporary Redirect:临时重定向,与303有着相同的含义,307会遵照浏览器标准不会从POST变成GET;(不同浏览器可能会出现不同的情况);
4xx (4种)
400 Bad Request:表示请求报文中存在语法错误;
401 Unauthorized:未经许可,需要通过HTTP认证;
403 Forbidden:服务器拒绝该次访问(访问权限出现问题)
404 Not Found:表示服务器上无法找到请求的资源,除此之外,也可以在服务器拒绝请求但不想给拒绝原因时使用;
5xx (2种)
500 Inter Server Error:表示服务器在执行请求时发生了错误,也有可能是web应用存在的bug或某些临时的错误时;
503 Server Unavailable:表示服务器暂时处于超负载或正在进行停机维护,无法处理请求;
TCP/IP协议簇
URL/URI/URN
URI = Universal Resource Identifier 统一资源标志符,用来标识抽象或物理资源的一个紧凑字符串。
URL = Universal Resource Locator 统一资源定位符,一种定位资源的主要访问机制的字符串,一个标准的URL必须包括:protocol、host、port、path、parameter、anchor。
URN = Universal Resource Name 统一资源名称,通过特定命名空间中的唯一名称或ID来标识资源。
个人的身份证号就是URN,个人的家庭地址就是URL,URN可以唯一标识一个人,而URL可以告诉邮递员怎么把货送到你手里。
GET和POST的区别
1.根据HTTP规范,GET用于信息获取,而且应该是安全的和幂等的。
2.根据HTTP规范,POST表示可能修改变服务器上的资源的请求。
3.GET请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,参数之间以&相连,如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0%E5%A5%BD。如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII。
因为GET没有正文
POST把提交的数据则放置在是HTTP包的包体中。
4.首先是"GET方式提交的数据最多只能是1024字节",因为GET是通过URL提交数据,那么GET可提交的数据量就跟URL的长度有直接关系了。而实际上,URL不存在参数上限的问题,HTTP协议规范没有对URL长度进行限制。这个限制是特定的浏览器及服务器对它的限制。IE对URL长度的限制是2083字节(2K+35)。对于其他浏览器,如Netscape、FireFox等,理论上没有长度限制,其限制取决于操作系统的支持。
注意这是限制是整个URL长度,而不仅仅是你的参数值数据长度。[见参考资料5]
5.理论上讲,POST是没有大小限制的,HTTP协议规范也没有进行大小限制,说“POST数据量存在80K/100K的大小限制”是不准确的,POST数据是没有限制的,起限制作用的是服务器的处理程序的处理能力。
对于ASP程序,Request对象处理每个表单域时存在100K的数据长度限制。但如果使用Request.BinaryRead则没有这个限制。
由这个延伸出去,对于IIS 6.0,微软出于安全考虑,加大了限制。我们还需要注意:
1).IIS 6.0默认ASP POST数据量最大为200KB,每个表单域限制是100KB。
2).IIS 6.0默认上传文件的最大大小是4MB。
3).IIS 6.0默认最大请求头是16KB。
DNS
域名系统(英文:Domain Name System,缩写:DNS)是互联网的一项服务。它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。
DNS解析是分布式存储的,比如根域名服务器ROOT DNS,只存储260个顶级域名的DNS服务器的ip地址。顶级域名服务器如.com的DNS服务器,存储的则是一些一级域名的权威DNS服务器地址(如suning.com,qq.com,163.com的DNS)。而suning.com的权威DNS存储的才是具体的主机记录(如A记录,cname记录,txt记录)
根域名服务器(ROOT)
根服务器主要用来管理互联网的主目录,全世界IPv4根服务器只有13台(这13台IPv4根域名服务器名字分别为“A”至“M”),1个为主根服务器在美国。其余12个均为辅根服务器,其中9个在美国,欧洲2个,位于英国和瑞典,亚洲1个位于日本。根服务器中有经美国政府批准的260个左右的互联网后缀(如.com、.net、.cn等)。
顶级域名服务器
负责解析本身顶级域名下一级域名对应的权威DNS服务器地址。
localDNS
本地DNS,一般是运营商的dns,主要作用是代理用户进行迭代解析。
本地host记录
这个优先级最高可以在自己电脑自定义域名的解析记录,如果本机有就不会再往上迭代。PC的host(C:\Windows\System32\drivers\etc\hosts)
DNS解析的过程
-
查询浏览器缓存有无缓存 有->结束 / 没有->继续
-
查询操作系统有无缓存 ( hosts文件中是否有映射 )
-
请求本地域名服务器( LDNS )来解析
本地域名服务器 : 一般性能比较好, 且离你所在城市较近, 一般都会缓存域名解析结果, 80%的域名解析都会至此结束.
-
如果LDNS没有命中, 直接跳到Root Server域名服务器请求解析
-
根域名服务器返回给LDNS一个所查询域的主域名服务器 ( gTLD Server , 国际顶尖域名服务器, 如.com.cn.org等 )地址
-
此时LDNS再发送请求给上一步返回的gTLD
-
接受请求的gTLD查找且返回这个域名对应的Name Server的地址 ( 即网站注册的域名服务器 )
-
Name Server根据映射关系表找到目标IP, 返回给LDNS
-
LDNS缓存这个域名和对应ip
-
LDNS把解析结果返回给用户, 用户根据TTL值缓存到本地系统缓存, 域名解析过程结束
DNS中哪里使用tpc?
DNS的规范规定了2种类型的DNS服务器,一个叫主DNS服务器,一个叫辅助DNS服务器。在一个区中主DNS服务器从自己本机的数据文件中读取该区的DNS数据信息,而辅助DNS服务器则从区的主DNS服务器中读取该区的DNS数据信息。当一个辅助DNS服务器启动时,它需要与主DNS服务器通信,并加载数据信息,这就叫做区传送(zone transfer)。 这种情况下,使用TCP协议。
DNS中哪里使用UDP?
客户端向DNS服务器查询域名的过程使用UDP
dns中为什么域名解析用udp
因为UDP快啊!UDP的DNS协议只要一个请求、一个应答就好了。而使用基于TCP的DNS协议要三次握手、发送数据以及应答、四次挥手。但是UDP协议传输内容不能超过512字节。不过客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。
dns中区域复制为什么用tcp
因为TCP协议可靠性好啊!你要从主DNS上复制内容啊,你用不可靠的UDP? 因为TCP协议传输的内容大啊,你用最大只能传512字节的UDP协议?万一同步的数据大于512字节,你怎么办?
DNS解析域名的原理
Cookie和Session
什么是cookie?
HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。所以cookie应运而生。
Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
cookie的细节
cookie 的数据类型一定是字符串,如果要发送中文,必须先对中文进行URL加密才可以发送。
setPath (path):修改cookie所在的有效路径。
什么是有效路径?
如果把该cookie 设置到某个有效路径下,然后当浏览器访问这个有效路径的时候,才会携带cookie数据给服务器。
setMaxAge(整数):设置cookie 的有效时间
正整数: 表示超过了正整数的数值的时间,cookie就会丢失! ! (cookie保存浏览器的缓存目录)单位:秒。
负整数: 表示如果浏览器关闭了,cookie就会丢失! (cookie保存浏览器内存)
0: 表示删除同名的cookie
cookie可以有多个,但是浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个cookie的大小限制为4KB
public class Cookiedemo1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 创建Cookie对象,保存会话数据
// 如果发送中文,必须先使用URLEncoder进行加密
String name = URLEncoder.encode("张三", "utf-8");
Cookie c1 = new Cookie("name", name);
Cookie c2 = new Cookie("email", "chen@c.com");
// 发送cookie
response.addCookie(c1);
response.addCookie(c2);
// 浏览器下次访问获取已有的cookie
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
// cookie的名
String cname = cookie.getName();
// cookie的值
String cvalue = cookie.getValue();
// 解密
cvalue = URLDecoder.decode(cvalue, "utf-8");
System.out.println(cname + "=" + cvalue);
}
} else {
System.out.println("没有cookie信息!");
}
}
}
什么是Session?
除了使用Cookie,Web应用程序中还经常使用Session来记录客户端状态。Session是服务器端使用的一种记录客户端状态的机制,使用上比Cookie简单一些,相应的也增加了服务器的存储压力。
Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。
如果说Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。
Session对象是在客户端第一次请求服务器的时候创建的。
为了获得更高的存取速度,服务器一般把Session放在内存里。每个用户都会有一个独立的Session。如果Session内容过于复杂,当大量客户访问服务器时可能会导致内存溢出。因此,Session里的信息应该尽量精简。
Tomcat中Session的默认超时时间为20分钟。通过setMaxInactiveInterval(int seconds)修改超时时间。可以修改web.xml改变Session的默认超时时间。
Session的作用域
然Session保存在服务器,对客户端是透明的,它的正常运行仍然需要客户端浏览器的支持。这是因为Session需要使用Cookie作为识别标志。HTTP协议是无状态的,Session不能依据HTTP连接来判断是否为同一客户,因此服务器向客户端浏览器发送一个名为JSESSIONID的Cookie,它的值为该Session的id(也就是HttpSession.getId()的返回值)。Session依据该Cookie来识别是否为同一用户。
该Cookie为服务器自动生成的,它的maxAge属性一般为–1,表示仅当前浏览器内有效,并且各浏览器窗口间不共享,关闭浏览器就会失效。
因此同一机器的两个浏览器窗口访问服务器时,会生成两个不同的Session。但是由浏览器窗口内的链接、脚本等打开的新窗口(也就是说不是双击桌面浏览器图标等打开的窗口)除外。这类子窗口会共享父窗口的Cookie,因此会共享一个Session。
注意:新开的浏览器窗口会生成新的Session,但子窗口除外。子窗口会共用父窗口的Session。例如,在链接上右击,在弹出的快捷菜单中选择“在新窗口中打开”时,子窗口便可以访问父窗口的Session。
如果客户端浏览器将Cookie功能禁用,或者不支持Cookie怎么办?例如,绝大多数的手机浏览器都不支持Cookie。Java Web提供了另一种解决方案:URL地址重写。URL地址重写是对客户端不支持Cookie的解决方案。URL地址重写的原理是将该用户Session的id信息重写到URL地址中。服务器能够解析重写后的URL获取Session的id。这样即使客户端不支持Cookie,也可以使用Session来记录用户状态。
cookie和session的区别
- cookie数据存放在客户的浏览器上,session数据放在服务器上.
- cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session。
- 设置cookie时间可以使cookie过期。但是使用session-destory(),我们将会销毁会话。
- session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用cookie。
- 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。(Session对象没有对存储的数据量的限制,其中可以保存更为复杂的数据类型)
TCP和UDP
什么是TCP?
TCP: 传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议
TCP的特点
- TCP是面向连接的传输层协议。也就是说,应用程序在使用TCP协议之前,必须先建立TCP连接。在传送数据完毕后,必须释放已经建立的TCP连接。
- TCP连接只能有两个端点,每一条TCP连接只能是点对点的。
- **TCP提供全双工通信。**TCP允许通信双方的应用进程在任何时候都能发送数据。TCP两端都设有发送缓存和接受缓存,用来临时存放双向通信的数据。
- **TCP是面向字节流的。**流指的是流入到进程或从进程流出的字节序列。TCP把应用程序交下来的数据仅仅只看城市一连串的无结构字节流。
为什么可靠?
TCP提供交付保证(Tcp通过校验和,序号标识,超时重传、确认应答(累计确认)、流量控制(滑动窗口,控制TCP报文的发送时机)、拥塞控制实现可靠传输),无差错,不丢失,不重复,且按序到达,也保证了消息的有序性。该消息将以从服务器端发出的同样的顺序发送到客户端,尽管这些消息到网络的另一端时可能是无序的。TCP协议将会为你排好序。
校验和
发送的数据包首部和数据按16位二进制拆分 相加然后取反,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段。
序号标识
TCP传输时将每个字节的数据都进行了编号,在发送数据时会将首部的序号标识为第一位字节的序号
确认应答
接收方收到报文就会确认(累积确认:对所有按序接收的数据的确认)
也就是在响应的报文首部的确认号设置为当前接收到的最新序号+1,表明之前的序号的数据字节收到了,希望下一个报文段的数据字节以+1开头
超时重传:
当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。
首先,发送方没有接收到响应的ACK报文原因可能有两点:
a、数据在传输过程中由于网络原因等直接全体丢包,接收方没有接收到。
b、接收方接收到了响应的数据,但是发送的ACK报文响应却由于网络原因丢包了。
TCP在解决这个问题的时候引入了一个新的机制,叫做超时重传机制。
简单理解就是发送方在发送完数据后等待一个时间,时间到达没有接收到ACK报文,那么对刚才发送的数据进行重新发送。
如果是刚才第一个原因,接收方收到二次重发的数据后,便进行ACK应答。
如果是第二个原因,接收方发现接收的数据已存在(判断存在的根据就是序列号,所以上面说序列号还有去除重复数据的作用),那么直接丢弃,仍旧发送ACK应答。
超时以500ms(0.5秒)为一个单位进行控制,每次判定超时重发的超时时间都是500ms的整数倍。
重发一次后,仍未响应,那么等待2500ms的时间后,再次重传。等待4500ms的时间继续重传。以一个指数的形式增长。
流量控制
如果发送端的发送速度太快,导致接收端的结束缓冲区很快的填充满了。此时如果发送端仍旧发送数据,那么接下来发送的数据都会丢包,继而导致丢包的一系列连锁反应,超时重传呀什么的。而TCP根据接收端对数据的处理能力,决定发送端的发送速度,这个机制就是流量控制。
接收方处理不过来的时候,就把窗口缩小,并把窗口值告诉发送端。
如果接收到窗口大小的值为0,那么发送方将停止发送数据。并定期的向接收端发送窗口探测数据段,让接收端把窗口大小告诉发送端。
滑动窗口控制
我们上面提到的超时重传的机制存在效率低下的问题,发送一个包到发送下一个包要经过一段时间才可以。所以我们就想着能不能不用等待确认包就发送下一个数据包呢?这就提出了一个滑动窗口的概念。
窗口的大小就是在无需等待确认包的情况下,发送端还能发送的最大数据量。这个机制的实现就是使用了大量的缓冲区,通过对多个段进行确认应答的功能。通过下一次的确认包可以判断接收端是否已经接收到了数据,如果已经接收了就从缓冲区里面删除数据。
控制TCP报文的发送时机
可以用不同的机制控制TCP报文段的发送时机。
- TCP维持一个变量,它等于最大报文段长度MSS。只要缓存中的数据达到MSS字节时,就组成一个报文段发送出去。
- 发送方的应用程序指明要发送报文段,即TCP支持的推送操作
- 发送方的计时器时限到了,就发送报文段。
Nagle(内格尔)算法
在TCP的实现中广泛使用Nagle 算法。算法如下:
若发送应用进程把要发送的数据逐个字节地送到TCP的发送缓存,则发送方就把第一个数据字节先发送出去,把后面到达的数据字节都缓存起来。当发送方收到对第一个数据字符的确认后,再把发送缓存中的所有数据组装成一个报文段发送出去,同时继续对随后到达的数据进行缓存。只有在收到对前一个报文段的确认后才继续发送下一个报文段。当数据到达较快而网络速率较慢时,用这样的方法可明显地减少所用的网络带宽。
Nagle 算法还规定,当到达的数据已达到发送窗口大小的一半或已达到报文段的最大长度时,就立即发送一一个报文段。这样做,就可以有效地提高网络的吞吐量。
糊涂窗口综合征
另一个向题叫做糊涂窗口综合征(silly window syndrome),有时也会使TCP的性能变坏。设想一种情况:
TCP 接收方的缓存已满,而交互式的应用进程一次只从接收缓存中读取1个字节(这样就使接收缓存空间仅腾出1个字节),然后向发送方发送确认,并把窗口设置为1个字节(但发送的数据报是40字节长)。接着,发送方又发来1个字节的数据(请注意,发送方发送的IP数据报是41字节长)。接收方发回确认,仍然将窗口设置为1个字节。这样进行下去,使网络的效率很低。
要解决这个问题,可以让接收方等待一段时间,使得或者接收缓存已有足够空间容纳一个最长的报文段,或者等到接收缓存已有一-半空闲的空间。只要出现这两种情况之一,接收方就发出确认报文,并向发送方通知当前的窗口大小。此外,发送方也不要发送太小的报文段,而是把数据积累成足够大的报文段,或达到接收方缓存的空间的一半大小。
上述两种方法可配合使用。使得在发送方不发送很小的报文段的同时,接收方也不要在缓存刚刚有了一点小的空间就急忙把这个很小的窗口大小信息通知给发送方。
拥塞控制
在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就要变坏,这种情况就叫做网络拥塞。
若出现拥塞而不进行控制,整个网络的吞吐量将随输入负荷的增大而下降。
流量控制是为了让接收方能来得及接收,而拥塞控制是为了降低整个网络的拥塞程度。
TCP 主要通过四个算法来进行拥塞控制:慢开始、拥塞避免、快重传、快恢复。
发送方需要维护一个叫做拥塞窗口(cwnd)的状态变量,注意拥塞窗口与发送方窗口的区别:拥塞窗口只是一个状态变量,实际决定发送方能发送多少数据的是发送方窗口。
慢开始和拥塞避免
最开始采用慢开始算法(指数增长)。当拥塞窗口的值达到慢开始门限时开始执行拥塞避免算法,呈现线性增长。
当发送超时重传时,将当前拥塞窗口值/2当作慢开始门限,同时将拥塞窗口值重置,重新执行慢开始算法
快恢复和快重传
当拥塞窗口达到某一个值时出现了一个新的情况,就是发送方连续收到3个对统一报文段的重复确认(3-ACK),发送方知道只是丢失了个别的报文段,不需要等到超时重传,发送方立即重传,同时将慢开始门限值设置为当前窗口的一半,将拥塞窗口的值设置为慢开始门限值。
可以避免丢包后发送方误以为发生拥塞且超时重传, 从而错误启动慢开始算法, 把拥塞窗口cwnd设置为最小值1, 降低了传输效率
TCP的粘包和解决方法
TCP粘包就是指发送方发送的若干包数据到达接收方时粘成了一包,从接收缓冲区来看,后一包数据的头紧接着前一包数据的尾。
出现粘包的原因主要有两方面:
- 由Nagle算法造成的发送端的粘包
- 接收端接收不及时造成的接收端粘包
对于UDP来说就不存在拆包的问题,因为UDP是个"数据包"协议,也就是两段数据间是有界限的,TCP面向字节流,数据包之间没有信息界限
解决方案
-
定长发送
在进行数据发送时采用固定长度的设计,也就是无论多大数据发送都分包为固定长度,也就是发送端在发送数据时都以LEN为长度进行分包。这样接收方都以固定的LEN进行接收,如此一来发送和接收就能一一对应了
-
尾部标记序列
在每个要发送的数据包的尾部设置一个特殊的字节序列,此序列带有特殊含义,跟字符串的结束符标识”\0”一样的含义,用来标示这个数据包的末尾,接收方可对接收的数据进行分析,通过尾部序列确认数据包的边界。
-
头部标记分步接收
定义一个用户报头,在报头中注明每次发送的数据包大小。接收方每次接收时先以报头的size进行数据读取,这必然只能读到一个报头的数据,从报头中得到该数据包的数据大小,然后再按照此大小进行再次读取,就能读到数据的内容了。这样一来,每个数据包发送时都封装一个报头,然后接收方分两次接收一个包,第一次接收报头,根据报头大小第二次才接收数据内容。
什么是UDP?
UDP:该协议称为用户数据报协议(UDP,User Datagram Protocol)。UDP 为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据报的方法。
UDP的特点
- UDP是无连接的,即发送数据之前不需要建立连接,因此减少了开销和发送数据之前的时延。
- UPD使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态表
- UPD是面向报文的。UDP对于应用层交下来的报文,在添加首部后就交付网络层。对于网络层接受的报文,也只是去除了首部后就交付给应用层。也就是说UDP一次交付一个完整的报文。
- UPD没有拥塞控制。
- UPD支持一对一、一对多、多对一和多对多的交互通信。
- UPD的首部开销小,只有8个字节,比TCP的20个字节的首部要短。
TCP和UDP的区别
是否基于连接
- TCP是面向连接的协议,而UDP是无连接的协议。即TCP面向连接;
- UDP是无连接的,即发送数据之前不需要建立连接。
可靠性 和 有序性 区别
- TCP提供交付保证(Tcp通过校验和,重传控制,序号标识,滑动窗口、确认应答实现可靠传输),无差错,不丢失,不重复,且按序到达,也保证了消息的有序性。该消息将以从服务器端发出的同样的顺序发送到客户端,尽管这些消息到网络的另一端时可能是无序的。TCP协议将会为你排好序。
- UDP不提供任何有序性或序列性的保证。UDP尽最大努力交付,数据包将以任何可能的顺序到达。
TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道
实时性
UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高的通信或广播通信。
协议首部大小
- TCP首部开销20字节;
- UDP的首部开销小,只有8个字节 。
运行速度
TCP速度比较慢,而UDP速度比较快,因为TCP必须创建连接,以保证消息的可靠交付和有序性,毕竟TCP协议比UDP复杂。
拥塞机制
UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
流模式(TCP)与数据报模式(UDP);
- TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;
- UDP是面向报文的 。
资源占用
- TCP对系统资源要求较多,UDP对系统资源要求较少。
- TCP被认为是重量级的协议,而与之相比,UDP协议则是一个轻量级的协议。因为UDP传输的信息中不承担任何间接创造连接,保证交货或秩序的的信息。这也反映在用于承载元数据的头的大小。
应用
- 每一条TCP连接只能是点到点的;
- UDP支持一对一,一对多,多对一和多对多的交互通信 。基于UDP不需要建立连接,所以且适合多播的环境,UDP是大量使用在游戏和娱乐场所。
TCP和UDP的优缺点
UDP
UDP 优点:简单、传输快。
网速的提升给UDP的稳定性提供可靠网络保障,丢包率很低,如果使用应用层重传,能够确保传输的可靠性。
TCP为了实现网络通信的可靠性,使用了复杂的拥塞控制算法,建立了繁琐的握手过程,由于TCP内置的系统协议栈中,极难对其进行改进。采用TCP,一旦发生丢包,TCP会将后续的包缓存起来,等前面的包重传并接收到后再继续发送,延时会越来越大,基于UDP对实时性要求较为严格的情况下,采用自定义重传机制,能够把丢包产生的延迟降到最低,尽量减少网络问题对游戏性造成影响。
UDP缺点:不可靠,不稳定;
UDP应用场景:
- 面向数据报方式
- 网络数据大多为短消息
- 拥有大量Client
- 对数据安全性无特殊要求
- 网络负担非常重,但对响应速度要求高
TCP
TCP: 优点:可靠 稳定
TCP的可靠体现在TCP在传输数据之前,会有三次握手来建立连接,而且在数据传递时,有确认. 窗口. 重传. 拥塞控制机制,在数据传完之后,还会断开来连接用来节约系统资源。
缺点:慢,效率低,占用系统资源高,易被攻击
TCP应用场景:
当对网络质量有要求时,比如HTTP,HTTPS,FTP等传输文件的协议;POP,SMTP等邮件传输的协议。
TCP的三次握手和四次挥手
三次握手:
- 在打算建立TCP连接的时,A向B发出连接请求的报文段,这时首部中的同步位SYN=1,同时选择一个初始序号seq=x。SYN报文段不能携带数据,但是要消耗一个序号,这时,TCP的客户进程进入SYN-SENT(同步已发送)状态。
- B收到连接请求的报文段后,如果同意建立连接,则向A发送确认。在确认报文段中把SYN位和ACK位都置1,确认号设置为ack=x+1,同时也为自己选择一个初始序号seq=y。这个报文段也不能携带数据,也要消耗一个序号。这时TCP服务器进入SYN-RCVD(同步收到)状态。
- TCP客户进程收到B的确认后,还要向B给出确认。确认报文段的ACK置1,确认号ack=y+1,而自己的序号seq=x+1。ACK报文段可以携带数据,如果不携带数据的话,数据报文段的序号仍然是seq=x+1。TCP连接已经建立,A进入ESTABLISHED(已建立连接)状态。
- 当B收到A的确认后,也进入ESTABLISHED(已建立连接)状态
四次挥手:
- A的应用程序先向其TCP发出连接释放报文段,并停止再发送数据,主动关闭TCP连接。A把连接释放报文段首部的终止控制位FIN置1,其序号seq=u,它等于前面已经传送过的数据的最后一个字节的序号+1。这时A进入FIN-WAIT-1(终止等待1)状态,等待B的确认。FIN报文段即使不携带数据,也消耗一个序号。
- B收到连接释放报文段后即发出确认,确认号是ack=u+1,而中国报文段自己的序号是v,等于B前面已传送过的数据的最后一个字节的序号+1。然后B进入CLOSE-WAIT(关闭等待)状态。从A到B这个方向的连接就释放了,这时的TCP连接处于半关闭状态。从B到A的这个方向的连接并未关闭。
- A收到B的确认以后,就进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段。
- 若B已经没有要发送的数据了,其应用程序就通知TCP释放连接。这时B发出的连接释放报文段必须使FIN=1。现假定B的序号为w(在半关闭状态下B可能又发送了一些数据)。B还必须重复上次已发送过的确认号ack=u+1。这时B就进入LAST-ACK(最后确认)状态,等待A的确认。
- A在收到B的连接释放报文段后,必须对此发出确认。在确认报文段中把ACK置1,确认号ack=w+1,而自己的序号是seq=u+1。然后进入TIME-WAIT状态(时间等待)状态。现在的TCP连接还没有释放掉。必须经过时间等待计时器设置的2MSL(两个最长报文段寿命)后,A才进入CLOSED状态。
为什么需要三次握手,两次不行吗?
弄清这个问题,我们需要先弄明白三次握手的目的是什么,能不能只用两次握手来达到同样的目的。
- 第一次握手:客户端发送网络包,服务端收到了。 这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。
- 第二次握手:服务端发包,客户端收到了。
- 这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。不过此时服务器并不能确认客户端的接收能力是否正常。
- 第三次握手:客户端发包,服务端收到了。 这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。
因此,需要三次握手才能确认双方的接收与发送能力是否正常。
试想如果是用两次握手,则会出现下面这种情况:
如客户端发出连接请求,但因连接请求报文丢失而未收到确认,于是客户端再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接,客户端共发出了两个连接请求报文段,其中第一个丢失,第二个到达了服务端,但是第一个丢失的报文段只是在某些网络结点长时间滞留了,延误到连接释放以后的某个时间才到达服务端,此时服务端误认为客户端又发出一次新的连接请求,于是就向客户端发出确认报文段,同意建立连接,不采用三次握手,只要服务端发出确认,就建立新的连接了,此时客户端忽略服务端发来的确认,也不发送数据,则服务端一致等待客户端发送数据,浪费资源。
三次握手过程中可以携带数据吗?
其实第三次握手的时候,是可以携带数据的。
但是,第一次、第二次握手不可以携带数据
为什么这样呢?大家可以想一个问题,假如第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据。因为攻击者根本就不理服务器的接收、发送能力是否正常,然后疯狂着重复发 SYN 报文的话,这会让服务器花费很多时间、内存空间来接收这些报文。
也就是说,第一次握手不可以放数据,其中一个简单的原因就是会让服务器更加容易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTABLISHED 状态。对于客户端来说,他已经建立起连接了,并且也已经知道服务器的接收、发送能力是正常的了,所以能携带数据也没啥毛病。
挥手为什么需要四次?
因为当服务端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当服务端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,“你发的FIN报文我收到了”。只有等到我服务端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四次挥手。
为什么要等待2MSL的时间?
- 确保A的最后一个ACK报文段能够到达B,如果发生了丢失,A可以进行重传,避免A关闭B没关闭的情况,服务端请求重发,一来一回就正好是2MSL
- 使本连接持续时间内所产生的所有报文段都从网络中消失,这样在下一个新的连接中不会出现旧的请求报文段
出现大量TIME-WAIT状态的原因和解决方法
- 在高并发(每秒几万qps)并且采用短连接方式进行交互的系统中运行一段时间后,系统中就会存在大量的time_wait状态,如果time_wait状态把系统所有可用端口都占完了且尚未被系统回收时,就会出现无法向服务端创建新的socket连接的情况。此时系统几乎停转,任何链接都不能建立。
解决方法:
调整系统内核参数
net.ipv4.tcp_syncookies = 1
#表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭
net.ipv4.tcp_tw_reuse = 1
#表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭
net.ipv4.tcp_tw_recycle = 1
#表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭
net.ipv4.tcp_fin_timeout = 5
#修改系统默认的MSL 时间。
调整短链接为长链接
长连接比短连接从根本上减少了关闭连接的次数,减少了TIME_WAIT状态的产生数量,在高并发的系统中,这种方式的改动非常有效果,可以明显减少系统TIME_WAIT的数量。
- HTTP默认的Connection值为close,那么就意味着关闭请求的一方几乎都会是由服务端这边发起的。那么这个服务端产生TIME_WAIT过多的情况就很正常了。
- 虽然HTTP默认Connection值为close,但是,现在的浏览器发送请求的时候一般都会设置Connection为keep-alive了,也就是由浏览器主动发起断开。
服务器保持了大量CLOSE_WAIT状态
close_wait是被动关闭连接是形成的,根据TCP状态机,服务器端收到客户端发送的FIN,TCP协议栈会自动发送ACK,链接进入close_wait状态。但如果服务器端不执行socket的close()操作,状态就不能由close_wait迁移到last_ack,则系统中会存在很多close_wait状态的连接,如下图所示:
- 程序问题:如果代码层面忘记了 close 相应的 socket 连接,那么自然不会发出 FIN 包,从而导致 CLOSE_WAIT 累积;或者代码不严谨,出现死循环之类的问题,导致即便后面写了 close 也永远执行不到。
- 响应太慢或者超时设置过小:如果连接双方不和谐,一方不耐烦直接 timeout,另一方却还在忙于耗时逻辑,就会导致 close 被延后。响应太慢是首要问题,不过换个角度看,也可能是 timeout 设置过小。
这时候很可能是因为程序中在收到FIN=1的TCP报文后,由于忙于读或者写,没有去及时发送FIN回来,也就是无法及时关闭连接。这时候需要着重检查释放资源的代码和处理请求的线程配置,有可能是代码中有资源没有被释放掉,也有可能是线程池中的线程数不合理等等
TCP的拥塞控制
TCP和HTTP的关系:
- TCP是传输层,而http是应用层
- http是要基于TCP连接基础上的 TCP就是单纯建立连接,不涉及任何我们需要请求的实际数据,简单的传输。
http是用来收发数据,即实际应用上来的。 - TCP是底层通讯协议,定义的是数据传输和连接方式的规范
- HTTP是应用层协议,定义的是传输数据的内容的规范
- HTTP协议中的数据是利用TCP协议传输的,所以支持HTTP也就一定支持TCP
Socket
Socket是什么呢?
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组系统调用接口,定义了许多标准的系统调用函数。它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
Socket通信流程
先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。