网络性能
谈网络我们最关注的是网络性能,而网络性能的两大指票是:带宽,延迟。(如下图)
带宽越大,并不意味着你的延迟越小。
延迟=发送时延+传播时延+处理时延+排队时延
通信方式
通信双方的分工和信号传输方向可将通信分为三种方式:
- 单工(Simplex)方式:通信双方设备中发送器与接收器分工明确,只能在由发送器向接收器的单一固定方向上传送数据。
- 半双工(Half Duplex)方式:通信双方设备既是发送器,也是接收器,两台设备可以相互传送数据,但某一时刻则只能向一个方向传送数据。
- 全双工(Full Duplex)方式:通信双方设备既是发送器,也是接收器,两台设备可以同时在两个方向上传送数据。
其中:局域网采用半双工方式,城域网和广域网采用全双工方式。
IP解决
众所周知我们现在用的是IPV4,而所能支持的机子数只有2^32,现在不够用。怎么解决?
1.DHCP,动态IP分配。
创建一个IP池,动态分配给正在上网的用户。
2.CIDR,无类别域间路由
网络有A,B,C三类网络,它们下面主机数量各不相同,可能造用IP浪费。CIDR则是把路由器具集起来,把网络号弱化
3.net技术。
在一个公有IP后面造一个私有网络。它完美解决了问题,但也触发了网络访问的问题。
公有IP访问不了私用IP,两私有IP之间的访问,而解决此问题的方法主要有2种
1.代理(服务器转发),代表nginx
2.打洞技术,代表花生壳
打洞技术
- A发送数据包到公网S,B发送数据包到公网S,则S分别得到了A和B的公网IP, S也和AB分别建立了会话。
- 由S发到NAT-A的数据包会被NAT-A直接转发给A,由S发到NAT-B的数据包会被NAT-B直接转发给B,除了S发出的数据包之外的则会被丢弃。 所以:现在A B 都能分别和S进行全双工通讯了,但是A B之间还不能直接通讯。
解决办法是:
- A向B的公网IP发送一个数据包,则NAT-A能接收来自NAT-B的数据包并转发给A了(即B现在能访问A了);
- 再由S命令B向A的公网IP发送一个数据包,则 NAT-B能接收来自NAT-A的数据包并转发给B了(即A现在能访问B了)。
TCP和UDP在打洞上却有点不同。这是因为伯克利socket(标准socket规范)的 API造成的。
- AB要连接到S,肯定首先AB双方都会在本地创建一个socket,去连接S上的socket。
- 创建一个socket必然会绑定一个本地端口(就算应用程序里面没写端口,实际上也是绑定了的,至少java确实如此)
- 假设为8888,这样A和B才分别建立了到 S的通信信道。
- 接下来就需要打洞了,打洞则需要A和B分别发送数据包到对方的公网IP。
- 但是问题就在这里:因为NAT设备是根据端口号来确定session,如果是UDP的socket,AB可以分别再创建socket,然后将socket绑定到8888,这样打洞就成功了。但是如果是TCP的 socket,则不能再创建socket并绑定到8888了,这样打洞就无法成功。
socket长连接、短连接以及心跳包机制
所谓长连接,指在一个TCP连接上可以连续发送多个数据包,在TCP连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接,一般需要自己做在线维持。
短连接是指通信双方有数据交互时,就建立一个TCP连接,数据发送完成后,则断开此TCP连接,一般银行都使用短连接。
总结:长连接和短连接的区别就是 一个close的关系。
心跳包机制的作用:
- 内网机器如果不主动向外发起连接,外网机没法直连内网的,这也是内网机安全的原因之一吧,又因为路由器会把这个关系记录下来,但是过一段时间这个记录可能会丢失 ,所有每一个客户端每隔一定时间就会向服务器发送消息,以保证服务器可以随时找到你,这东西被称为心跳包
- 理论上说,这个连接是一直保持连接的,但是实际情况中,如果中间节点出现什么故障是难以知道的。更要命的是,有的节点(防火墙)会自动把一定时间之内没有数据交互的连接给断掉。在这个时候,就需要我们的心跳包了,用于维持长连接,保活。在获知了断线之后,服务器逻辑可能需要做一些事情,比如断线后的数据清理呀,重新连接呀
- 如果不主动关闭socket的话,系统不会自动关闭的,除非当前进程挂掉了,操作系统把占用的socket回收了才会关闭。为什么需要心跳连接主要是判断当前连接是否是有效的、可被使用的。每个socket连接都是长连接,它是一个相当占用系统资源的通信管道, 如果这个长连接什么事也没干硬是要占着资源,则server端可以选择关闭这个连接,以省下资源让更多的用户连接进来。