网络(1)

DHCP动态主机配置协议

所有的Internet协议都做了这样一个假设,即主机配置了一些基本信息,比如IP地址。主机如何获得此信息?手动设置是可以的,但太麻烦,因此有了DHCP,即自动给主机配置IP地址、网络掩码等信息。
DHCP如何实现分配IP?
首先每个网络必须有一个DHCP服务器
计算机启动时,在自己的网络上广播一个报文,请求IP地址
这个请求就是DHCP DISCOVER包,这个包必须到达DHCP服务器
DHCP收到请求了就给主机分配一个IP地址,并通过DHCP OFFER包返回给主机
为了在主机没有IP地址的情况下完成此项工作,服务器用主机的以太网地址来标识这台主机
防止IP地址过期
为了避免主机离开网络,并没有把IP地址返回给DHCP服务器,因此DHCP服务器在分配IP地址的时候都会指定一个有效期。在有效期满之前,主机必须请求续订。
DHCP数据包格式及其原理
DHCP可为主机配置除了IP地址以外的其他各种参数,比如网络掩码、默认网关的IP地址,DNS服务器和时间服务器的IP地址。

五层因特网协议栈

两个节点物理线路、传输介质是物理层。
在数据链路层中传递数据包,并进行校验,DHCP协议是数据链路层的。
节点和节点之间可以用数据链路层,但传递给其他学校或者国家,这就不是两个节点之间的传输了,就需要网络层。网络层会有路由,包发给路由器,路由器再发给路由器,转转转,通过IP协议,每个节点都有IP地址,最终传到目标节点。网络层还包括ICMP和IGMP协议。ICMP是IP协议的附属协议。IP层用它来与其他主机或路由器交换错误报文和其他重要信息。IGMP是Internet组管理协议。它用来把一个UDP数据报多播到多个主机。网络层还有ARP协议(地址解析协议),作用是将IP地址映射到数据链路层的以太网地址(mac地址),因为网卡只认以太网地址(mac地址)。
虽然在数据链路层进行了校验,但并不可靠,需要出错重传,就有了传输层。在传输层有TCP/UDP协议。TCP协议是基于连接的,UDP无连接。
数据是为哪个应用服务呢?是HTTP还是FTP还是SMTP、POP3、DNS、AMQP AMQP协议 因此需要有应用层。
FTP、Telnet、SMTP、HTTP、POP3是基于TCP的;DNS、SNMP、RIP是基于UDP的。
socket只是对TCP/IP协议栈操作的抽象,即socket是TCP/IP协议的API

OSI七层模型

UDP/TCP区别
1. TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
2. TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
3. TCP实时性比UDP差,UDP更适用于对高速传输和实时性有较高的通信(比如LOL这种实时对战网络游戏)或广播通信。
4. 每一条TCP连接只能是点到点的,即TCP不支持组播或者广播传输模式。UDP支持一对一,一对多,多对一和多对多的交互通信。
TCP对系统资源要求较多,UDP对系统资源要求较少。
为什么UDP在越来越多的场景下取代了TCP?
• UDP以其简单、传输快的优势,在越来越多场景下取代了TCP,不能容忍延迟比如LOL、Dota用UDP,可以容忍延迟的游戏如RPG还是用TCP。
• 网速的提升给UDP的稳定性提供可靠网络保障,丢包率很低,如果使用应用层重传,能够确保传输的可靠性。
• 网络游戏如果采用TCP,一旦发生丢包,TCP会将后续的包缓存起来,等前面的包重传并接收到后再继续发送,延时会越来越大,基于UDP对实时性要求较为严格的情况下,采用自定义重传机制,能够把丢包产生的延迟降到最低,尽量减少网络问题对游戏性造成影响。

设计UDP丢包检查来保证可靠性
1. 可以采用一个近似TCP的ack机制,可以给每个数据包都添加一个sequence ID,然后服务端就依次发送数据包,客户端收到数据包后就可以根据sequence ID来判断是否有丢包了。
2. 接下来是重点,客户端需要发该sequenceID的ack给服务端,服务端才会知道这个包是否已经送达。但这是一笔不小的开销,而且,ack本身也有可能丢包。
3. 可以这样,客户端发送一个sequence ID的ack时,附加一个32bit的位序列,表示当前sequence ID之前的32个连续顺位的数据包是否已经送达,其实就是冗余的发送连续32个包的送达状态,如果bit为0说明这个包还没到,如果为1,说明已经收到了。这样一来,除非连续丢包30多次,ack是一定会送到的,这种几率已经非常小了。
4. 相应的,在服务端设置一个超时机制,这个时间差不多比连续发30个ack的时间长一点,如果发送一个包后开始计时,达到超时还没有收到ack,这个包就丢失了。
5. 但即使丢包了也不一定需要重发!是否需要重发,如何重发可以和游戏的逻辑结合起来,没有必要实现类似TCP那样的完全可靠的机制,毕竟战斗中的同步速率很高,丢一个一般也没啥事情。


TCP如何保证可靠
一句话解释:
Tcp通过校验和,重传控制,序号标识,滑动窗口、确认应答实现可靠传输。如丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。
详细解释:
1. 数据被分割成TCP认为最合适的数据块
2. 包是按序收到的,即发送顺序和接受顺序一致。
3. TCP发送一个段之后会启动一个定时器,等待目标端的确认信息,如果没有收到确认信息,会重发
4. 防止序号回绕机制。即在连接期间,时间戳被用来辅助扩展32位序号,而且采用了伪随机的初始序号,防止重复数据包。
5. TCP保证收到的包不出错,即保持首部和数据的校验和,如果收到的校验和出错,TCP将丢弃这个数据报也不会确认这个数据报
6. TCP会对收到的数据进行重新排序,保证数据以正确的顺序交给应用层
7. TCP还有流量控制和拥塞控制
滑动窗口协议也是来保证可靠的

三次握手

TCP使用了三次握手法来建立连接。
为什么是三次握手、四次挥手?而不是五次六次
首先讲这个思想1、网络是不可靠的,任何包都有可能丢。2、遇见问题,解决问题,不断迭代。3、因此网络协议能用就好。然后回答具体流程

、某一端,比如服务器必须先依次执行LISTEN和ACCEPT原语,然后被动的等待入境连接请求。
2、另一端,比如说客户,执行CONNECT原语,同时说明它希望连接的IP地址、端口等参数。CONNECT原语发送一个SYN标志位置为ON和ACK标志位置为OFF的TCP段,进入SYN_SENT状态,然后等待服务器响应。
3、当这个TCP段到达接收方时,接收方的TCP实体检查是否有一个进程已经在目标端口上执行了LISTEN。如果没有,则它发送一个设置了RST的应答报文,拒绝客户的连接请求。
4、如果是LISTEN,那么TCP实体将入境的TCP段交给该进程处理,进程可以接受或者拒绝这个连接请求。如果接受,则进入SYN_RECEIVED状态,并发送回一个确认段。
5、正常情况下,发送的TCP段顺序如下
    ⑴第一次握手,客户发送SYN=x到服务器
    ⑵第二次握手,服务器确认后,进入SYN_RECEIVED状态并发送SYN=y,ACK=x+1到客户
    ⑶第三次握手,客户确认后,进入ESTABLISHED状态,发送SYN=x+1,ACK=y+1到服务器,此包发送完毕,服务器收到后进入ESTABLISHED状态。客户端和服务器TCP连接成功,完成三次握手,开始传送数据。如果这里服务器没收到,客户进入ESTABLISHED状态后也会自认为连接完成,开始发送数据,不过发数据一直没有响应,最后会超时断开连接。
⑷客户不知道服务器是否收到了它的SYN=x+1,如此下去是个死循环,因此够用就好。这里可以看视频7分钟
TCP连接如何释放?
0、简称四次挥手
1、虽然TCP连接是全双工的,这里我们把TCP看成单工的。
2、为了释放一个连接,任何一方(比如A)都可以发送一个设置了FIN标志位的TCP段,这表示它已经没有数据要发送了。当FIN被另一方(比如B)确认后,这个方向(A到B)的连接就被关闭。
3、另一方向上或许还继续传着数据流。当两个方向都关闭后,连接才算彻底关闭。
4、为了避免“两军对垒”问题,需要使用计时器,如果两倍最大数据包生存期内,针对FIN的响应没有出现(A发了FIN,A没有收到B的FIN响应),那么FIN发送端(A)会直接释放连接。另一方最终会发现没人监听,超时后也会释放连接。
5、四次握手具体如下:
6、注意这个TIME_WAIT,因为最后接收方不会发送ACK回来了,因此发起方会进入TIME_WAIT状态等待一段时间,如果没啥变化,再进入CLOSED关闭状态。

断开为什么是四次握手?
因为A到B断开了,B也许还有数据没有发送完,B到A这方向不能立刻断,因此设计上和三次握手有区别。再讲四次握手流程

服务器出现异常?
如果服务器出现异常,百分之***十都是下面两种情况:
    1. 服务器保持了大量TIME_WAIT状态
    2. 服务器保持了大量CLOSE_WAIT状态
因为linux分配给一个用户的文件句柄是有限的,而TIME_WAIT和CLOSE_WAIT两种状态如果一直被保持,那么意味着对应数目的通道就一直被占着,而且是“占着茅坑不使劲”,一旦达到句柄数上限,新的请求就无法被处理了,接着就是大量Too Many Open Files异常,tomcat崩溃。。。

服务器大量CLOSE_WAIT状态的原因??
    • CLOSE_WAIT产生的原因在于:TCP Server 已经ACK了过来的FIN数据包,但是上层应用程序迟迟没有发命令关闭Server到client 端的连接。所以TCP一直在那等啊等.....
    • 所以说如果发现自己的服务器保持了大量的CLOSE_WAIT,问题的根源十有***是自己的server端程序代码的问题。

服务器大量TIME_WAIT状态原因??
    • 服务器处理大量连接并主动关闭连接时,将导致服务器端存在大量的处于TIME_WAIT状态的socket。
    • 因为主动关闭方会进入TIME_WAIT的状态,然后在保持这个状态2MSL(max segment lifetime)时间(1到4分钟)之后,彻底关闭回收资源(被占用的是一个五元组:(协议,本地IP,本地端口,远程IP,远程端口)。对于 Web 服务器,协议是 TCP,本地 IP 通常也只有一个,本地端口默认的 80 或者 443。只剩下远程 IP 和远程端口可以变了。如果远程 IP 是相同的话,就只有远程端口可以变了。这个只有几万个)。
    • 所以如果大量关闭,资源还没来得及回收,会导致大量TIME_WAIT。
    • 解决方案是修改linux内核,允许将TIME-WAIT sockets重新用于新的TCP连接,并开启TCP连接中TIME-WAIT sockets的快速回收,这些默认都是关闭的。

遇到的一个TIME_WATI\CLOSE_WAIT实例
事件经过:
    7月份我们上线了一个改动,这个改动会产生慢查询,增加数据库压力。大量的慢查询导致后台处理系统不能及时处理峰值请求,请求数据严重重发,如此恶性循环最终导致系统崩溃,服务中有大量TIME_WAIT状态和大量CLOSE_WAIT状态,当时线程池的数量为20,使用线程数为20,等待线程数为1000。
原因分析:
    1. 服务端阻塞在数据库访问上,因此服务端无法处理请求,客户端超时发起关闭TCP,服务端这边因为处理请求的线程还阻塞在数据库,没有发起服务端到客户端的关闭,因此服务端这边积累了大量CLOSE_WAIT状态。
    2. 服务发起方(客户端服务器),因为数据库阻塞了,所以服务发起方的请求大量超时,大量关闭,请求资源还没来得及回收(1到4分钟才能回收完),因此服务发起方这边就会积累大量TIME_WAIT。
为什么会慢查询呢?

    比如数据库配置的连接数只有10,实际要连接的数目>配置的连接数时,就会导致实例不能连接数据库,导致数据库慢查询。在评估数据库连接数的时候,需要把程序并发数考虑进去。
改进措施
    1. 请求优化,如果存在请求积压时主动放弃请求
    2. 检查SQL,对潜在问题进行优化
    3. 服务增加只访问缓存的紧急预案,保证数据库出现问题时能够灵活切换,减少服务损失同时减少数据库请求防止雪崩发生




TCP协议要达成什么目的?
要实现可靠的传输,什么叫可靠的传输呢?1、包是按序收到的,即发送顺序和接受顺序一致。2、保证收到的包不出错。3、流量控制和拥塞控制

TCP计时器管理
1、TCP有三个计时器,分别是持续计时器、保活计时器和重传计时器,其中最重要的是重传计时器。
2、重传计时器:当TCP实体发出一个段时,它同时启动一个重传计时器,如果在该计时器超时前段被确认,则计时器被停止。如果在确认到来之前计时器超时,则段被重传。
3、那么问题来了,超时间隔应该设置为多长?解决方案是使用一个动态算法,它根据网络性能的连续测量情况,不断地调整超时间隔。

TCP如何进行拥塞控制?
1、当路由器上的队列增长到很大时,网络层检测到拥塞,并试图通过丢弃数据包来管理拥塞。
2、传输层(TCP所在)收到从网络层反馈来的拥塞信息,就会减慢它发送到网络的流量速率。
3、TCP会并发的维持一个拥塞窗口和一个流量控制窗口。拥塞窗口大小限制发送端可以发送的字节数,流量控制窗口指出了接收端可以缓冲的字节数。有效发送是这两个窗口的较小者。

TCP如何进行流量控制?
滑动窗口协议。滑动窗口协议不仅用于流量控制,还参与了一部分拥塞控制

网络传输
为什么网络传输不可靠?
丢包、重复包、包出错、包乱序、安全

TCP协议如何解决网络传输不可靠问题?
滑动窗口协议。是在TCP协议中使用的非常重要的部分,用来维持发送方和接收方缓冲区。这个缓冲区就是为了解决网络传输不可靠的问题。发送方和接收方各自维护自己的缓冲区,商定如何accept传递包和重传机制。
0、窗口大小最大65535,不仅用于流量控制,还参与了一部分拥塞控制,在传输控制过程中窗口大小可以调整,大小为0是合法的。
1、最原始的无滑动窗口协议时,如下。发送一个包,确认一个包。缺点也很明显,很慢

、改进方案,如下。两个包一起发,一起确认。缺点也很明显,收到了包1确认,没收到包2确认,那我一直等下去?发不发后面的包?



3、滑动窗口协议,每确认一个包,就往后移动
如果出现丢包,也就是未收到确认信息,那么就有一个超时重传机制。注意接收方发送Ack(确认字符)必须按照顺序来,即使678号包收到了,但5号包一直没收到,就不会发送678号包的Ack信息。只有收到了5号包,才会把5678的Ack一起发送出去。


TCP\UDP常用端口
端口号的范围是从1~65535。其中1~1024是被RFC 3232规定好了的,被称作“众所周知的端口”(Well Known Ports);从1025~65535的端口被称为动态端口(Dynamic Ports),可用来建立与其它主机的会话,也可由用户自定义用途。

TCP 21端口:FTP 文件传输服务

TCP 23端口:TELNET 终端仿真服务,远程登录

TCP 25端口:SMTP 简单邮件传输服务,发送邮件

UDP 53端口:DNS 域名解析服务

TCP 80端口:HTTP 超文本传输服务

TCP 110端口:POP3 “邮局协议版本3”使用的端口,接收邮件

TCP 443端口:HTTPS 加密的超文本传输服务


IP协议
IPv4协议是32位地址,IPv6是128位地址。

IPv4地址不够用怎么办?
    1. NAT网络地址转换,比如一个IP地址作为一个大学的地址,大学内各个计算机的地址用内网私有地址。
    2. 动态分配,为一台连在网上并使用的计算机动态分配一个IP地址,当该主机不活跃的时候收回分配给他的IP地址
    3. 最终解决方案是IPv6

IPv6相比IPv4的提升
    1. 有更长的地址,一个从32位提升到了128位
    2. 对头进行了简化,从13个字段下降到7个字段,因此路由器可以更快的处理数据包
    3. 更好的支持选项,即以前必须的字段现在变成了可选
安全性的改进,后来这些特征也被引入到了IPv4中,因此现在安全性差异没那么大