文章目录
- tcp粘包问题?
- BIO,NIO,AIO是什么?
- 零拷贝是什么?
- 浏览器发出一个请求到收到响应的具体步骤?
- select, poll, epoll区别是什么?
- https是如何保证安全传输的?
- tcp的三次握手和四次挥手:
- tcp网络分层:
- 网络分层的好处:
- tcp三次握手为什么3次, 为什么不是2次或者4次?
- tcp的四次挥手为啥必须是4次?
- 为什么syn/fin不包含数据却要消耗一个序列号?
- tcp流量控制机制
- tcp中keep-alive原理。
- tcp中的端口号?
- telnet主要用法:
- netstat用法:
- tcpdump的用法
- tcp和udp区别:
- 慢开始、拥塞避免、快重传、快恢复
tcp粘包问题?
tcp接收端收到了几个数据包结合在一起的包,
这个协议本身是以流的形式来传送,
tcp实际上没有粘包问题,
解决方案:
1.使用标准的应用层协议。
2.尾部添加特殊字符
3.在发送数据块之前,添加包头。
tcp中的分包、粘包问题。
原因是发送数据太快, 或者接收数据太慢,
导致服务接收端直接打印,
加上字符串长度,然后读取指定数据字符串。
BIO,NIO,AIO是什么?
BIO: 同步阻塞io, 使用BIO读取数据时候, 线程会阻塞住, 并且需要线程主动查询是否有数据可读,
并且需要处理完一个Socket之后才能处理下一个socket.
NIO:同步非阻塞IO, 使用NIO读取数据的时候, 线程不会阻塞, 但需要线程主动去查询是否有IO事件。
AIO:异步非阻塞IO, 使用AIO读取数据的时候, 线程不会阻塞, 并且当有数据可读时候, 会通知给线程, 不需要线程主动去查询。
零拷贝是什么?
原来是需要走 内核中read buffer -> 应用程序的buffer -> 内核中socket buffer -> 网卡buffer
==> 优化后, 不需要应用程序从中间来交换
read buffer -> 使用transferTo()调用 -> 内核中socket buffer -> 网卡buffer
少了2次拷贝动作。
浏览器发出一个请求到收到响应的具体步骤?
1.浏览器解析用户输入的url, 生成一个http格式请求
2.根据url域名从本地host文件中查找是否有映射ip, 如果没有就将域名发送给电脑所配置的DNS进行域名解析,
得到ip地址
3.浏览器通过操作系统将请求通过四层网络协议发出。
4.途中经过各种路由器、交换机、最终到达服务器
5.服务器收到请求后, 根据请求所指定的端口, 找到对应应用程序,
6.收到数据后, 按照http格式进行解析, 得到所有访问的接口
7.处理业务逻辑,
8.处理好后封装http响应内容, 再次通过网络返回请求客户端
9.浏览器所在服务器拿到结果, 传递到浏览器, 解析并且渲染。
select, poll, epoll区别是什么?
select模型, 使用的数组来存储socket连接文件描述符, 容量是固定的, 需要通过轮询来判断是否发生了IO事件
poll模型, 使用的是链表来存储socket连接文件描述符, 容量是不固定的, 同样需要通过轮询来判断是否发生了IO事件
epoll模型, epoll是一个事件通知模型, 当发生了IO事件时, 应用程序才进行IO操作, 不需要像poll模型那样去轮询。
https是如何保证安全传输的?
https通过使用对称加密、非对称加密、数字证书等方式来保证数据安全传输。
1.客户端向服务器发送数据之前, 需要先建立tcp连接, 所以先建立tcp连接, 建立完tcp连接后, 服务端会先给客户端发送公钥, 客户端拿到公钥后就可以用来加密数据了,
服务端到时候接收到数据, 就可以用私钥解密数据, 这种就是通过非对称加密来传输数据。
2.不过非对称加密对比对称加密要慢, 所以不能直接使用非对称加密来传输请求数据, 所以可以通过非对称加密的方式来传输对称加密的密钥, 之后就可以使用对称加密来传输请求数据了。
3.但是仅仅通过非对称加密+对称加密不足以能够保证数据传输的绝对安全, 因为服务端向客户端发送公钥时,可能会被截取。
4.所以为了安全的传输公钥, 需要用到数字证书, 数字证书是具有公信力、大家都认可的, 服务端向客户端发送公钥时, 可以把公钥和服务端相关信息通过hash算法生成消息摘要, 再通过数字证书
提供的私钥对消息进行加密生成数字签名, 再把没进行hash算法之前的信息和数字签名一起形成数字证书, 最后把数字证书发送给客户端, 客户端收到数字证书后, 就会通过数字证书提供的公钥来解密
数字证书, 从而得到非对加密要用的公钥。
5.这个过程中, 就算有中间人拦截到服务器端发出来的数字证书, 虽然它可以解密得到非对称加密要用到的公钥, 但是中间人是没办法伪造数字证书发给客户端的, 因为客户端上内嵌的数字证书是全球
公信力的, 某个网站如果想支持https, 都是需要申请数字证书的私钥的, 中间人如果要生成能被客户端解析的数字证书, 也要申请私钥, 所以比较安全。
tcp的三次握手和四次挥手:
建立tcp:
1.客户端向服务端发送一个
SYN
2.服务端接收到syn后, 给客户端一个sync_ack
3.客户端收到syn-ack后, 给服务端再发一个ack
断开时候:
1.客户端发送fin
2.服务端收到后, 发送ack, 表示我收到了断开请求, 不过服务端可能还有数据正在处理
3.服务端处理完数据后, 向客户端发送fin, 表示服务端现在可以断开连接
4.客户端收到服务端fin, 向服务端发送ack, 表示客户端也断开连接了。
tcp网络分层:
传输层: 提供端口对端口的服务。8080(Tcp协议) , 加上tcp报文头
网络层: 加上IP报文头, ip地址, 从地址到地址
网络链路层: 以太网报文头, mac地址,
物理层: 比特流
网络分层的好处:
1.各层独立, 不需要知道上下层如何工作, 增加或者修改不会影响传输层协议
2.灵活性更好, 比如路由器不需要知道应用层和传输层, 分层后路由器就可以
只用加载更少的几个协议层
3.易于测试和维护, 提高可测试性, 可以独立的测试特定层, 某一层
有了更好的实现可以整体替换掉
4. 促进标准化, 每层职责清晰, 方便进行标准化。
tcp三次握手为什么3次, 为什么不是2次或者4次?
tcp是面向连接的传输, 所以需要2端都做好准备,即面向双方的。
如果只有2次, server端就可能单方面认为连接建立,
造成server端连接资源的浪费。
四次浪费报文资源。
tcp的四次挥手为啥必须是4次?
如果优化成3次, 那么server端可能某些资源可能没释放,
中间可能有比较大的延时或者时差,
等太长时间超过超时时间后, 还会造成消息重发,
造成资源浪费。
这样才能达到效率最高。
为什么syn/fin不包含数据却要消耗一个序列号?
凡是对端确认的, 一定消耗tcp报文序列号。
tcp流量控制机制
对于发送端和接收端而言, tcp需要把发送的数据发送到
发送缓冲区, 将接收到的数据放到接收缓冲区。
流量控制就是通过接收缓冲区大小,控制发送端的发送。
如果对方接受缓冲区满了, 就不再发送。
为了控制发送端速率, 接收端会告知客户端自己的接收窗口,
也就是接收缓冲区的空闲部分。
ack确认的时候, 会带有窗口的大小。
滑动窗口限流。
tcp中keep-alive原理。
通过定时发送探测包来探测连接的对端是否存活,
不过默认情况下是7200秒, 没有数据包交互才会发送
keep-alive探测包, 往往这个时间太久了, 我们熟知的很多组件都没有开启keep-alive特性 ,而是选择在应用层做心跳机制。
tcp中的端口号?
端口号在传输层tcp报文头中。, 一台主机最大允许65536个端口号。
熟知端口号: 0-1023
http:80
https: 443
ssh:22
已登记端口号:
mysql:3306
redis:6379
mongodb:27017
telnet主要用法:
telnet最大作用是检查一个端口是否处于打开,
telnet ip port 这条命令可以告诉我们远端server指定端口的网络连接是否科大。
netstat用法:
netstat 主要用于显示各种网络相关信息:
-a:显示所有选项, 默认不显示Listen相关
-t(tcp): 仅仅显示tcp相关
-u(udp):仅仅显示udp相关选项
-n 拒绝显示别名, 能显示数字的全部转为数字
-l :列出在listen的服务状态
-p: 显示建立相关链接的程序名
-r: 显示路由信息, 路由表
tcpdump的用法
tcpdump是一个抓包工具, 是一个网络流量抓包工具,
一般用来抓tcp的包。
tcpdump -i any 抓取任意端口的包。
sudo tcpdump -i any host 112.80.248.76
tcpdump -i any host www.baidu.com
tcp和udp区别:
tcp是面向连接的, 可靠的, 基于字节流的传输层协议
udp是面向无连接的传输层协议。
面向连接指的是客户端和服务器端的链接, 在双方互相通信之前
tcp需要建立3次握手, 而udp没有建立连接的过程。
可靠性:tcp花了很多保证连接可靠,
1.tcp有状态, tcp会精确记录那些数据发送了, 那些没有,
哪些被对方接受了, 哪些没有被接收到, 而且保证数据包
按序到达, 不允许半点出错。
2.tcp可控制, 意识到包丢了或者网络环境差, tcp会根据
具体情况调整自己的行为, 控制自己发送的速度或者重发。
慢开始、拥塞避免、快重传、快恢复
慢开始
最开始从0开始, 拥塞窗口默认是最小为1.
每收到一次确认, 原来的拥塞窗口+1, 直接翻倍。
慢开始指的是最初注入到网络中的报文段数量。
指数级增加方式。
拥塞避免:
ssthresh: 慢开始门限值,
根据当前网络拥塞程度估算当前阈值, 一般是根据往返时延。
估算一个临街值, 调整窗口大小,
原来拥塞值到达之前, 指数增加, 到达之后, 采用线性增加。
到达网络拥塞之前这段线性增加的过程就是拥塞避免算法, 是线性增加的。
当到达实际网络拥塞的时候(出现超时了),
ssthrsh的值降为拥塞的窗口大小的一半。
发送窗口调整为最小值1开始。
快重传:
收到3个重复的ack确认报文, 执行快重传算法, 可能报文丢失。
不用等待超时, 然后提前执行重传的过程。
快恢复:
慢开始门限起点直接定位拥塞的上限的一半, 然后线性增大。
跳过了从1恢复的过程。
生产环境中, 上面4种情况都可能会用到。