JAVA常用知识总结(八)——计算机网络

  • GET 和 POST 的区别?

  • get参数通过url传递,post放在request body中。

  • get请求在url中传递的参数是有长度限制的,而post没有。

  • get比post更不安全,因为参数直接暴露在url中,所以不能用来传递敏感信息。

  • GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。
  • GET产生一个TCP数据包;POST产生两个TCP数据包。

    对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);

    而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

(据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。)

但现有的大多数Http通信还是用的get请求,原因主要为:

POST要比GET安全一点点,注意,是一点点。。。

说这两者都是明文传送当然是没有错的了,但是这里有一个细节,就是GET的URL会被放在浏览器历史和WEB 服务器日志里面。

POST 发完基本就木有了。。

所以如果你把关键数据放在GET里面,被人偷窥了浏览器,或者WEB服务器被入侵日志被人倒去了,基本泄露可能性100%。而POST来说,日志没有记录,只要数据库服务器不被入侵,基本还是安全的。

当然如果被抓了包,这一切都没有什么用,所以,HTTPS该用还是得用。最大的优势是, GET 的URL可以手输啊。。。你在地址栏打个POST给我看看。本质上面, GET 的所有信息都在URL, 所以很方便的记录下来重复使用(请求中的URL可以被存在书签里,或者历史里,或者快速拨号里面,或者分享给别人。
- 请求中的URL是可以被搜索引擎收录的。请求中的URL可以被缓存)。

反之,就用POST. 特别是有一些东西你是不想让人家可以在浏览器地址栏里面可以输入的。比如,如果你设计一个blog系统, 设计这样一个URL来删掉所有帖子。
  http://myblog.com/?action=delete_all

我只能说很快你就知道什么叫不作死就不会死这个道理了,搜索引擎的爬虫分分钟教你做人。

另外一个准则是,可以重复的交互,比如取个数据,跳个页面, 用GET

不可以重复的操作, 比如创建一个条目/修改一条记录, 用POST, 因为POST不能被缓存,所以浏览器不会多次提交。

然而说出“就是几个字母的区别”这种话仅仅是表达了“我搞过服务端开发”这层意思而已。 实际上问题真正困难的地方在于,网络上每天产生的请求数目庞大,并且其中绝大部分请求均为只读请求,如果所有这些请求都要交由web服务器直接处理,这无疑是巨大的资源浪费。所以大家自然能想到,假如我们能在请求到达web服务器之前,就对请求作一个初步的解析,得知请求的大致意图,对于不同意图的请求以不同方式满足(比如请求经过nginx的时候nginx就会解析请求头信息,然后根据这些信息把请求分配给合适的角色去进一步处理),那么事情就合理多了。 于是RESTful的建议就在这个时候应运而生了,它的出现正是为了解决http基础设施未能得到充分合理利用的问题。

所以我们开发一个服务的时候,选择http协议(而不是直接用tcp),最根本的原因是,我们希望它可以直接和浏览器打交道,可以借用现有的http基础设施,它的行为能被除自己的客户端以外的,网络中的其它角色所理解。 (而不是仅仅靠http解决文本编码问题 这才是我们之所以强调get和post区别,强调“语义”的真正原因。

  • Cookies和session区别?

  1. Cookies是一种能够让网站服务器把少量数据储存到客户端的硬盘或内存,或是从客户端的硬盘读取数据的一种技术。Cookies是当你浏览某网站时,由Web服务器置于你硬盘上的一个非常小的文本文件,它可以记录你的用户ID、密码、浏览过的网页、停留的时间等信息。session: 当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,服务器将终止该会话。cookie机制:采用的是在客户端保持状态的方案,而session机制采用的是在服务端保持状态的方案。同时我们看到由于服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助cookie机制来达到保存标识的目的。

  2. Session是服务器用来跟踪用户的一种手段,每个Session都有一个唯一标识:session ID。当服务器创建了Session时,给客户端发送的响应报文包含了Set-cookie字段,其中有一个名为sid的键值对,这个键值Session ID。客户端收到后就把Cookie保存浏览器,并且之后发送的请求报表都包含SessionID。HTTP就是通过Session和Cookie这两个发送一起合作来实现跟踪用户状态,Session用于服务端,Cookie用于客户端

  • HTTP一次请求的响应结构组成以及过程?

客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成,HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。

一次完整的HTTP请求过程:

域名解析 --> 发起TCP的3次握手 --> 建立TCP连接后发起http请求 --> 服务器响应http请求,浏览器得到html代码 --> 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等) --> 浏览器对页面进行渲染呈现给用户(最后进行四次挥手断开

  • 讲一下长连接?

  在HTTP1.0和HTTP1.1协议中都有对长连接的支持。其中HTTP1.0需要在request中增加”Connection: keep-alive“ header才能够支持,而HTTP1.1默认支持.

  http是一种无状态的协议,也就是stateless协议,而http协议又是建立在tcp/ip协议的基础之上的。

       无状态表示每次请求都是一次独立的http事务,也就是发送http 请求(request)过去,然后web服务器或者application服务器进行响应,发送一个http response回来,这样就是结束了一次http事务。

     http建立在tcp/ip的基础之上,从而会遵循tcp协议的规则,在每次进行连接的时候,必须先进行三次握手,数据交换之后,进行四次断开。

       每次请求的时候,都要进行三次握手,四次断开,从性能上来说,满足不了大并发的需要,从而也就有了长连接,在进行请求的时候,不需要再次进行三次握手和四次断开,直接使用原来的连接进行传输数据。

       长连接能实现的前提就是,在同一个客户端进行多次的请求,如果不是同一客户端的话,那么还是需要进行三次握手和四次断开。每一个客户端在访问一个网页的时候,可能会发出几百个请求,请求各种web服务器的资源,例如图片,超链接,js和css等,请求过    后,浏览器将所有的对象组织在一个页面中,然后显示在客户端。

  • http1.0请求与服务端的交互过程:

  1. 客户端发出带有包含一个header:”Connection: keep-alive“的请求

  2. 服务端接收到这个请求后,根据http1.0和”Connection: keep-alive“判断出这是一个长连接,就会在response的header中也增加”Connection: keep-alive“,同是不会关闭已建立的tcp连接.

  3. 客户端收到服务端的response后,发现其中包含”Connection: keep-alive“,就认为是一个长连接,不关闭这个连接。并用该连接再发送request.转到a)

  • 讲一下三次握手与四次挥手?

三次握手:

第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

完成三次握手,客户端与服务器开始传送数据

四次挥手:

  1. 客户端先发送FIN,进入FIN_WAIT1状态

  2. 服务端收到FIN,发送ACK,进入CLOSE_WAIT状态,客户端收到这个ACK,进入FIN_WAIT2状态

  3. 服务端发送FIN,进入LAST_ACK状态

  4. 客户端收到FIN,发送ACK,进入TIME_WAIT状态,服务端收到ACK,进入CLOSE状态

TIME_WAIT的状态就是主动断开的一方(这里是客户端),发送完最后一次ACK之后进入的状态。并且持续时间还挺长的。客户端TIME_WAIT持续2倍MSL时长,在linux体系中大概是60s,转换成CLOSE状态

TIME_WAIT

TIME_WAIT 是主动关闭链接时形成的,等待2MSL时间,约4分钟。主要是防止最后一个ACK丢失。 由于TIME_WAIT 的时间会非常长,因此server端应尽量减少主动关闭连接

CLOSE_WAIT

CLOSE_WAIT是被动关闭连接是形成的。根据TCP状态机,服务器端收到客户端发送的FIN,则按照TCP实现发送ACK,因此进入CLOSE_WAIT状态。但如果服务器端不执行close(),就不能由CLOSE_WAIT迁移到LAST_ACK,则系统中会存在很多CLOSE_WAIT状态的连接。此时,可能是系统忙于处理读、写操作,而未将已收到FIN的连接,进行close。此时,recv/read已收到FIN的连接socket,会返回0。

为什么需要 TIME_WAIT 状态?

假设最终的ACK丢失,server将重发FIN,client必须维护TCP状态信息以便可以重发最终的ACK,否则会发送RST,结果server认为发生错误。TCP实现必须可靠地终止连接的两个方向(全双工关闭),client必须进入 TIME_WAIT 状态,因为client可能面 临重发最终ACK的情形。

为什么 TIME_WAIT 状态需要保持 2MSL 这么长的时间?

如果 TIME_WAIT 状态保持时间不足够长(比如小于2MSL),第一个连接就正常终止了。第二个拥有相同相关五元组的连接出现,而第一个连接的重复报文到达,干扰了第二个连接。TCP实现必须防止某个连接的重复报文在连接终止后出现,所以让TIME_WAIT状态保持时间足够长(2MSL),连接相应方向上的TCP报文要么完全响应完毕,要么被 丢弃。建立第二个连接的时候,不会混淆。

TIME_WAIT 和CLOSE_WAIT状态socket过多

如果服务器出了异常,百分之八九十都是下面两种情况:

1.服务器保持了大量TIME_WAIT状态

2.服务器保持了大量CLOSE_WAIT状态,简单来说CLOSE_WAIT数目过大是由于被动关闭连接处理不当导致的。

  • OSI七层协议

 

OSI是Open System Interconnection的缩写,意为开放式系统互联。国际标准化组织(ISO)制定了OSI模型,该模型定义了不同计算机互联的标准,是设计和描述计算机网络通信的基本框架。OSI模型把网络通信的工作分为7层,分别是物理层数据链路层、网络层、传输层会话层表示层应用层
这是一种事实上被TCP/IP 4层模型淘汰的协议。在当今世界上没有大规模使用。
TCP/IP模型实际上是OSI模型的一个浓缩版本,它只有四个层次:
1.应用层,对应着OSI的应用层、表示层、会话层
2.传输层,对应着OSI的传输层
3.网络层,对应着OSI的网络层
OSI模型的网络层同时支持面向连接和无连接的通信,但是传输层只支持面向连接的通信;TCP/IP模型的网络层只提供无连接的服务,但是传输层上同时提供两种通信模式。

TCP/IP与OSI最大的不同在于OSI是一个理论上的网络通信模型,而TCP/IP则是实际运行的网络协议。

  OSI七层模式简单通俗理解

这个模型推出的最开始,是是因为美国人有两台机器之间进行通信的需求。
需求1: 
科学家要解决的第一个问题是,两个硬件之间怎么通信。具体就是一台发些比特流,然后另一台能收到。 
于是,科学家发明了物理层: 
主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流(就是由1、0转化为电流强弱来进行传输,到达目的地后在转化为1、0,也就是我们常说的数模转换与模数转换)。这一层的数据叫做比特。 
需求2: 
现在通过电线我能发数据流了,但是,我还希望通过无线电波,通过其它介质来传输。然后我还要保证传输过去的比特流是正确的,要有纠错功能。  
于是,发明了数据链路层:
定义了如何让格式化数据以进行传输,以及如何让控制对物理介质的访问。这一层通常还提供错误检测和纠正,以确保数据的可靠传输。
需求3:
现在我能发正确的发比特流数据到另一台计算机了,但是当我发大量数据时候,可能需要好长时间,例如一个视频格式的,网络会中断好多次(事实上,即使有了物理层和数据链路层,网络还是经常中断,只是中断的时间是毫秒级别的)。
那么,我还须要保证传输大量文件时的准确性。于是,我要对发出去的数据进行封装。就像发快递一样,一个个地发。
于是,先发明了传输层(传输层在OSI模型中,是在网络层上面) 
例如TCP,是用于发大量数据的,我发了1万个包出去,另一台电脑就要告诉我是否接受到了1万个包,如果缺了3个包,就告诉我是第1001,234,8888个包丢了,那我再发一次。这样,就能保证对方把这个视频完整接收了。
例如UDP,是用于发送少量数据的。我发20个包出去,一般不会丢包,所以,我不管你收到多少个。在多人互动游戏,也经常用UDP协议,因为一般都是简单的信息,而且有广播的需求。如果用TCP,效率就很低,因为它会不停地告诉主机我收到了20个包,或者我收到了18个包,再发我两个!如果同时有1万台计算机都这样做,那么用TCP反而会降低效率,还不如用UDP,主机发出去就算了,丢几个包你就卡一下,算了,下次再发包你再更新。 
TCP协议是会绑定IP和端口的协议,下面会介绍IP协议。
需求4:
传输层只是解决了打包的问题。但是如果我有多台计算机,怎么找到我要发的那台?或者,A要给F发信息,中间要经过B,C,D,E,但是中间还有好多节点如K.J.Z.Y。我怎么选择最佳路径?这就是路由要做的事。
于是,发明了网络层。即路由器,交换价那些具有寻址功能的设备所实现的功能。这一层定义的是IP地址,通过IP地址寻址。所以产生了IP协议。  
需求5:
现在我们已经保证给正确的计算机,发送正确的封装过后的信息了。但是用户级别的体验好不好?难道我每次都要调用TCP去打包,然后调用IP协议去找路由,自己去发?当然不行,所以我们要建立一个自动收发包,自动寻址的功能。 
于是,发明了会话层。会话层的作用就是建立和管理应用程序之间的通信。
需求6:
现在我能保证应用程序自动收发包和寻址了。但是我要用Linux给window发包,两个系统语法不一致,就像安装包一样,exe是不能在linux下用的,shell在window下也是不能直接运行的。于是需要表示层(presentation),帮我们解决不同系统之间的通信语法问题。
需求7:
OK,现在所有必要条件都准备好了,我们可以写个android程序,web程序去实现需求把。
补充: 
Socket
这不是一个协议,而是一个通信模型。其实它最初是伯克利加州分校软件研究所,简称BSD发明的,主要用来一台电脑的两个进程间通信,然后把它用到了两台电脑的进程间通信。所以,可以把它简单理解为进程间通信,不是什么高级的东西。主要做的事情不就是:
A发包:发请求包给某个已经绑定的端口(所以我们经常会访问这样的地址182.13.15.16:1235,1235就是端口);收到B的允许;然后正式发送;发送完了,告诉B要断开链接;收到断开允许,马上断开,然后发送已经断开信息给B。
B收包:绑定端口和IP;然后在这个端口监听;接收到A的请求,发允许给A,并做好接收准备,主要就是清理缓存等待接收新数据;然后正式接收;接受到断开请求,允许断开;确认断开后,继续监听其它请求。
可见,Socket其实就是I/O操作。Socket并不仅限于网络通信。在网络通信中,它涵盖了网络层、传输层、会话层、表示层、应用层——其实这都不需要记,因为Socket通信时候用到了IP和端口,仅这两个就表明了它用到了网络层和传输层;而且它无视多台电脑通信的系统差别,所以它涉及了表示层;一般Socket都是基于一个应用程序的,所以会涉及到会话层和应用层。
  • TCP与UDP区别总结

1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付

Tcp通过校验和,重传控制,序号标识,滑动窗口、确认应答实现可靠传输。如丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。

3、UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高的通信或广播通信。

4.每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信

5、TCP对系统资源要求较多,UDP对系统资源要求较少。

为什么UDP有时比TCP更有优势?

UDP以其简单、传输快的优势,在越来越多场景下取代了TCP,如实时游戏。

(1)网速的提升给UDP的稳定性提供可靠网络保障,丢包率很低,如果使用应用层重传,能够确保传输的可靠性。

(2)TCP为了实现网络通信的可靠性,使用了复杂的拥塞控制算法,建立了繁琐的握手过程,由于TCP内置的系统协议栈中,极难对其进行改进。

采用TCP,一旦发生丢包,TCP会将后续的包缓存起来,等前面的包重传并接收到后再继续发送,延时会越来越大,基于UDP对实时性要求较为严格的情况下,采用自定义重传机制,能够把丢包产生的延迟降到最低,尽量减少网络问题对游戏性造成影响。

  • HTTPS和HTTP的区别?

  1. https协议需要到CA申请证书,一般免费证书很少,需要交费。

  2. http是超文本传输协议,信息是明文传输;https 则是具有安全性的ssl加密传输协 议。

  3. http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。

  4. http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

  5. http默认使用80端口,https默认使用443端口

  • https是如何保证数据传输的安全?

     https实际就是在TCP层与http层之间加入了SSL/TLS来为上层的安全保驾护航,主要用到对称加密、非对称加密、证书,等技术进行客户端与服务器的数据加密传输,最终达到保证整个通信的安全性。

  • SSL/TLS协议作用:

  1. 认证用户和服务器,确保数据发送到正确的客户机和服务器;

  2. 加密数据以防止数据中途被窃取;

  3. 维护数据的完整性,确保数据在传输过程中不被改变。

原文地址:https://www.cnblogs.com/king-brook/p/10026562.html