作为一个程序员需要了解多少网络方面的基础?网络基础总结(不断更新)

Java鱼仔
听说微信搜索《Java鱼仔》会变更强哦!

本文收录于JavaStarter,里面有我完整的Java系列文章,面试前看一看不香吗?

面试过程中经常会被问到计算机网络相关的知识,就打算写一篇博客不断总结一些计算机网络的基础点以及面试中常问的考点。如果文档中存在错误欢迎指出,有任何补充留言私信均可以,我会不定期的添加上去。话不多说,直接进入主题:

1.OSI网络体系结构和TCP/IP协议结构

OSI网络体系结构分为七层:

从下到上分为:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层

TCP/IP协议结构分为四层:

从下到上分为:网络接口层、网际层、传输层、应用层

网络接口层对应于OSI的物理层和数据链路层,应用层对应于OSI的会话层、表示层、应用层。

2.HTTP和HTTPS协议

Http协议运行在TCP之上,明文传输,客户端与服务器端都无法验证对方的身份;Https是身披SSL(Secure Socket Layer)外壳的Http,运行于SSL上,SSL运行于TCP之上,是添加了加密和认证机制的HTTP。二者之间存在如下不同:

端口不同:Http与Http使用不同的连接方式,用的端口也不一样,前者是80,后者是443;

资源消耗:和HTTP通信相比,Https通信会由于加减密处理消耗更多的CPU和内存资源;

开销:Https通信需要证书,而证书一般需要向认证机构购买; 

Https的加密机制是一种共享密钥加密和公开密钥加密并用的混合加密机制。

HTTP协议格式

http请求协议部分数据

GET /user HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9

<html>...

第一部分:请求行:请求类型,资源路径以及http版本(上述第一行)

第二部分:请求头:紧接在请求行之后,用于说明服务器需要使用的附加信息(第二到第八行)

第三部分:空行(请求头和主体之间必须有换行)

第四部分:主体数据,可以添加任意数据

http响应协议

HTTP/1.1 200
Content-Type:text/html

OK

第一部分:状态行,http版本,状态码,状态信息(第一行)

第二部分:响应报文头部,说明服务器需要用到的附加信息(第二行)

第三部分:空行(第三行)

第四部分:响应正文(第四行)

3.TCP协议和UDP协议

TCP是传输层协议,TCP提供了数据的可靠连接,通过面向连接、端到端和可靠的字节流服务。

UDP是传输层协议,UDP在数据传输前不会建立连接,不能保证数据连接的可靠性,传输速度快。

4.TCP协议的三次握手和四次挥手

三次握手

第一次握手:建立连接时,客户端发送syn包(seq=x)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。

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

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=x+1),此包发送完毕,客户端和服务器进入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连接的时间要比客户端早一些。

4.1 为什么连接的时候是三次握手,关闭的时候却是4次挥手

因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

4.2为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可能最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

4.3为什么要用三次握手而不是两次或四次

3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。

现在把三次握手改成仅需要两次握手,当第二次握手后(即服务器发送给客户端)的请求客户端没收到时,服务器会认为已经建立了连接,开始发送数据,但是客户端没收到连接请求,会认为连接未建立,继续发送连接信息。这时就导致了死锁。

至于为什么不改成四次,当三次连接后,服务器和客户机都能确定之前的通信情况,但是无法确认之后的情况,可靠的通信协议是根本不存在的,因此再增加一次也是徒劳。

4.4 如果已经建立了连接,但是客户端突然出现故障了怎么办?

TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

5.常见的网络协议有哪些?

网络层

IP协议:网际协议

ICMP协议:Internet控制报文协议

ARP协议:地址解析协议

RARP协议:逆地址解析协议

传输层

UDP协议:用户数据报协议

TCP协议:传输控制协议

应用层

FTP:文件传送协议

Telenet:远程登录协议

DNS:域名解析协议

POP3:邮局协议

HTTP协议:超文本传输协议

SMTP:简单邮件传送协议

SNMP:简单网络管理协议

TFTP:简单文件传送协议

6.常见的网络攻击方式?以及预防措施

6.1 DDoS

DDoS攻击

DDoS全称Distributed Denial of Service,中文意思为“分布式拒绝服务”,就是利用大量合法的分布式服务器对目标发送请求,从而导致正常合法用户无法获得服务。

常见的攻击方式如TCP攻击:

客户端向服务端发送请求链接数据包

服务端向客户端发送确认数据包

客户端不向服务端发送确认数据包,服务器一直等待来自客户端的确认

DDoS预防

限制同时打开SYN半链接的数目

缩短SYN半链接的Time out 时间

关闭不必要的服务

6.2 SQL注入

SQL注入

攻击者不是将标准数据提交到文本框或其他数据输入字段,而是输入SQL语句来诱骗应用程序显示或操纵其数据。

SQL注入预防措施

不要使用动态SQL

不要将敏感数据保留在纯文本中。

限制数据库权限和特权

避免直接向用户显示数据库错误

对访问数据库的Web应用程序使用Web应用程序防火墙(WAF)

定期测试与数据库交互的Web应用程序

将数据库更新为最新的可用修补程序

6.3 XSS攻击

XSS 攻击

XSS 攻击,即跨站脚本攻击(Cross Site Scripting),它是 web 程序中常见的漏洞。  攻击者破坏易受攻击的网站或Web应用程序并注入恶意代码。当页面加载时,代码在用户的浏览器上执行恶意脚本。

XSS预防

web 页面用户输入的地方,对输入的数据转义、过滤处理。后台输出页面的时候,也需要对输出内容进行转义、过滤处理(因为攻击者可能通过其他方式把恶意脚本写入数据库)

前端对 html 标签属性、css 属性赋值的地方进行校验

6.4 CSRF攻击

CSRF 攻击

跨站请求伪造(英语:Cross-site request forgery),是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。

CSRF预防

检查Referer字段

HTTP头中有一个Referer字段,这个字段用以标明请求来源于哪个地址。在处理敏感数据请求时,通常来说,Referer字段应和请求的地址位于同一域名下。以上文银行操作为例,Referer字段地址通常应该是转账按钮所在的网页地址,应该也位于www.examplebank.com之下。而如果是CSRF攻击传来的请求,Referer字段会是包含恶意网址的地址,不会位于www.examplebank.com之下,这时候服务器就能识别出恶意的访问。

添加校验token

由于CSRF的本质在于攻击者欺骗用户去访问自己设置的地址,所以如果要求在访问敏感数据请求时,要求用户浏览器提供不保存在cookie中,并且攻击者无法伪造的数据作为校验,那么攻击者就无法再运行CSRF攻击。这种数据通常是窗体中的一个数据项。服务器将其生成并附加在窗体中,其内容是一个伪随机数。当客户端通过窗体提交请求时,这个伪随机数也一并提交上去以供校验。正常的访问时,客户端浏览器能够正确得到并传回这个伪随机数,而通过CSRF传来的欺骗性攻击中,攻击者无从事先得知这个伪随机数的值,服务端就会因为校验token的值为空或者错误,拒绝这个可疑请求。

7.TCP协议的粘包问题

TCP 是面向连接的,面向流的可靠协议;发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包。这样,接收端,就难于分辨出来了,就会出现所谓的粘包问题。

产生粘包的原因:

(1)发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据了很小,会合到一起,产生粘包)

(2)接收方不及时接收缓冲区的包,造成多个包接收(客户端发送了一段数据,服务端只收了一小部分,服务端下次再收的时候还是从缓冲区拿上次遗留的数据,产生粘包)

粘包的解决方案:

(1)定长发送

在进行数据发送的时候采用固定长度的设计,无论多大的数据包都分成固定的长度进行发送,这种方式的弊端在于,最后一个包的长度往往会被填充为空格,接收方可能无法辨别无效部分。

(2)设置尾部的标记

在一个包结束的位置增加一个特殊的标记,当接收方读取到这个标记后就说明数据包读取完毕,这种方式的弊端在于取什么样的数据作为标志位是一件很难找到恰当答案的事情。

(3)在头部增加标记标明数据包长度

在头部标记一个长度,读取时先读取这个长度再接受数据,这样就不用担心数据包丢失的问题。

阅读 139
1 声望
1 粉丝
0 条评论
你知道吗?

1 声望
1 粉丝
宣传栏