四次挥手
- (1)主动关闭的一方,调用close(),协议层发送FIN包,进入FIN_wait-1状态
- (2)被动关闭的一方收到FIN包之后,在协议层回复ACK,然后被动关闭的一方进入close_wait状态。主动关闭的一方则进入FIN_wait_2状态,此时主动关闭的一方要等待被动关闭的一方的应用程序调用close操作。
- (3)被动关闭的一方在完成所有数据发送之后,调用close操作,此时在协议层发送FIN包给主动关闭的一方,等待主动关闭方的ASK报文,此时被动关闭的一方进入了LAST_ACK状态。
- (4)主动关闭的一方收到FIN包之后,在协议层回复ACK,此时主动关闭的连接的一方,进入TIME_WAIT状态,被动关闭的一方进入CLOSED状态。
- (5)主动关闭的一方等待2MSL时间,接收TIME_WAIT,进入CLOSED状态
2MSL
2倍的最大报文生存时间 1 - 4分钟
time_wait
必要性:
- 1.因为虽然正常情况下主动关闭方发送ASK报文,被动关闭方接收ASK报文之后,tcp连接就正常关闭了,但是由于网络是不可靠的,因此无法保证最后发送的的ASK报文一定能被对方接收到,因此对方处于LAST_ASK状态下的socket可能因为超时未收到ASK报文而重发FIN报文,所以这TIME_WAIT状态第一个作用就是用来重发可以可能丢失的报文,以保证四次挥手的完成
- 2.TIME_WAIT状态可以使旧的数据包在网络中因为过期而消失。如果没有TIME_WAIT状态,那么如果该TCP连接立即重新建立,这个时候由于TCP连接是一个四元组,因此对于TCP协议栈来说,前后两条连接完全是同一条连接。而上一条连接的某些数据包可因为网络拥塞等原因在新连接建立后到达接收端。TIME_WAIT状态可以避免这一现象。
危害:
第一是内存资源占用;
第二是对端口资源和系统文件描述符的占用,一个 TCP 连接至少消耗一个本地端口;
避免:
- 服务器可以通过设置SO_REUSEADDR套接字选项来通知内核,如果端口忙,但TCP连接处于TIME_WAIT状态时,可以重用该端口。举个例子,如果服务器程序停止后想要立即重启,而新的套接字依旧希望使用同一端口,那么SO_REUSEADDR选项就可以避免TIME_WAIT状态。
2 OSI七层模型
从上到下:
应用层:网络应用程序和它们的应用层协议存留的地方,包括HTTP,FTP,SMTP,DNS 和DHCP(动态主机配置协议)。传输报文表示层:使通信的应用程序可以解释交换数据的含义。数据压缩和数据加密会话层:提供数据交换定界和同步功能,建立,管理和终止会话。运输层:运输层在应用程序端点之间传输应用层报文,包括TCP(确保传递,拥塞控制,流量控制)和UDP协议。传输报文段。网络层:从一台主机传输到另一台主机,IP协议和一些路由选择协议(BGP,OSPF)。传输数据报(ICMP协议是IP层的附属协议,介于TCP和IP之间的协议,)数据链路层:将分组从一个结点传输到另一个结点。以太网,WIFI和电缆接入网等协议。传输的是帧。不同的链路有不同的协议。ARP地址解析协议物理层:负责一比特一比特的从一个结点传输数据到下一个结点,这物理层的协议与传输材质有关。IEEE802(局域网和层域网标准委员会)定义的一些物理层协议
NAT网址转换协议
该协议允许一个整体机构以一个公用ip地址出现在Internet上,即它是一种把内部私有网络地址翻译成合法网络地址的协议。
4.TCP
(1)TCP连接提供的是全双工服务,它是点对点的,也就是说tcp连接中,服务段和客户端中间的网络结点不会维持一个tcp连接的状态,它们看到的是一些数据报。
(2)tcp通过套接字传递数据流,应用程序将数据写入套接字描述符中,然后tcp将该数据引导到该连接的 发送缓存 。 取出数量受MSS(最大报文段长度,这个和数据链路层可以传输的最大帧长度有关)限制,
(3)tcp的报文段结构
最重要的两个字段是序号字段和确认号字段。
序号字段:该报文传输的数据流的第一个字节在字节流中的编号,比如如果MSS大小为1000,那么第一个报文的序号字段就是0,第二个报文的序号字段就是1000,初始序号可以随机选,以避免接收到先前已经终止的连接的报文段。
确认号字段:主机A期望主机B发送给主机A的下一字节的序号。
对于失序报文段,TCP可以让编程人员自由选择:直接丢弃或者保留等待
(4)流量控制
通过让发送方维护一个接收窗口来避免发送方发送的数据使接收方缓存溢出的可能性。tcp报文段头部有一个接收窗口,接收方把当前缓空间的剩余值放在它发送给另一方的报文段的窗口字段中。
当主机B缓存空间为零时,主机A将继续发送只有一个字节数据的报文段,这些报文段将被接收端确认,并且缓存最终开始清空,确认报文中包含有非零的接收窗口值,避免发送端不知道接收端已经有可用的缓存空间了。
UDP不提供流量控制,所以有缓存溢出风险。
滑动窗口。
(5)拥塞控制
IP层不向端系统提供显式的网络拥塞反馈。
TCP拥塞控制算法
慢启动
TCP连接开始时,cwnd(拥塞窗口值对发送方发送流量进行了限制)设为一个MSS(最大报文长度)。然后传输的报文段首次被确认,cwnd就翻倍。慢启动在检测到一个超时指示的丢包事件之后,将cwnd设置为1,重新开始慢启动,并将ssthresh设置为慢启动门限为 cwnd/2。当cwnd到达ssthresh后,将进入拥塞避免阶段
拥塞避免
在一个RTT往返时延 内,将cwnd的大小增加1,变为线性增长。当丢包事件出现时,ssthresh的值被更新为cwnd值的一半,然后cwnd的值被设定为一个MSS()
快重传:
快重传算法要求首先接收方收到一个失序的报文段后就立刻发出重复确认,而不要等待自己发送数据时才进行捎带确认。
快速恢复
当发送端收到第三个重复确认的报文时,会更新ssthresh(慢启动阈值)的值,然后立即重传丢失的报文段,并且设置:cwnd = ssthresh+3*SMSS,进入拥塞避免阶段。
当收到一个重复确认的报文时,设置cwnd = cwnd +SMSS。此时发送端可以发送新的TCP报文(如果新的cwnd允许)
当收到新数据的确认时,设置cwnd=ssthresh。进入拥塞避免阶段。
TCP 可靠性保证
- 检验和:TCP和UDP的校验和覆盖首部和数据,而TCP头部的校验和只覆盖头部
- 序列号:
a、保证可靠性(当接收到的数据总少了某个序号的数据时,能马上知道)
b、保证数据的按序到达
c、提高效率,可实现多次发送,一次确认
d、去除重复数据
数据传输过程中的确认应答处理、重发控制以及重复控制等功能都可以通过序列号来实现
DUP报文段长度为32比特,提供了差错检验功能。报文段有:源端口号,目的端口号,长度,校验和,应用数据
特点:
只要应用程序将数据传递给UDP,UDP就会将此数据打包进UDP报文段,并将其传递给网络层
无需连接建立:时延小,DNS运行在UDP上。
无连接状态
分组首部开销小:TCP20字节,UDP8字节
ARP链路层地址解析协议
为什么需要链路层地址
并不是主机或路由器具有链路层地址,而是它们的适配器(网络接口)具有链路层地址,所以具有多个网络接口的主机或者路由器有多个链路层地址。交换机不具有。
ARP
因为存在网络层地址和链路层地址,所以需要地址解析协议在这两个地址之间转换。ARP协议与DNS协议相似,但是不同的是ARP协议只提供在同一个子网中的地址查询。DNS是工作在应用层,而ARP是跨越链路层和网络层。
A当一个主机决定向另一个已知IP的主机发送数据报时,需要查询该主机的MAC地址,首先将查找本地ARP表中是否有该IP对应MAC地址的缓存,因为该表的过期时间一般为20分钟。如果没有的找到的话,需要构造一个ARP查询分组,并且用FF-FF(链路层广播地址)来发送这个分组。该查询分组可以被子网上所有的其它适配器收到,并且每个适配器都把该帧中的ARP查询分组向上传递给ARP模块,然后ARP模块检测ARP表中是否有该IP对应MAC地址存在则返回一个ARP响应分组。发送主机收到分组之后就更新对应ARP表。
局域网ARP泛洪
交换机有一张MAC地址表,存储着ip和MAC地址对应关系,该表具有自动学习的功能,可以加快数据的转发。泛洪攻击通过利用这种学习机制,不断发送MAC地址给交换机,充满交换机的MAC地址表,这个时候交换机就只能进行数据广播,其实攻击者可以取代目标主机的MAC地址,使交换机把数据发送给攻击者,攻击者就可以借此获取有用信息。抓包,获取账户密码等信息。
防范:限制每个端口学习的MAC地址数量,制定规则,每个端口只能学习特定的MAC地址。
DDOS 分布式拒绝服务攻击
SYN FLOOD攻击
SYN FLOOD攻击是目前网络上最常见的DDOS攻击,利用的是TCP协议实现上的一个缺陷。通过向网络服务所在端口发送大量伪造源地址的攻击报文,就服务器产生大量的半开TCP连接,占满半连接队列,消耗掉服务器的TCP连接资源,无法向正常的客户提供服务。将无法响应正常的连接请求。
防范:
当服务器收到一个SYN报文段时,并不为该报文段生成一个半开连接,而是生成一个初始TCP序列号,该序列号是根据SYN报文段的源IP地址和端口号等信息精心生成的,服务器发送具有该序列号的SYNASK分组,重要的是,服务器并不记忆相关信息。如果这是一个合法连接,那么服务器将收到ACK报文段,服务器将根据存储在确认号中的信息生成一个套接字的全新连接。
三次握手
客户端的TCP首先向服务端发送一个特殊的TCP报文段,该报文段不包含应用层数据,但是在报文段的首部中的标志位SYN会被置为1,此外客户端会随机选取一个初始序号,放在在TCP报文段的序号字段。
当该报文段到达服务端之后,服务器会从数据报中提取出TCP SYN报文段,为该TCP连接分配TCP缓存和变量,并向客户发送允许连接的SYN ASK报文段,此时的报文段也不包含应用层数据,但是在该报文的TCP首部有三个重要的信息,首先是SYN标志位被置1,其次该首部的确认序号被置为客户端初始发送的序号+1,最后服务端要选择一个字节自己的初试序号。
客户端收到服务端回复的TCP报文段之后,也要为该连接分配缓存和变量,客户向报文段回复一个报文段,作为对服务器的SYN ASK报文段的确认,此报文段的确认序号是服务器发送序号+1.因为此时连接已经建立,所以可以携带数据
TCP为什么是流协议,怎么分割
因为TCP在传输数据之前,必须建立连接,TCP是一个面向连接的,可靠的字节流服务,数据以字节流的形式,为被分割成TCP认为最合适发送的数据块,按顺序从一端发送到另一端,没有固定的报文或者报文边界的概念。
UDP只要应用进程将数据交给UDP,UDP就会将此数据打包放入一个UDP报文段,并且立即将其传递给网络层
如何分割,一般来说,TCP每次可以从TCP缓存中取出放入报文段中的数据数量受限于最大报文长度,MSS通常根据最初确定的由本地发送主机发送的最大链路层帧长度来确定。
tcp keep-alive
tcp keep-alive是TCP的一种检测TCP连接状况的保鲜机制。tcp keep-alive保鲜定时器,支持三个系统内核配置参数:
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_keepalive_time = 1800
keepalive是TCP保鲜定时器,当网络两端建立了TCP连接之后,闲置(双方没有任何数据流发送往来)了tcp_keepalive_time后,服务器就会尝试向客户端发送侦测包,来判断TCP连接状况(有可能客户端崩溃、强制关闭了应用、主机不可达等等)。如果没有收到对方的回答(ack包),则会在 tcp_keepalive_intvl后再次尝试发送侦测包,直到收到对方的ack,如果一直没有收到对方的ack,一共会尝试 tcp_keepalive_probes次,每次的间隔时间在这里分别是15s, 30s, 45s, 60s, 75s。如果尝试tcp_keepalive_probes,依然没有收到对方的ack包,则会丢弃该TCP连接。TCP连接默认闲置时间是2小时,一般设置为30分钟足够了
TCP 有一个机制是保活机制。这个机制的原理是这样的:
定义一个时间段,在这个时间段内,如果没有任何连接相关的活动,TCP 保活机制会开始作用,每隔一个时间间隔,发送一个探测报文,该探测报文包含的数据非常少,如果连续几个探测报文都没有得到响应,则认为当前的 TCP 连接已经死亡,系统内核将错误信息通知给上层应用程序。
在 Linux 内核可以有对应的参数可以设置保活时间、保活探测的次数、保活探测的时间间隔,以下都为默认值:
net.ipv4.tcp_keepalive_time=7200
net.ipv4.tcp_keepalive_intvl=75
net.ipv4.tcp_keepalive_probes=9
tcp_keepalive_time=7200:表示保活时间是 7200 秒(2小时),也就 2 小时内如果没有任何连接相关的活动,则会启动保活机制
tcp_keepalive_intvl=75:表示每次检测间隔 75 秒;
tcp_keepalive_probes=9:表示检测 9 次无响应,认为对方是不可达的,从而中断本次的连接。
也就是说在 Linux 系统中,最少需要经过 2 小时 11 分 15 秒才可以发现一个「死亡」连接。
tcp和udp的区别
1.连接
tcp是面向连接的传输层协议,传输数据前要先建立连接。UDP不需要连接,即可传输数据
2.服务对象
tcp是一对一的两点服务,一条连接只有两个端点。
3.可靠性
tcp是可靠交付数据的,数据可以无差错,不丢失,不重复,按需到达。
udp是尽最大努力交付,不保证可靠交付数据
4.拥塞控制,流量控制
tcp有拥塞控制和流量控制,保证数据传输的安全性
udp则没有,即使网络非常拥堵了,也不会影响udp的发送速率
5.首部开销
tcp首部开销较长,没有使用选项字段时20字节,udp首部大小固定,为8字节,开销比较小
6.传输方式
tcp是流式传输,没有边界,但保证顺序和可靠
udp是一个包一个包的发送,是有边界的,但可能会丢包和乱序
7.分片不同
tcp的数据大小如果大于MSS(最大报文长度),则会在传输层进行分片,目标主机收到后,也同样在传输层组装tcp数据包,如果中途丢失了一个分片,只需要传输这个丢失的分片。
udp数据大小如果大于MTU(最大传输单元(对数据帧的限制)),则需要在IP层进行分片,目标主机收到后,在IP层组装完数据,接着再传给传输层,如果中途丢失了一个分片,则就需要重传所有的数据包,这样的传输效率非常差,所以UDP的报文应该小于MTU
为什么TCP连接是3次握手
原因一:避免历史连接
三次握手的首要原因是为了防止旧的重复连接初始化造成混乱。比如如果客户端多次发送SYN连接建立报文,在网络拥塞的情况下,一个旧的报文比一个新的报文先到达了服务端,服务端发送一个SYN + ACK报文给客户端,客户端可以根据自身的上下文判断出这是一个历史连接(序号过期或者超时),那么客户端就会发送RST报文给服务端,表示中止这一次连接
如果是两次握手,就无法判断当前连接是否是历史连接
原因二:同步双方序列号
还有一个原因是为了同步双方初始化序列号
序列号是可靠传输的一个关键因素,作用是:
- 接收方可以去除重复的数据
- 接收方可以根据数据包的序列号按序接收
- 可以表示发送出去的数据包中,哪些是已经被对方收到的
当客户端发送携带初始化序列号的SYN报文是,需要服务端一个ACK应答报文,表示客户端的SYN报文已被服务端成功接收,那当服务端发送初始化序列号给客户端时,依然也要得到客户端的应答响应,这样一来一回才能确保双方的初始化序列号能被可靠的同步
原因三:
避免资源浪费,如果只有两次握手,当客户端的SYN报文在网络中阻塞,客户端没有收到ASK报文,就会重新发送SYN报文,如果没有第三次握手,此时服务端收到请求之后,就会建立很多冗余的无效连接,造成不必要的资源浪费
ACK和 ack的区别
一个是确认值(Acknowledgement),为1便是确认连接。
另一个是确认编号(Acknowledgement Number),即接收到的上一次远端主机传来的seq然后+1,再发送给远端主机。提示远端主机已经成功接收上一次所有数据。
大写的是标志位,小写的是序列号,回复已经接收到数据
本地套接字
本地套接字一般也叫做UNix域套接字, 本地套接字严格意义上来说提供了一种单主机,跨进程间通信方式,开发方便,减小了协议栈实现的复杂程度,效率比TCP/UDP套接字都要高许多。
(1)本地套接字的编程接口和IPv4, IPv6套接字接口是一样的,支持字节流和数据报来年各种功能协议
(2)本地套接字的实现效率大大高于IPV4和IPV6的字节流,数据流套接字实现。
TCP协议保证数据传输可靠性的方式主要有:
校验和
序列号
确认应答
超时重传
连接管理
流量控制
拥塞控制
计算机网络基础知识
TELNET远程登录协议
它允许用户通过一个协商过程来与一个盐城设备进行通信,它为用户提供远程了在本地计算机上完成远程主机工作的能力
SSH协议
SSH是一种建立在应用层上的安全加密协议,弥补了TELNET的安全问题,使用SSH进行远程登录可以加密信息,防止攻击。
SSH使用人工判断figerprint是否有效的方式,第一次登录时,用户要确认是否是正确的fingerprint,然后SSH会在本地存下这个fingerprint,再次登录时会自动进行校验
SSH其实是专门为shell设计的一种通信协议,它垮了两个网络层(传输层和应用层)。通俗点讲就是只有SSH客户端,和SSH服务器端之间的通信才能使用这个协议,其他软件服务无法使用它。但是其实我们非常需要一个通用的,建立在应用层之下的一个传输层安全协议,它的目标是建立一种对上层应用协议透明的,不管是HTTP、FTP、还是电子邮件协议或其他任何应用层协议都可以依赖的底层的可安全通信的传输层协议
停止等待协议
停止等待协议(stop-and-wati),是数据链据层一个很重要的协议,基本原理就是说每发送一个分组,必须要停下来等待,等接收方确认后才可继续发送下一个分组。如果没收到确认,就只能超时重传。
优点:很简单,每次发送一个分组就等待确认。
缺点:信道利用率不高,每次都要等。
为了克服停止等待的缺点,于是乎又出现了另外两种协议。
1.连续ARQ(Automatic Repeat reQuest)协议,滑动窗口的前身,也就是不滑动的窗口,一次性发送N个,然后等待,减少了等待时间,提高信道利用率和吞吐量。
2.选择重传ARQ
socket可以TCP和UDP共用吗
传输层如何分辨是TCP还是UDP报文
根据ip头部的(网络层的协议字段),有一个标识符,tcp是6,udp是17。
