文章目录
-
- 1. Http和Https的区别
- 2. 对称加密与非对称加密
- 3. 交换机、路由器、网关的概念
- 4. HTTP协议
- 5. 键入URL,回车之后的流程及用到的协议
- 6. GET和POST的区别
- 7. TCP三次握手与四次挥手
- 8. 为什么TCP链接需要三次握手,两次不可以么?
- 9. 为什么四次挥手最后客户端还要等待2MSL?
- 10. TCP和UDP协议的区别
- 11. TCP和UDP分别对应的常见应用层协议
- 12. TCP协议如何来保证传输的可靠性
- 13. HTTP长连接、短连接
- 14. 客户端不断进行请求链接会怎样?
- 15. Session、Cookie 与 Application
- 16. OSI网络体系结构与TCP/IP协议模型
- 17. SQL注入
- 18. XSS 攻击
- 19. 创建一个简单tcp服务器需要的流程
- 20. AJAX是什么,如何使用AJAX?
1. Http和Https的区别
- Http协议运行在TCP之上,明文传输,客户端与服务器端都无法验证对方的身份;
- Https是身披SSL(Secure Socket Layer)外壳的Http,运行于SSL上,SSL运行于TCP之上,是添加了加密和认证机制的HTTP。二者之间存在如下不同:
-
端口不同:Http与Http使用不同的连接方式,用的端口也不一样,前者是80,后者是443
-
资源消耗:和HTTP通信相比,Https通信会由于加减密处理消耗更多的CPU和内存资源
-
开销:Https通信需要证书,而证书一般需要向认证机构购买,Https的加密机制是一种共享密钥加密和公开密钥加密并用的混合加密机制
2. 对称加密与非对称加密
-
对称密钥加密是指加密和解密使用同一个密钥的方式,这种方式存在的最大问题就是密钥发送问题,即如何安全地将密钥发给对方;而非对称加密是指使用一对非对称密钥,即公钥和私钥,公钥可以随意发布,但私钥只有自己知道。发送密文的一方使用对方的公钥进行加密处理,对方接收到加密信息后,使用自己的私钥进行解密。
-
由于非对称加密的方式不需要发送用来解密的私钥,所以可以保证安全性;但是和对称加密比起来,它非常的慢,所以我们还是要用对称加密来传送消息,但对称加密所使用的密钥我们可以通过非对称加密的方式发送出去
3. 交换机、路由器、网关的概念
- 交换机
交换机拥有一条高带宽的背部总线和内部交换矩阵。交换机的所有的端口都挂接在这条背部总线上,当控制电路收到数据包以后,处理端口会查找内存中的地址对照表以确定目的MAC(网卡的硬件地址)的NIC(网卡)挂接在哪个端口上,通过内部交换矩阵迅速将数据包传送到目的端口。目的MAC若不存在,交换机才广播到所有的端口,接收端口回应后交换机会“学习”新的地址,并把它添加入内部地址表中。交换机工作于OSI参考模型的第二层,即数据链路层。交换机内部的CPU会在每个端口成功连接时,通过ARP协议学习它的MAC地址,保存成一张 ARP表
- 路由器
路由器(Router)是一种计算机网络设备,提供了路由与转送两种重要机制,可以决定数据包从来源端到目的端所经过的路由路径(host到host之间的传输路径),这个过程称为路由;将路由器输入端的数据包移送至适当的路由器输出端(在路由器内部进行),这称为转送。路由工作在OSI模型的第三层——即网络层。路由器的一个作用是连通不同的网络,另一个作用是选择信息传送的线路。
- 网关
网关(gateway)能在不同协议间移动数据,而路由器(router)是在不同网络间移动数据,相当于传统所说的IP网关(IP gateway)。
4. HTTP协议
- 简介
-
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。
-
HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。
-
HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(Next Generation of HTTP)的建议已经提出。
-
HTTP协议工作于客户端-服务端架构为上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息。
- 主要特点
-
简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
-
灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
-
无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
-
无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
-
支持B/S及C/S模式。
- 工作原理
HTTP协议定义Web客户端如何从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端。HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求报文,请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。
以下是 HTTP 请求/响应的步骤:
- 客户端连接到Web服务器
一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接
- 发送HTTP请求
通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成
- 服务器接受请求并返回HTTP响应
Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成
- 释放连接TCP连接
若connection 模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求
- 客户端浏览器解析HTML内容
客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示
- 请求方法
HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD方法。
HTTP1.1 新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
方法
|
作用 |
---|---|
get | 请求指定的页面信息,并返回实体主体 |
head | 类似get,但返回的响应中没有具体的内容,用于获取报头 |
post | 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改 |
put | 从客户端向服务器传送的数据取代指定的文档的内容 |
delete | 请求服务器删除指定的页面 |
connect | HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器 |
options | 允许客户端查看服务器的性能 |
trace | 回显服务器收到的请求,主要用于测试或诊断 |
- 请求消息Request
请求行(request line)、请求头部(header)、空行和请求数据四个部分组成
GET /562f25980001b1b106000338.jpg HTTP/1.1
Host img.mukewang.com
User-Agent Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36
Accept image/webp,image/*,*/*;q=0.8
Referer http://www.imooc.com/
Accept-Encoding gzip, deflate, sdch
Accept-Language zh-CN,zh;q=0.8
POST / HTTP1.1
Host:www.wrox.com
User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
Content-Type:application/x-www-form-urlencoded
Content-Length:40
Connection: Keep-Alive
name=Professional%20Ajax&publisher=Wiley
- 响应消息Response
状态行、消息报头、空行和响应正文组成
HTTP/1.1 200 OK
Date: Fri, 22 May 2009 06:07:21 GMT
Content-Type: text/html; charset=UTF-8
<html>
<head></head>
<body>
<!--body goes here-->
</body>
</html>
- http状态码
状态码 | 含义 | 原因 |
---|---|---|
1xx | 指示信息 | 表示请求已接收,继续处理 |
2xx | 成功 | 表示请求已被成功接收、理解、接受 |
3xx | 重定向 | 要完成请求必须进行更进一步的操作 |
4xx | 客户端错误 | 请求有语法错误或请求无法实现 |
5xx | 服务器端错误 | 服务器未能实现合法的请求 |
200 OK //客户端请求成功
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,eg:输入了错误的URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
5. 键入URL,回车之后的流程及用到的协议
-
浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;
-
解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立TCP连接(三次握手);
-
浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;
-
服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器。若遇到对js文件、css文件及图片等静态资源的引用,则重复上述步骤并向服务器请求这些资源;
-
释放 TCP连接;
-
浏览器将该 html 文本并显示内容;
6. GET和POST的区别
- get是从服务器上获取数据,post是向服务器传送数据
- get参数通过URL传递,post放在Request body中
- 可提交数据大小不同,get受限于浏览器可键入URL的长度,而post取决于服务器的设置和内存大小
- get请求能够被缓存,保存在浏览记录中,以GET请求的URL能够保存为浏览器书签,post请求不具有这些功能
- get比post更不安全,因为参数直接暴露在URL上,但两者都是http明文协议,所以安全级别是一样的,但可以加密
- get请求会把http header和data一并发送出去,服务器响应200(返回数据);post先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据),并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。
- HTTP的底层是TCP/IP,GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接。GET和POST能做的事情是一样一样的。你要给GET加上request body,给POST带上url参数,技术上是完全行的通的。
7. TCP三次握手与四次挥手
- TCP连接的建立(三次握手)
- 【我要和你建立链接;你真的要和我建立链接么;我真的要和你建立链接;成功,开始发送数据】
-
TCP服务器进程先创建传输控制块TCB,时刻准备接受客户进程的连接请求,此时服务器就进入了LISTEN(监听)状态
-
TCP客户进程也是先创建传输控制块TCB,然后向服务器发出连接请求报文,这是报文首部中的同部位SYN=1,同时选择一个初始序列号 seq=x ,此时,TCP客户端进程进入了SYN-SENT(同步已发送状态)状态
-
TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1,同时也要为自己初始化一个序列号 seq=y,此时,TCP服务器进程进入了SYN-RCVD(同步收到)状态
-
TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,自己的序列号seq=x+1,此时,TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态
-
当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了
- TCP连接的释放(四次挥手)
- 【我要和你断开链接;好的,断吧;我也要和你断开链接;好的,断吧】
-
客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
-
服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
-
客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
-
服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
-
客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗*∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
-
服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。
8. 为什么TCP链接需要三次握手,两次不可以么?
- 原因
主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。
- 举例
如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。
如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。
9. 为什么四次挥手最后客户端还要等待2MSL?
MSL(Maximum Segment Lifetime),TCP允许不同的实现可以设置不同的MSL值。
-
保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。
-
防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文
10. TCP和UDP协议的区别
11. TCP和UDP分别对应的常见应用层协议
- TCP
-
FTP:定义了文件传输协议。下载文件,上传主页,都要用到FTP服务。端口21.
-
Telnet:一种用于远程登陆的端口,用户可以以自己的身份远程连接到计算机上,通过这种端口可以提供一种基于DOS模式下的通信服务。
-
SMTP:定义了简单邮件传送协议,很多邮件服务器都用的是这个协议,用于发送邮件。端口25
-
POP3:它是和SMTP对应,POP3用于接收邮件。端口110。
-
HTTP:从Web服务器传输超文本到本地浏览器的传送协议。
- UDP
-
DNS:用于域名解析服务,将域名地址转换为IP地址。端口53。
-
SNMP:简单网络管理协议,是用来管理网络设备的。由于网络设备很多,无连接的服务就体现出其优势。端口161。
-
TFTP(Trival File Transfer Protocal):简单文件传输协议,该协议在熟知端口69上使用UDP服务。
12. TCP协议如何来保证传输的可靠性
-
数据包校验:目的是检测数据在传输过程中的任何变化,若校验出包有错,则丢弃报文段并且不给出响应,这时TCP发送数据端超时后会重发数据;
-
对失序数据包重排序:既然TCP报文段作为IP数据报来传输,而IP数据报的到达可能会失序,因此TCP报文段的到达也可能会失序。TCP将对失序数据进行重新排序,然后才交给应用层;
-
丢弃重复数据:对于重复数据,能够丢弃重复数据;
-
应答机制:当TCP收到发自TCP连接另一端的数据,它将发送一个确认。这个确认不是立即发送,通常将推迟几分之一秒;
-
超时重发:当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段(自动重传请求 ARQ 协议);
-
流量控制:TCP连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区所能接纳的数据,这可以防止较快主机致使较慢主机的缓冲区溢出,这就是流量控制。TCP使用的流量控制协议是可变大小的滑动窗口协议。
13. HTTP长连接、短连接
- HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接
-
在HTTP/1.0中默认使用短连接。也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。
-
而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码:
Connection:keep-alive
- 在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。
14. 客户端不断进行请求链接会怎样?
- DDos(Distributed Denial of Service)攻击?
- 服务器端会为每个请求创建一个链接,并向其发送确认报文,然后等待客户端进行确认
- DDos 攻击
- 客户端向服务端发送请求链接数据包
- 服务端向客户端发送确认数据包
- 客户端不向服务端发送确认数据包,服务器一直等待来自客户端的确认
- DDos 预防 ( 没有彻底根治的办法,除非不使用TCP )
- 限制同时打开SYN半链接的数目
- 缩短SYN半链接的Time out 时间
- 关闭不必要的服务
15. Session、Cookie 与 Application
- cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案
-
Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie,而客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器,服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容
-
客户端请求服务器,如果服务器记录该用户状态,就获取Session来保存状态,如果服务器已经为此客户端创建过session,服务器就按照sessionid把这个session检索出来使用;如果客户端请求不包含sessionid,则为此客户端创建一个session并且生成一个与此session相关联的sessionid,并将这个sessionid在本次响应中返回给客户端保存。保存这个sessionid的方式可以采用cookie机制,这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器;若浏览器禁用Cookie的话,可以通过URL重写机制将sessionid传回服务器。
- Session 与 Cookie 的对比
-
**实现机制:**Session的实现常常依赖于Cookie机制,通过Cookie机制回传SessionID
-
大小限制:Cookie有大小限制并且浏览器对每个站点也有cookie的个数限制,Session没有大小限制,理论上只与服务器的内存大小有关
-
安全性:Cookie存在安全隐患,通过拦截或本地文件找得到cookie后可以进行攻击,而Session由于保存在服务器端,相对更加安全
-
服务器资源消耗:Session是保存在服务器端上会存在一段时间才会消失,如果session过多会增加服务器的压力
16. OSI网络体系结构与TCP/IP协议模型
名称 | 作用 | 涉及协议 |
---|---|---|
应用层 | 允许访问OSI环境的手段(应用协议数据单元APDU) | FTP、DNS、Telnet、SMTP、HTTP、WWW、NFS |
表示层 | 对数据进行翻译、加密和压缩(表示协议数据单元PPDU) | JPEG、MPEG、ASII |
会话层 | 建立、管理和终止会话(会话协议数据单元SPDU) | NFS、SQL、NETBIOS、RPC |
传输层 | 提供端到端的可靠报文传递和错误恢复(段Segment) | TCP、UDP、SPX |
网络层 | 负责数据包从源到宿的传递和网际互连(包PackeT) | IP、ICMP、ARP、RARP、OSPF、IPX、RIP、IGRP、 (路由器) |
数据链路 | 将比特组装成帧和点到点的传递(帧Frame) | PPP、FR、HDLC、VLAN、MAC (网桥,交换机) |
物理层 | 通过媒介传输比特,确定机械及电气规范(比特Bit) | RJ45、CLOCK、IEEE802.3 (中继器,集线器) |
17. SQL注入
-
SQL注入就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令
-
使用预编译手段,绑定参数是最好的防SQL注入的方法,使恶意SQL会被当做SQL的参数而不是SQL命令被执行;使用正则表达式过滤传入的参数
18. XSS 攻击
-
XSS是指恶意攻击者利用网站没有对用户提交数据进行转义处理或者过滤不足的缺点,进而添加一些脚本代码嵌入到web页面中去,使别的用户访问都会执行相应的嵌入代码,从而盗取用户资料、利用用户身份进行某种动作或者对访问者进行病毒侵害的一种攻击方式
-
将重要的cookie标记为http only, 这样的话Javascript 中的document.cookie语句就不能
获取到cookie了;表单数据规定值的类型;对数据进行Html Encode 处理
19. 创建一个简单tcp服务器需要的流程
- socket创建一个套接字
- bind绑定ip和port
- listen使套接字变为可以被动链接
- accept等待客户端的链接
- recv/send接受发送数据
20. AJAX是什么,如何使用AJAX?
- ajax (异步的javascript 和xml) 能够刷新局部网页数据而不是重新加载整个网页
-
创建xmlhttprequest对象,var xmlhttp =new XMLHttpRequest();XMLHttpRequest对象用来和服务器交换数据
-
使用xmlhttprequest对象的open()和send()方法发送资源请求给服务器
-
使用xmlhttprequest对象的responseText或responseXML属性获得服务器的响应
-
onreadystatechange函数,当发送请求到服务器,我们想要服务器响应执行一些功能就需要使用onreadystatechange函数,每次xmlhttprequest对象的readyState发生改变都会触发onreadystatechange函数
转载:https://blog.csdn.net/sGDUTBMW/article/details/115836896