网络IO面试题
网络
TCP

是一个基于字节流的一个传输层的通信协议,在发送数据之前双方是需要建立一个连接的,这个所谓的连接就是双方都保存一个对方的ip地址还有端口等信息,然后TCP其实是一个字节流,头部就保存了这些信息,进行连接的时候有三个阶段:建立连接、传输数据、关闭连接,三次握手来建立,四次挥手来关闭,其中交换的报文都是tcp的头部。
三次握手
三次握手是一个在内核发生的一个行为,基于TCP协议,,首先呢,客户端应用启动以后,服务端进入listen状态,为了未来收到数据包做准备,然后在这个状态下内核进行了三次握手,
- 首先第一次是客户端向服务端发送带有SYN,代表发送连接的标识,的一个报文,自己进入一个SYN-SENT状态,然后服务器接收进入SYN-RECV状态
- 第二次是服务器发送带有SYN+ACK的报文,ACK是确认序号有效的标识,客户端接收进入established状态;
- 然后就是最后一次握手 因为服务端还需要知道自己发送和对方接收是否成功,所以客户端发送带有ACK标识的报文,服务端接收到才进入establised状态,以上三次握手就进行完毕

然后在这里以后应用要进行接收,就得将连接的socket放入accept队列,需要IO模型,调用server.accept() 如果队列里面有就取出来传到应用里,这里就有两种模型分别是阻塞等待返回的BIO和无阻塞轮询返回的NIO;还有一种模型是多路复用器,调用select,poll,epoll,但是它只是做一个和内核调用来知道队列里面是否有事件,然后再去有效性地进行一个accep()方法的调用
四次分手

客户端完成数据传输,要准备释放连接的时候:
进行第一次挥手,发一个带FIN(代表释放连接的标识)的报文给服务端然后进入FIN_WAIT1状态,服务接收到以后进入一个CLOSE-WAIT状态;
第二次挥手就是,服务器端向客户端发带ACK标识的报文,客户端接收后又进入FIN-WAIT状态,等待服务端将数据处理完毕收尾;
第三次服务端再去发送一个带FIN和ACK的报文,之前不一起发是因为服务端接收以后需要将数据发送进行完毕,在一个CLOSE-WAIT状态,搞定以后再发,客户端接收后进入TIME_WAIT状态;
然后就是第四次,客户端发送一个带ACK的报文给服务端,这里客户端的TIME-wait状态不能直接结束需要等待两倍报文寿命时间,再去closed,为什么是两倍报文寿命的时间是因为又肯呢个会出现服务器丢包的问题,但是服务端没接收到就会继续发送FIN,客户端要等待这么一个一去一回的时间来确认服务端没有再发送FIN,也就是确认服务端是否接收到,再去关闭,服务端接收到就会进入closed状态;
以上就是我了解的四次挥手过程。
与UDP的区别
udp 是用户数据协议,tcp是传输控制协议, 我就从这几个方面进行比较吧,首先一个是udp是无连接的,tcp是基于连接的, 第二个方面是他们的传输方式,udp 是报文, tcp是一个字节流,第三个是他们连接方式,udp是一对一一对多,多对多多对一的通信,而tcp只能是一对一,从这就可以看出第四方面他们的可靠性和安全性tcp明显是要高一些,也导致tcp首部要传输的信息很多,开销大,适用的场景就是文件传输,udp就可以在实时应用比如视频会议电话等场景用。
粘包
TCP协议是面向连接的可靠性协议。说它可靠并不表示数据信息一定会被对端接受,而是在传输失败后会放弃重传机制并中断连接来通知用户。它提供的只是数据可靠性的传输和故障通知。
TCP是数据流传输,数据流是只有起点和终点的字节数据序列,只有输入流和输出流。根本不存在“包”的概念。粘包的包是应用层的包,应用层协议规定了包的结构和大小,本质上就是一段数据报文。比如一段http请求,
1 | //http 请求 |
TCP粘包的原因
首先粘包的情况可能是recv-buffer这个缓冲区里有a包的一部分,或者a包和b包的一部分都有,原因从发送端来讲可能是send发送数据的时候因为还没收到接收端的ACK,就暂时将数据填充到缓冲区中等待,接收端方面就可能是因为处理数据不及时,数据都堆在缓冲区,致使ab包相连。
如何解决粘包呢?
- 固定包长度。每个包的大小都是一样的。
- 在包中给定包大小。例如:(固定前4个字节为包大小)
- 设置特定的结束标志。
1 | struct Message {undefined |
http协议就是使用了上述的2,3方法。http使用”\r\n”为结束标识。
当为post请求时则有content-Length标识请求体长度。
Connection refused
可能是一个网络问题,还有可能就是内核建立连接发给程序的时候,那个accept队列阻塞了。
因为是内核帮助建立连接,程序必须通过listen里面的accept接收队列来进行一个等待程序的接收,有一个大小限制的backlog,如果队列满了可能就会造成一个报错, 是内核和程序之间发生的一个卡。
Session , Cookie, Token

因为http协议本身是一个无状态也就是浏览器没办法判断用户身份,然后cookie提供了暂时保存用户信息的一个作用,它其实是一个服务器放在浏览器上面的一个key-value形式的一个小文件,如果服务器需要保存用户状态,就通过response给客户端颁发一个cookie,下次浏览器再请求的时候再将cookie提交,服务器检查来进行辨认。
而session呢,是域对象之一,是会话过程中服务器分的一块储存空间,但也是依赖着cookie实现的,浏览器会在cookie里面设置sessionid, 服务器根据sessionid取出session中存储的信息。
两者区别呢就是存储空间的限制,session是没有限制的,cookie是有限制的,然后就是存储的位置,cookie是在浏览器上,session是在服务器端,这样安全性也就可以看出来cookie的不高,另一方面占用资源 session也会更多更加降低性能。
而token呢,是因为客户端如果频繁向服务端请求数据,服务端频繁的去数据库查询会有很多压力,使用token呢,就会降低服务器压力,减少频繁访问数据库,增强健壮性,token是服务端产生的字符串,作为一个客户端请求的令牌,第一次登陆就生成给客户端,以后客户端就拿这个token来请求数据,不用用户名和密码。 和session的区别就是session存储在服务器端,而token是在浏览器端,并且还提供认证功能,安全性比session好,不会让服务器压力很大,适用于项目级的前后端分离项目,session只能在服务器和客户端在同一台机器的场景使用。
HTTP
常用HTTP状态码:
2XX | 成功(这系列表明请求被正常处理了) |
---|---|
200 | OK,表示从客户端发来的请求在服务器端被正确处理 |
204 | No content,表示请求成功,但响应报文不含实体的主体部分 |
206 | Partial Content ,进行范围请求成功 |
3XX | 重定向 (表明浏览器要执行特殊处理) |
301 | moved permanently,永久 性重定向,表示资源已被分配了新的 URL |
302 | found,临时性重定向,表示资源临时被分配了新的 URL |
303 | see other,表示资源存在着另一个 URL, 应使用 GET 方法获取资源 (对于 301/302/ 303响应,几乎所有浏览器都会删除报文主体并 自动用 GET重新请求) |
304 | not modified ,表示服务器允许访问资源,但请求未满足条件的情况(与重定向无关) |
307 | temporary redirect,临时重定 向,和302 含义类似,但是期望客户端保持请求方法不变向新的地址发出请求 |
4XX | 客户端错误 |
400 | bad request,请求报文存在语法错误 |
401 | unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息 |
403 | forbidden ,表示对请求资源的访问被服务器拒绝,可在实体主体部分返回原因描述 |
404 | not found,表示在服务器上没有找到请求的资源 |
5XX | 服务器错误 |
500 | internal sever error,表 示服务器端在执行请求时发生了错误 |
501 | Not Implemented,表示服务器不支持当前请求所需要的某个功能 |
503 | service unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求 |
HTTP1和HTTP2
HTTP2 可以提高了网页的性能。
在 HTTP1 中浏览器限制了同一个域名下的请求数量(Chrome 下一般是六
个),当在请求很多资源的时候,由于队头阻塞当浏览器达到 大请求数量时,剩余的资源需等待当前的六个请求完成后才能发起请求。
HTTP2 中引入了多路复用的技术,这个技术可以只通过一个 TCP 连接就可以传输所有的请求数据。多路复用可以绕过浏览器限制同一个域名下的请求数量的问题,进而提高了网页的性能。
HTTPS
HTTP 是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范
区别 | HTTP | HTTPS |
---|---|---|
协议 | 运行在 TCP 之上,明文传输,客户端与服务器端都无法验证对方的身份 | 身披 SSL( Secure Socket Layer )外壳的 HTTP,运行于 SSL 上,SSL 运行于 TCP 之 上, 是添加了加密和认证机制的 HTTP。 |
端口 | 80 | 443 |
资源消耗 | 较少 | 由于加解密处理,会消耗更 多的 CPU 和内存资源 |
开销 | 无需证书 | 需要证书,而证书一般需要向认证机构购买 |
加密机制 | 无 | 共享密钥加密和公开密钥加密并用的混合加密机制 |
安全性 | 弱 | 由于加密机制,安全性强 |
==get和post的区别==

- GET在浏览器回退时是无害的,而POST会再次提交请求。
- GET产生的URL地址可以被Bookmark,而POST不可以。
- GET请求会被浏览器主动cache,而POST不会,除非手动设置。
- GET请求只能进行url编码,而POST支持多种编码方式。
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
- GET请求在URL中传送的参数是有长度限制的,而POST则没有。对参数的数据类型GET只接受ASCII字符,而POST即可是字符也可是字节。
- GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
- GET参数通过URL传递,POST放在Request body中。