TCP与UDP区别总结:
1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保 证可靠交付
3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的
UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
5、TCP首部开销20字节;UDP的首部开销小,只有8个字节
6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道
OSI七层模型和TCP/IP四层模型,每层列举2个协议。公众号 趣谈编程 互联网协议(上)
从系统的角度,解释互联网是如何构成的。
物理层:它就是把电脑连接起来的物理手段。
它主要规定了网络的一些电气特性,作用是负责传送0和1的电信号。
链路层:它在物理层的上方,确定了0和1的分组方式,实现在多台计算机之间传送数据。
单纯的0和1没有任何意义,必须规定解读方式:多少个电信号算一组?每个信号位有何意义?数据包的定义(标头+数据)、网卡的MAC地址(标头中:定位网卡和确定数据包的路径)、广播的发送方式(不是把数据包准确送到接收方,而是向本网络内所有计算机发送一个数据包,让每台计算机自己判断这个包的"标头",找到接收方的MAC地址,与自身的MAC地址相比较,判断是否为接收方,如果两者相同,就接受这个包,做进一步处理,否则就丢弃这个包。这种发送方式就叫做"广播"(broadcasting)
),"链接层"就可以在多台计算机之间传送数据了。以太网协议,依靠MAC地址发送数据。
广播方式的缺点:以太网采用广播方式发送数据包,所有成员人手一"包",不仅效率低,而且局限在发送者所在的子网络。也就是说,如果两台计算机不在同一个子网络,广播是传不过去的。
网络层:引进网址,使得我们能够区分不同的计算机(哪些MAC地址)是否属于同一个子网络。
网络层:建立"主机到主机"的通信。
计算机的两种地址MAC地址和网络地址:两种地址之间没有任何联系,MAC地址是绑定在网卡上的,网络地址则是管理员分配的,它们只是随机组合在一起。网络地址帮助我们确定计算机所在的子网络,MAC地址则将数据包送到该子网络中的目标网卡。因此,从逻辑上可以推断,必定是先处理网络地址,然后再处理MAC地址。
"子网掩码"(subnet mask):是表示子网络特征的一个参数。它在形式上等同于IP地址,也是一个32位二进制数字,它的网络部分全部为1,主机部分全部为0。用来判断任意两个IP地址是否处在同一个子网络。方法是将两个IP地址与子网掩码分别进行AND运算(两个数位都为1,运算结果为1,否则为0),然后比较结果是否相同,如果是的话,就表明它们在同一个子网络中,否则就不是。
IP协议的作用:一个是为每一台计算机分配IP地址,另一个是确定哪些地址在同一个子网络。
ARP协议:能够从IP地址得到MAC地址。因为IP数据包是放在以太网数据包里发送的,所以我们必须同时知道两个地址,一个是对方的MAC地址,另一个是对方的IP地址。通常情况下,对方的IP地址是已知的,但是我们不知道它的MAC地址。
这里又可以分成两种情况:
第一种情况,如果两台主机不在同一个子网络,那么事实上没有办法得到对方的MAC地址,只能把数据包传送到两个子网络连接处的"网关"(gateway),让网关去处理。
第二种情况,如果两台主机在同一个子网络,那么我们可以用ARP协议,得到对方的MAC地址。
ARP协议也是发出一个数据包(包含在以太网数据包中),其中包含它所要查询主机的IP地址,在对方的MAC地址这一栏,填的是FF:FF:FF:FF:FF:FF,表示这是一个"广播"地址。
它所在子网络的每一台主机,都会收到这个数据包,从中取出IP地址,与自身的IP地址进行比较。如果两者相同,都做出回复,向对方报告自己的MAC地址,否则就丢弃这个包。
有了ARP协议之后,我们就可以得到同一个子网络内的主机MAC地址,可以把数据包发送到任意一台主机之上了。
传输层:建立"端口到端口"的通信。
UDP协议,它的格式几乎就是在数据前面,加上端口号。
UDP数据包,也是由"标头"和"数据"两部分组成。
"标头"部分主要定义了发出端口和接收端口,"数据"部分就是具体的内容。
然后,把整个UDP数据包放入IP数据包的"数据"部分,而前面说过,IP数据包又是放在以太网数据包之中的,所以整个以太网数据包现在变成了下面这样:
UDP数据包非常简单,"标头"部分一共只有8个字节,总长度不超过65,535字节,正好放进一个IP数据包。
UDP协议的优点是比较简单,容易实现,但是缺点是可靠性较差,一旦数据包发出,无法知道对方是否收到。
为了解决这个问题,提高网络可靠性,TCP协议就诞生了。
这个协议非常复杂,但可以近似认为,它就是有确认机制的UDP协议,每发出一个数据包都要求确认。如果有一个数据包遗失,就收不到确认,发出方就知道有必要重发这个数据包了。
因此,TCP协议能够确保数据不会遗失。它的缺点是过程复杂、实现困难、消耗较多的资源。
TCP数据包和UDP数据包一样,都是内嵌在IP数据包的"数据"部分。TCP数据包没有长度限制,理论上可以无限长,但是为了保证网络的效率,通常TCP数据包的长度不会超过IP数据包的长度,以确保单个TCP数据包不必再分割。
应用层:规定应用程序的数据格式。
举例来说,TCP协议可以为各种各样的程序传递数据,比如Email、WWW、FTP等等。那么,必须有不同协议规定电子邮件、网页、FTP数据的格式,这些应用程序协议就构成了"应用层"。
这是最高的一层,直接面对用户。它的数据就放在TCP数据包的"数据"部分。因此,现在的以太网的数据包就变成下面这样。
DHCP协议:应用层协议,建立在UDP协议之上,所以整个数据包是这样的:
(1)最前面的"以太网标头",设置发出方(本机)的MAC地址和接收方(DHCP服务器)的MAC地址。前者就是本机网卡的MAC地址,后者这时不知道,就填入一个广播地址:FF-FF-FF-FF-FF-FF
(2)后面的"IP标头",设置发出方的IP地址和接收方的IP地址。这时,对于这两者,本机都不知道。于是,发出方的IP地址就设为0.0.0.0,接收方的IP地址设为255.255.255.255。
(3)最后的"UDP标头",设置发出方的端口和接收方的端口。这一部分是DHCP协议规定好的,发出方是68端口,接收方是67端口。
这个数据包构造完成后,就可发出了。以太网是广播发送,同一个子网络的每台计算机都收到了这个包。
因为接收方的MAC地址是FF-FF-FF-FF-FF-FF,看不出是发给谁的,所以每台收到这个包的计算机,还必须分析这个包的IP地址,才能确定是不是发给自己的。
当看到发出方IP地址是0.0.0.0,接收方是255.255.255.255,于是DHCP服务器知道"这个包是发给我的",而其他计算机就可以丢弃这个包。
接下来,DHCP服务器读出这个包的数据内容,分配好IP地址,发送回去一个"DHCP响应"数据包。
这个响应包的结构也是类似的,以太网标头的MAC地址是双方的网卡地址,IP标头的IP地址是DHCP服务器的IP地址(发出方)和255.255.255.255(接收方),UDP标头的端口是67(发出方)和68(接收方),分配给请求端的IP地址和本网络的具体参数则包含在Data部分。
新加入的计算机收到这个响应包,于是就知道了自己的IP地址、子网掩码、网关地址、DNS服务器等等参数。
一个实例:访问网页
9.1本机参数
我们假定,经过上一节的步骤,用户设置好了自己的网络参数:
* 本机的IP地址:192.168.1.100
* 子网掩码:255.255.255.0
* 网关的IP地址:192.168.1.1
* DNS的IP地址:8.8.8.8
然后他打开浏览器,想要访问Google,在地址栏输入了网址:www.google.com。
这意味着,浏览器要向Google发送一个网页请求的数据包。
9.2DNS协议
我们知道,发送数据包,必须要知道对方的IP地址。但是,现在,我们只知道网址www.google.com,不知道它的IP地址。
DNS协议可以帮助我们,将这个网址转换成IP地址。已知DNS服务器为8.8.8.8,于是我们向这个地址发送一个DNS数据包(53端口)。
然后,DNS服务器做出响应,告诉我们Google的IP地址是172.194.72.105。于是,我们知道了对方的IP地址。
9.3子网掩码
接下来,我们要判断,这个IP地址是不是在同一个子网络,这就要用到子网掩码。
已知子网掩码是255.255.255.0,本机用它对自己的IP地址192.168.1.100,做一个二进制的AND运算(两个数位都为1,结果为1,否则为0),计算结果为192.168.1.0;
然后对Google的IP地址172.194.72.105也做一个AND运算,计算结果为172.194.72.0。
这两个结果不相等,所以结论是,Google与本机不在同一个子网络。
因此,我们要向Google发送数据包,必须通过网关192.168.1.1转发,也就是说,接收方的MAC地址将是网关的MAC地址。
9.4应用层协议
浏览网页用的是HTTP协议,它的整个数据包构造是这样的:
HTTP部分的内容,类似于下面这样:
我们假定这个部分的长度为4960字节,它会被嵌在TCP数据包之中。
9.5 TCP协议
TCP数据包需要设置端口,接收方(Google)的HTTP端口默认是80,发送方(本机)的端口是一个随机生成的1024-65535之间的整数,假定为51775。
TCP数据包的标头长度为20字节,加上嵌入HTTP的数据包,总长度变为4980字节。
9.6 IP协议
然后,TCP数据包再嵌入IP数据包。IP数据包需要设置双方的IP地址,这是已知的,发送方是192.168.1.100(本机),接收方是172.194.72.105(Google)。
IP数据包的标头长度为20字节,加上嵌入的TCP数据包,总长度变为5000字节。
9.7 以太网协议
最后,IP数据包嵌入以太网数据包。以太网数据包需要设置双方的MAC地址,发送方为本机的网卡MAC地址,接收方为网关192.168.1.1的MAC地址(通过ARP协议得到)。
以太网数据包的数据部分,最大长度为1500字节,而现在的IP数据包长度为5000字节。因此,IP数据包必须分割成四个包。
因为每个包都有自己的IP标头(20字节),所以四个包的IP数据包的长度分别为1500、1500、1500、560。
9.8服务器端响应
经过多个网关的转发,Google的服务器172.194.72.105,收到了这四个以太网数据包。
根据IP标头的序号,Google将四个包拼起来,取出完整的TCP数据包,然后读出里面的"HTTP请求",接着做出"HTTP响应",再用TCP协议发回来。
本机收到HTTP响应以后,就可以将网页显示出来,完成一次网络通信。
这个例子就到此为止,虽然经过了简化,但它大致上反映了互联网协议的整个通信过程。
ARP是地址解析协议,简单语言解释一下工作原理。
答:1:首先,每个主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP地址和MAC地址之间的对应关系。
2:当源主机要发送数据时,首先检查ARP列表中是否有对应IP地址的目的主机的MAC地址,如果有,则直接发送数据,如果没有,就向本网段的所有主机发送ARP数据包,该数据包包括的内容有:源主机 IP地址,源主机MAC地址,目的主机的IP 地址。
3:当本网络的所有主机收到该ARP数据包时,首先检查数据包中的IP地址是否是自己的IP地址,如果不是,则忽略该数据包,如果是,则首先从数据包中取出源主机的IP和MAC地址写入到ARP列表中,如果已经存在,则覆盖,然后将自己的MAC地址写入ARP响应包中,告诉源主机自己是它想要找的MAC地址。
4:源主机收到ARP响应包后。将目的主机的IP和MAC地址写入ARP列表,并利用此信息发送数据。如果源主机一直没有收到ARP响应数据包,表示ARP查询失败。
广播发送ARP请求,单播发送ARP响应。
各种协议的介绍
答:ICMP协议: 因特网控制报文协议。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。
TFTP协议: 是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂、开销不大的文件传输服务。
HTTP协议: 超文本传输协议,是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。
NAT协议:网络地址转换属接入广域网(WAN)技术,是一种将私有(保留)地址转化为合法IP地址的转换技术,
DHCP协议:动态主机配置协议,是一种让系统得以连接到网络上,并获取所需要的配置参数手段,使用UDP协议工作。具体用途:给内部网络或网络服务供应商自动分配IP地址,给用户或者内部网络管理员作为对所有计算机作中央管理的手段。
描述RARP协议
答:RARP是逆地址解析协议,作用是完成硬件地址到IP地址的映射,主要用于无盘工作站,因为给无盘工作站配置的IP地址不能保存。工作流程:在网络中配置一台RARP服务器,里面保存着IP地址和MAC地址的映射关系,当无盘工作站启动后,就封装一个RARP数据包,里面有其MAC地址,然后广播到网络上去,当服务器收到请求包后,就查找对应的MAC地址的IP地址装入响应报文中发回给请求者。因为需要广播请求报文,因此RARP只能用于具有广播能力的网络。
DNS域名系统,简单描述其工作原理。
答:当DNS客户机需要在程序中使用名称时,它会查询DNS服务器来解析该名称。客户机发送的每条查询信息包括三条信息:包括:指定的DNS域名,指定的查询类型,DNS域名的指定类别。基于UDP服务,端口53. 该应用一般不直接为用户使用,而是为其他应用服务,如HTTP,SMTP等在其中需要完成主机名到IP地址的转换。
在OSI七层模型中,每一层的作用和对应的协议如下:
TCP位码,有6种标识:
SYN(synchronous建立联机) ACK(acknowledgement 确认) PSH(push传送)
FIN(finish结束) RST(reset重置) URG(urgent紧急)
Sequence number(顺序号码) Acknowledge number(确认号码)
3次握手
第一次握手:客户端发送syn包(syn=x)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(syn=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。
4次挥手
第一次挥手:主动关闭方发送一个FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不 会再给你发数据了(当然,在fin包之前发送出去的数据,如果没有收到对应的ack确认报文,主动关闭方依然会重发这些数据),但是,此时主动关闭方还可 以接受数据。
第二次挥手:被动关闭方收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)。
第三次挥手:被动关闭方发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了。
第四次挥手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手。
问题:
1.为什么连接的时候是三次握手,关闭的时候却是四次挥手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
2.为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。
3.client发送完最后一个ack之后,进入time_wait状态,但是他怎么知道server有没有收到这个ack呢?莫非sever也要等待一段时间,如果收到了这个ack就close,如果没有收到就再发一个fin给client?这么说server最后也有一个time_wait哦?
因为网络原因,主动关闭的一方发送的这个ACK包很可能延迟,从而触发被动连接一方重传FIN包。极端情况下,这一去一回,就是两倍的MSL时长。如果主动关闭的一方跳过TIME_WAIT直接进入CLOSED,或者在TIME_WAIT停留的时长不足两倍的MSL,那么当被动关闭的一方早先发出的延迟包到达后,就可能出现类似下面的问题:
1.旧的TCP连接已经不存在了,系统此时只能返回RST包
2.新的TCP连接被建立起来了,延迟包可能干扰新的连接,这就是为什么time_wait需要等待2MSL时长的原因。
4. TCP连接建立过程中为什么需要"三次握手" TCP三次握手 以及为什么不是两次
目的是为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。
"已失效的连接请求报文段"的产生在这样一种情况下:
client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。若不采用"三次握手",那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用"三次握手"的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。"
TCP的三次握手过程?为什么会采用三次握手,若采用二次握手可以吗?
答:建立连接的过程是利用客户服务器模式,假设主机A为客户端,主机B为服务器端。
(1)TCP的三次握手过程:主机A向B发送连接请求;主机B对收到的主机A的报文段进行确认;主机A再次对主机B的确认进行确认。
(2)采用三次握手是为了防止失效的连接请求报文段突然又传送到主机B,因而产生错误。失效的连接请求报文段是指:主机A发出的连接请求没有收到主机B的确认,于是经过一段时间后,主机A又重新向主机B发送连接请求,且建立成功,顺序完成数据传输。考虑这样一种特殊情况,主机A第一次发送的连接请求并没有丢失,而是因为网络节点导致延迟达到主机B,主机B以为是主机A又发起的新连接,于是主机B同意连接,并向主机A发回确认,但是此时主机A根本不会理会,主机B就一直在等待主机A发送数据,导致主机B的资源浪费。
(3)采用两次握手不行,原因就是上面说的实效的连接请求的特殊情况。
5.如果客户的最后一个 ack 丢失了客户端和服务端分别会做出什么动作 ?
如果没有经过4次挥手,一方突然掉线,有什么后果(会有复位信号)
当Client端收到Server的SYN+ACK应答后,其状态变为ESTABLISHED,并发送ACK包给Server;如果此时ACK在网络中丢失,那么Server端该TCP连接的状态为SYN_RECV,并且依次等待3秒、6秒、12秒后重新发送SYN+ACK包,以便Client重新发送ACK包。Server重发SYN+ACK包的次数,可以通过设置/proc/sys/net/ipv4/tcp_synack_retries修改,默认值为5。如果重发指定次数后,仍然未收到ACK应答,那么一段时间后,Server自动关闭这个连接。但是Client认为这个连接已经建立,如果Client端向Server写数据,Server端将以RST包响应,方能感知到Server的错误。
tcp如何保证可靠传输?不匹配会怎么样?(滑动窗口)https://blog.csdn.net/cmm0401/article/details/77878998
1、确认和重传:接收方收到报文就会确认,当TCP发出一个段后,它启动一个定时器,如果收到了接受端对该段的ACK信息,就将该段从队列中删去。发送方发送一段时间后没有收到确认就重传。
2、数据校验:TCP将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段。
3、数据合理分片和排序:
UDP:IP数据报大于1500字节,大于MTU.这个时候发送方IP层就需要分片(fragmentation).把数据报分成若干片,使每 一片都小于MTU.而接收方IP层则需要进行数据报的重组.这样就会多做许多事情,而更严重的是,由于UDP的特性,当某一片数据传送中丢失时,接收方便 无法重组数据报.将导致丢弃整个UDP数据报.
tcp会按MTU合理分片,TCP给发送的每一个包进行编号, 接收方会缓存未按序到达的数据,重新排序后再交给应用层。
4、流量控制:TCP连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的我数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP使用的流量控制协议是可变大小的滑动窗口协议。
5、拥塞控制:当网络拥塞时,减少数据的发送。
TCP 流量控制:
如果发送端发送的特别快,而接收端处理的能力慢,会出现什么情况?
大量的数据报积压在接收端,甚至被丢弃,进而也会引发重传等后果。
滑动窗口机制:任意时刻发送方都维持一个连续的允许发送的帧的需要,称之为窗口,其中每个序号代表了那些已经发送,但是没有被确认的帧或可以被发送的帧
1.1传输效率问题
可以用不同的机制控制TCP报文段的发送时机:
[1]. TCP维持一个变量MSS,等于最大报文段长度。只要缓冲区存放的数据达到MSS字节时,就组装成了一个TCP报文段发送出去。
[2]. 由发送方的应用进程指明要发送的报文段,即:TCP支持推送操作。
[3]. 发送方的一个计时器期限到了,这时就把当前已有的缓存数据装入报文段(但长度不能超过MSS大小)发送出去。
1.2 Nagle算法
发送方把第一个数据字节发送出去,把后面到达的数据字节缓存起来。当发送方接收对第一个数据字符的确认后,再把发送缓存中的所有数据组装成一个报文段再发送出去,同时继续对随后到达的数据进行缓存。只有在收到对前一个报文段的确认后,才继续发送下一个报文段。规定一个TCP连接最多只能有一个未被确认的未完成的小分组,在该分组的确认到达之前不能发送其他的小分组。当数据到达较快而网络速率较慢时,用这样的方法可明显地减少所用的网络带宽。
Nagle算法还规定:当到达的数据已达到发送窗口大小的一半或已经达到报文段的最大长度时,就可立即发送一个报文段。
1.3 糊涂窗口综合症
TCP接收方的缓存已满,而交互式的应用进程一次只从接收缓存中读取1字节(这样就使接收缓存空间仅腾出1字节),然后向发送方发送确认,并把窗口设置为1个字节(但发送的数据报为40字节的的话)。然后,发送方又发来1个字节的数据(发送方的IP数据报是41字节),接收方发回确认,仍然将窗口设置为1个字节。这样,网络的效率很低。要解决这个问题,可让接收方等待一段时间,使得或者接收缓存已有足够空间容纳一个最长的报文段或者等到接收方缓存已有一半的空闲空间。只要出现这两种情况,接收方就发回确认报文,并向发送方通知当前的窗口大小。此外,发送方也不要发送太小的报文段,而是把数据报积累成足够大的报文段,或达到接收方缓存的空间的一半大小。
TCP拥塞控制:慢启动、拥塞避免、快重传、快启动
网络拥塞现象是指到达通信子网中某一部分的分组数量过多,使得该部分网络来不及处理,以致引起这部分乃至整个网络性能下降的现象,严重时导致网络通信业务陷入停顿出现死锁现象。拥塞控制是通过拥塞窗口处理网络拥塞现象的一种机制。
发送报文段速率确定:
[1]. 全局考虑防止拥塞 <- - 拥塞窗口 (Congestion Window) - -> 发送端流量控制,发送端根据自己估计的网络拥塞程度而设置的窗口值;
[2]. 接收端的接收能力 <- - 接收窗口 (Reciver Window) - -> 接收端流量控制,接收端根据目前的接收缓存大小所许诺的最新窗口值;
发送方窗口的上限值 = Min [ rwind, cwind ]
当rwind < cwind 时,接收方的接收能力限制发送方窗口的最大值。
当cwind < rwind 时,网络的拥塞限制发送方窗口的最大值。
因特网建议标准RFC2581定义了拥塞控制的四种算法:慢开始(Slow-start),拥塞避免(Congestion Avoidance),快重传(Fast Restrangsmit)和快恢复(Fast Recovery)。我们假定
1)数据单方向传送,而另外一个方向只传送确认;
2)接收方总是有足够大的缓存空间,因为发送窗口的大小由网络的拥塞程度来决定。
慢启动:
发送方维护一个拥塞窗口cwind的状态变量。拥塞窗口的大小取决于网络的拥塞程度,动态变化。通过逐渐增加cwind的大小来探测可用的网络容量,防止连接开始时采用不合适的发送量导致网络拥塞。
-[1]. 当主机开始发送数据时,如果通过较大的发送窗口立即将全部数据字节都注入到网络中,由于不清楚网络情况,有可能引起网络拥塞;
-[2]. 较好方法是试探,从小到达逐渐增大发送端拥塞控制窗口的cwind数值;
-[3]. 开始发送报文段时,先将拥塞窗口cwind设置为一个最大报文段MSS值。每收到一个对新报文段的ACK确认后,将拥塞窗口cwind增加至多一个MSS的数值。当rwind足够大的时候,为防止拥塞窗口cwind的增长引起网络拥塞,还需要另外一个变量,慢开始门限ssthresh。
当 cwind < ssthresh时,使用上述慢启动算法;
当 cwind > ssthresh时,停止使用慢启动算法,改用拥塞避免算法;
慢启动局限性:
[1]. 需要获得网络内部流量分布的信息,浪费可用的网络容量,额外开销;
[2]. 估算合理的ssthresh值并不容易,可能耗时较长;
慢启动的"慢"并不是指cwind的增长速度慢,而是指在TCP开始发送报文段时先设置cwind=1,使得发送方在开始时只发送一个报文段(目的是探测一下网络的拥塞情况),然后再逐渐增大cwind。
拥塞避免:
让拥塞窗口cwind缓慢地增大,每经过一个往返时间RTT就把发送方的拥塞窗口cwind加1,而不是加倍。这样拥塞窗口cwind线性缓慢增长,比慢开始算法的拥塞窗口增长速率缓慢得多。
无论慢启动开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认),就要把慢启动门限ssthresh设置为出现拥塞时的发送方窗口值的一半(但不能小于2)。然后把拥塞窗口cwind重新设置为1,执行慢启动算法。目的是迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕。
控制过程:
-[1]. TCP连接初始化,将拥塞窗口cwind设置为1个报文段,即cwind=1;
-[2]. 执行慢开始算法,cwind按指数规律增长,直到cwind == ssthresh时,开始执行拥塞避免算法,cwind按线性规律增长;
-[3]. 当网络发生拥塞,把ssthresh值更新为拥塞前ssthresh值的一半,cwind重新设置为1,再按照 [2] 执行。
说明:由指数增长拉低到线性增长,降低出现拥塞的可能。"拥塞避免"并非指完全能够避免拥塞,利用以上的措施要完全避免网络拥塞还是不可能的。
慢开始算法只是在TCP连接建立和网络出现超时时才使用。
快重传和快恢复
基本原理:
一条TCP连接有时会因等待重传计时器的超时而空闲较长的时间,慢开始和拥塞避免无法很好的解决这类问题,因此提出了快重传和快恢复的拥塞控制方法。
为使发送方及早知道有报文段没有达到对方,快速重传算法首先要求接收方每收到一个报文段后就立即发出重复确认。快重传算法并非取消了重传机制,只是在某些情况下更早的重传丢失的报文段,即:当TCP源端收到到三个相同的ACK确认时,即认为有数据包丢失,则源端重传丢失的数据包,而不必等待 RTO(Retransmission Timeout)超时。由于发送方尽早重传未被确认的报文段,因此,采用快重传后可以使整个网络吞吐量提高约20%。
控制过程:
与快重传配合使用的还有快恢复算法,具体地:
- [1]. 当发送方连续收到三个重复确认时,执行"乘法减小"算法,慢启动门限减半,为了预防网络发生拥塞。
- [2]. 由于发送方现在认为网络很可能没有发生拥塞,因此现在不执行慢启动算法,而是把cwind值设置为慢启动门限减半后的值,然后开始执行拥塞避免算法,拥塞窗口cwind值线性增大。避免了当网络拥塞不够严重时采用"慢启动"算法而造成过大地减小发送窗口尺寸的现象。
说明:新的 TCP Reno 版本在快重传之后采用快恢复算法而不是采用慢启动算法。从接收方对发送方的流量控制的角度考虑,发送方的发送窗口一定不能超过对方给出的接收窗口rwind 。
拥塞控制流量控制区别:
相同:提高网络性能。
不同:
[1].流量控制:在TCP连接上实现对发送流量的控制,考虑点对点之间对通信量的控制,端到端,即:控制发送端的数据发送速率,使接收端可以来得及接收,保证网络高效稳定运行。
[2].拥塞控制:处理网络拥塞现象,考虑网络能够承受现有的网络负荷,全局性变量,涉及所有的路由器、主机以及与降低网络传输性能有关的因素。防止过多的数据注入到网络,使网络中的路由器或链路不致过载,确保通信子网可以有效为主机传递分组。
udp想要可靠传输的话如何设计?
UDP它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。
传输层无法保证数据的可靠传输,只能通过应用层来实现了。实现的方式可以参照tcp可靠性传输的方式,只是实现不在传输层,实现转移到了应用层。
实现确认机制、重传机制、窗口确认机制。
如果你不利用linux协议栈以及上层socket机制,自己通过抓包和发包的方式去实现可靠性传输,那么必须实现如下功能:
发送:包的分片、包确认、包的重发
接收:包的调序、包的序号确认
目前有如下开源程序利用udp实现了可靠的数据传输。分别为RUDP、RTP、UDT。
RUDP 提供一组数据服务质量增强机制,如拥塞控制的改进、重发机制及淡化服务器算法等,从而在包丢失和网络拥塞的情况下, RTP 客户机(实时位置)面前呈现的就是一个高质量的 RTP 流。在不干扰协议的实时特性的同时,可靠 UDP 的拥塞控制机制允许 TCP 方式下的流控制行为。
实时传输协议(RTP)为数据提供了具有实时特征的端对端传送服务,如在组播或单播网络服务下的交互式视频音频或模拟数据。应用程序通常在 UDP 上运行 RTP 以便使用其多路结点和校验服务;这两种协议都提供了传输层协议的功能。但是 RTP 可以与其它适合的底层网络或传输协议一起使用。如果底层网络提供组播方式,那么 RTP 可以使用该组播表传输数据到多个目的地。
RTP 本身并没有提供按时发送机制或其它服务质量(QoS)保证,它依赖于底层服务去实现这一过程。 RTP 并不保证传送或防止无序传送,也不确定底层网络的可靠性。 RTP 实行有序传送, RTP 中的序列号允许接收方重组发送方的包序列,同时序列号也能用于决定适当的包位置,例如:在视频解码中,就不需要顺序解码。
基于UDP的数据传输协议(UDP-basedData Transfer Protocol,简称UDT)是一种互联网数据传输协议。UDT的主要目的是支持高速广域网上的海量数据传输,而互联网上的标准数据传输协议TCP在高带宽长距离网络上性能很差。顾名思义,UDT建于UDP之上,并引入新的拥塞控制和数据可靠性控制机制。UDT是面向连接的双向的应用层协议。它同时支持可靠的数据流传输和部分可靠的数据报传输。由于UDT完全在UDP上实现,它也可以应用在除了高速数据传输之外的其它应用领域,例如点到点技术(P2P),防火墙穿透,多媒体数据传输等等。
实现方案
收发缓存设计:发送方发送缓存主体为一个循环队列(存放数据),同时配置一个链队列维护每个segment的信息(如序列号,数据量,与循环队列配合使用)。接收方缓存为一个固定大小的结构体数组。
// rUDP_sender:
Typedef struct
{
charbuf[MAXNUM];
intfront, rear;
}QueueBuf;
//Buffer Information Management
//linked queue
Typedef struct // element type
{
intseqnum = 0;
intlength = 0;
}Info;
typedef struct node
{
Infoinfo;
node*next = NULL;
}InfoNodeType;
typedefstruct
{
InfoNodeType*front;
InfoNodeType*rear;
}BufInfoManagLq;
// rUDP_receiver:
typedefstruct{
intseqnum;
int payload_len;
char seg[sizeof(Segment)];
}RecvNode;
typedefstruct{
intindex = 0;
RecvNoderecv_array[10];
}RecvBuf;
开一个线程执行有限状态机任务。
核心框架是一个发送类和一个接收类(收发分别实现的单工版本),可以提供类似于tcp socket的API和最基本的可靠性数据传输服务。
且:无数据截断,无快速重传,初始序列预定义,序列号不循环使用。
TCP为什么可靠 UDP为什么不可靠
在TCP协议中使用了接收确认和重传机制。这样每一次信息的传输都经过了像三次握手那样的一个过程,使得每一个信息都能保证到达,是可靠的。而UDP是尽力传送,没有应答和重传机制,UDP只是将信息发送出去,对方收不收到也不进行应答。所以UDP协议是不可靠的。
tcp的timeout状态含义,怎么避免timeout
TCP和UDP相关的协议与端口号
TCP对应的协议:
(1) FTP:定义了文件传输协议,使用21端口。
(2) Telnet:一种用于远程登陆的端口,使用23端口,用户可以以自己的身份远程连接到计算机上,可提供基于DOS模式下的通信服务。
(3) SMTP:邮件传送协议,用于发送邮件。服务器开放的是25号端口。
(4) POP3:它是和SMTP对应,POP3用于接收邮件。POP3协议所用的是110端口。
(5)HTTP:是从Web服务器传输超文本到本地浏览器的传送协议。
UDP对应的协议:
(1) DNS:用于域名解析服务,将域名地址转换为IP地址。DNS用的是53号端口。
(2) SNMP:简单网络管理协议,使用161号端口,是用来管理网络设备的。由于网络设备很多,无连接的服务就体现出其优势。
(3) TFTP简单文件传输协议,该协议在熟知端口69上使用UDP服务。
TCP UDP的应用场景举例
使用TCP:当对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议。
在日常生活中,常见使用TCP协议的应用如下:
- 浏览器,用的HTTP
- FlashFXP,用的FTP
- Outlook,用的POP、SMTP
- Putty,用的Telnet、SSH
- QQ文件传输
使用UDP:当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用UDP。
比如,日常生活中,常见使用UDP协议的应用如下:
- QQ语音
- QQ视频
- TFTP
-
数据包总量比较少的通信,比如DNS、SNMP。
-
视频、音频等对实时性要求比较高的多媒体通信。
-
广播通信、多播通信。
Tcp分包粘包问题,怎么处理? udp会粘包吗?为什么?
粘包产生原因:
先说TCP:由于TCP协议本身的机制(面向连接的可靠地协议-三次握手机制)客户端与服务器会维持一个连接(Channel),数据在连接不断开的情况下,可以持续不断地将多个数据包发往服务器,但是如果发送的网络数据包太小,那么他本身会启用Nagle算法(可配置是否启用)对较小的数据包进行合并(基于此,TCP的网络延迟要UDP的高些)然后再发送(超时或者包大小足够)。那么这样的话,服务器在接收到消息(数据流)的时候就无法区分哪些数据包是客户端自己分开发送的,这样产生了粘包;服务器在接收到数据库后,放到缓冲区中,如果消息没有被及时从缓存区取走,下次在取数据的时候可能就会出现一次取出多个数据包的情况,造成粘包现象(确切来讲,对于基于TCP协议的应用,不应用包来描述,而应 用 流来描述),个人认为服务器接收端产生的粘包应该与linux内核处理socket的方式 select轮询机制的线性扫描频度无关。
UDP:本身作为无连接的不可靠的传输协议(适合频繁发送较小的数据包),他不会对数据包进行合并发送(也就没有Nagle算法之说了),他直接是一端发送什么数据,直接就发出去了,既然他不会对数据合并,每一个数据包都是完整的(数据+UDP头+IP头等等发一次数据封装一次)没有粘包。
分包产生的原因就简单的多:可能是IP分片传输导致的,也可能是传输过程中丢失部分包导致出现的半包,还有可能就是一个包可能被分成了两次传输,在取数据的时候,先取到了一部分(还可能与接收的缓冲区大小有关系),总之就是一个数据包被分成了多次接收。
粘包与分包的处理方法:
一个是采用分隔符的方式,即我们在封装要传输的数据包的时候,采用固定的符号作为结尾符(数据中不能含结尾符),这样我们接收到数据后,如果出现结尾标识,即人为的将粘包分开,如果一个包中没有出现结尾符,认为出现了分包,则等待下个包中出现后 组合成一个完整的数据包,这种方式适合于文本传输的数据,如采用/r/n之类的分隔符;
另一种是采用在数据包中添加长度的方式,即在数据包中的固定位置封装数据包的长度信息(或可计算数据包总长度的信息),服务器接收到数据后,先是解析包长度,然后根据包长度截取数据包(此种方式常出现于自定义协议中),但是有个小问题就是如果客户端第一个数据包数据长度封装的有错误,那么很可能就会导致后面接收到的所有数据包都解析出错(由于TCP建立连接后流式传输机制),只有客户端关闭连接后重新打开才可以消除此问题,我在处理这个问题的时候对数据长度做了校验,会适时的对接收到的有问题的包进行人为的丢弃处理(客户端有自动重发机制,故而在应用层不会导致数据的不完整性);
TCP 粘包问题:
由于 TCP 协议是基于字节流并且无边界的传输协议, 因此很有可能产生粘包问题。 此外,发送方引起的粘包是由 TCP 协议本身造成的,TCP 为提高传输效率,发送方往往要收集到足够多的数据后才发送一个 TCP 段。若连续几次需要 send 的数据都很少,通常 TCP 会根据优化算法把这些数据合成一个 TCP 段后一次发送出去,但是接收方并不知道要一次接收多少字节的数据,这样接收方就收到了粘包数据。
粘包和拆包产生的原因:
1. 要发送的数据大于 TCP 发送缓冲区剩余空间大小,将会发生拆包。
2. 待发送数据大于 MSS(最大报文长度), TCP 在传输前将进行拆包。
3. 要发送的数据小于 TCP 发送缓冲区的大小, TCP 将多次写入缓冲区的数据一次发送出去,将会发生粘包。(TCP 的延迟确认与拥塞机制, 使用下面两个函数解决)
recv 到数据后每次调用 setsockopt(fd,IPPROTO_TCP, TCP_QUICKACK, (int*){1},sizeof(int));
只需开始设置即可 setsockopt(fd, IPPROTO_TCP,TCP_NODELAY, (int*){1}, sizeof(int));
4. 接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包
粘包处理:
1. 定长数据 不实用,数据短了浪费资源,数据长了不够用
2. 特殊字符分隔符 也不实用,数据本身有这个特殊字符就比较难办了
3. TLV 格式数据 最常用数据格式:type + length + value
TCP和UDP用一个端口发送信息是否冲突
TCP、UDP可以绑定同一端口来进行通信:
端口是一种抽象的软件结构(包括一些数据结构和I/O缓冲区)。应用程序(即进程)通过系统调用与某端口建立连接(binding)后,传输层传给该端口的数据都被相应进程所接收,相应进程发给传输层的数据都通过该端口输出。在TCP/IP协议的实现中,端口操作类似于一般的I/O操作,进程获取一个端口,相当于获取本地唯一的I/O文件,可以用一般的读写原语访问之。 类似于文件描述符,每个端口都拥有一个叫端口号(port number)的整数型标识符,用于区别不同端口。
由于TCP/IP传输层的两个协议TCP和UDP是完全独立的两个软件模块,因此各自的端口号也相互独立,如TCP有一个255号端口,UDP也可以有一个255号端口,二者并不冲突。
端口号的分配有两种基本分配方式:第一种叫全局分配,这是一种集中控制方式,由一个公认的中央机构根据用户需要进行统一分配,并将结果公布于众。第二种是本地分配,又称动态连接,即进程需要访问传输层服务时,向本地操作系统提出申请,操作系统返回一个本地唯一的端口号,进程再通过合适的系统调用将自己与该端口号联系起来(绑扎)。
TCP/IP端口号的分配中综合了上述两种方式。TCP/IP将端口号分为两部分,少量的作为保留端口,以全局方式分配给服务进程。因此,每一个标准服务器都拥有一个全局公认的端口(即周知口,well-known port),即使在不同机器上,其端口号也相同。剩余的为自由端口,以本地方式进行分配。TCP和UDP均规定,小于256的端口号才能作保留端口。
一个服务器监控一个端口,比如80端口,它为什么可以建立上成千上万的连接?
首先,一个TCP连接需要由四元组来形成,即(src_ip,src_port,dst_ip,dst_port)。当一个连接请求过来的时候,服务端调用accept函数,新生成一个socket,这个socket所占用的本地端口依然是80端口。由四元组就很容易分析到了,同一个(src_ip,src_port),它所对应的(dst_ip,dst_port)可以无穷变化,这样就可以建立很多个客户端的请求了。
什么时候是TIME_WAIT状态:客户端接受到服务器发来的FIN包,并且向服务器发出ACK的时候,
客户端变成TIME_WAIT状态,并且等两个MSL时间(一个数据包平均来回时间)就变成CLOSED状态
为什么要等两个MSL:一般情况下一个MSL时间服务器就应该收到了ACK包,客户端等两个MSL就认为服务器收到了ACK,自己就关闭连接
还知道哪些包?
RST:在三次握手过程中,如果客户端发出了ACK包给服务器,客户端认为建立连接,而服务器没收到ACK。如果此时客户端给服务器发数据, 服务器会返回RST(reset),强行关闭连接
socket编程了,具体的系统调用,参数,还有一些场景的分析,
大量TIME_WAIT存在什么问题,如何解决
描述:通常只会在每次由操作系统分配随机端口的程序运行的机器上出现(每次分配随机端口,导致后面无端口可用)。
解决方法 可以用两种思路来解决机器TIME_WAIT过多导致无法对外建立新TCP连接的问题。
1 修改系统配置
需要修改本文前面介绍的tcp_max_tw_buckets、tcp_tw_recycle、tcp_tw_reuse这三个配置项。
1)将tcp_max_tw_buckets调大,从本文第一部分可知,其默认值为18w(不同内核可能有所不同,需以机器实际配置为准),根据文档,我们可以适当调大,至于上限是多少,文档没有给出说明,我也不清楚。个人认为这种方法只能对TIME_WAIT过多的问题起到缓解作用,随着访问压力的持续,该出现的问题迟早还是会出现,治标不治本。
2)开启tcp_tw_recycle选项:在shell终端输入命令
"echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle"可以开启该配置。
需要明确的是:其实TIME_WAIT状态的socket是否被快速回收是由tcp_tw_recycle和tcp_timestamps两个配置项共同决定的,只不过由于tcp_timestamps默认就是开启的,故大多数文章只提到设置tcp_tw_recycle为1。
还需要特别注意的是:当client与server之间有如NAT这类网络转换设备时,开启tcp_tw_recycle选项可能会导致server端drop(直接发送RST)来自client的SYN包。
3)开启tcp_tw_reuse选项:echo1 > /proc/sys/net/ipv4/tcp_tw_reuse。该选项也是与tcp_timestamps共同起作用的,另外socket reuse也是有条件的,
2 修改应用程序
细分为两种方式:
1)将TCP短连接改造为长连接。通常情况下,如果发起连接的目标也是自己可控制的服务器时,它们自己的TCP通信最好采用长连接,避免大量TCP短连接每次建立/释放产生的各种开销;如果建立连接的目标是不受自己控制的机器时,能否使用长连接就需要考虑对方机器是否支持长连接方式了。
2)通过getsockopt/setsockoptapi设置socket的SO_LINGER选项
ping 百度途经的主机是如何展示出来的
在浏览器中输入www.baidu.com后执行的全部过程
答:1、客户端浏览器通过DNS解析到www.baidu.com 的IP地址220.181.27.48,通过这个IP地址找到客户端到服务器的路径。客户端浏览器发起一个HTTP会话到220.181.27.48,然后通过TCP进行封装数据包,输入到网络层。
2、在客户端的传输层,把HTTP会话请求分成报文段,添加源和目的端口,如服务器使用80端口监听客户端的请求,客户端由系统随机选择一个端口如5000,与服务器进行交换,服务器把相应的请求返回给客户端的5000端口。然后使用IP层的IP地址查找目的端。
3、客户端的网络层不用关心应用层或者传输层的东西,主要做的是通过查找路由表确定如何到达服务器,期间可能经过多个路由器,这些都是由路由器来完成的工作,我不作过多的描述,无非就是通过查找路由表决定通过那个路径到达服务器。
4、客户端的链路层,包通过链路层发送到路由器,通过邻居协议查找给定IP地址的MAC地址,然后发送ARP请求查找目的地址,如果得到回应后就可以使用ARP的请求应答交换的IP数据包现在就可以传输了,然后发送IP数据包到达服务器的地址。
浏览器输入url到界面渲染的整个过程
-
浏览器向DNS服务器查找输入URL对应的IP地址。
-
DNS服务器返回网站的IP地址。
-
浏览器根据IP地址与目标web服务器在80端口上建立TCP连接
-
浏览器获取请求页面的html代码。
-
浏览器在显示窗口内渲染HTML。
-
窗口关闭时,浏览器终止与服务器的连接。
get和post的区别
GET - 从指定的服务器中获取数据
POST - 提交数据给指定的服务器处理
GET方法:
使用GET方法时,查询字符串(键值对)被附加在URL地址后面一起发送到服务器:
/test/demo_form.jsp?name1=value1&name2=value2
特点:
-
GET请求能够被缓存
-
GET请求会保存在浏览器的浏览记录中
-
以GET请求的URL能够保存为浏览器书签
-
GET请求有长度限制
-
GET请求主要用以获取数据
POST方法:
使用POST方法时,查询字符串在POST信息中单独存在,和HTTP请求一起发送到服务器:
POST /test/demo_form.jsp HTTP/1.1
Host: w3schools.com
name1=value1&name2=value2
特点:
-
POST请求不能被缓存下来
-
POST请求不会保存在浏览器浏览记录中
-
以POST请求的URL无法保存为浏览器书签
-
POST请求没有长度限制
-
get参数通过url传递,post放在request body中。
-
get请求在url中传递的参数是有长度限制的,而post没有。
-
get比post更不安全,因为参数直接暴露在url中,所以不能用来传递敏感信息。
-
get请求只能进行url编码,而post支持多种编码方式
-
get请求会浏览器主动cache,而post支持多种编码方式。
-
get请求参数会被完整保留在浏览历史记录里,而post中的参数不会被保留。
-
对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
-
GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。
-
GET产生一个TCP数据包;POST产生两个TCP数据包。
长的说:
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
(据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。)
HTTP和HTTPS的基本概念
HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。
HTTPS:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。
HTTPS协议的主要作用可以分为两种:
一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。
HTTP与HTTPS有什么区别
HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。简单来说,HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全。
HTTPS和HTTP的区别主要如下:
1、https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
2、http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
HTTPS的优点
尽管HTTPS并非绝对安全,掌握根证书的机构、掌握加密算法的组织同样可以进行中间人形式的攻击,但HTTPS仍是现行架构下最安全的解决方案,主要有以下几个好处:
(1)使用HTTPS协议可认证用户和服务器,确保数据发送到正确的客户机和服务器;
(2)HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,要比http协议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性。
(3)HTTPS是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。
(4)谷歌曾在2014年8月份调整搜索引擎算法,并称"比起同等HTTP网站,采用HTTPS加密的网站在搜索结果中的排名将会更高"。
HTTPS的缺点
(1)HTTPS协议握手阶段比较费时,会使页面的加载时间延长近50%,增加10%到20%的耗电;(2)HTTPS连接缓存不如HTTP高效,会增加数据开销和功耗,甚至已有的安全措施也会因此被影响;
(3)SSL证书需要钱,功能越强大的证书费用越高,个人网站、小网站没有必要一般不会用。
(4)SSL证书通常需要绑定IP,不能在同一IP上绑定多个域名,IPv4资源不可能支撑这个消耗。
(5)HTTPS协议的加密范围也比较有限,在黑客攻击、拒绝服务攻击、服务器劫持等方面几乎起不到什么作用。最关键的,SSL证书的信用链体系并不安全,特别是在某些国家可以控制CA根证书的情况下,中间人攻击一样可行。
http切换到HTTPS
如果需要将网站从http切换到https到底该如何实现呢?
这里需要将页面中所有的链接,例如js,css,图片等等链接都由http改为https。例如:http://www.baidu.com改为https://www.baidu.com
BTW,这里虽然将http切换为了https,还是建议保留http。所以我们在切换的时候可以做http和https的兼容,具体实现方式是,去掉页面链接中的http头部,这样可以自动匹配http头和https头。例如:将http://www.baidu.com改为//www.baidu.com。然后当用户从http的入口进入访问页面时,页面就是http,如果用户是从https的入口进入访问页面,页面即使https的。
HTTP 的报文段是什么样的。
HTTP请求报文由3部分组成(请求行+请求头+请求体):
下面是一个实际的请求报文:
①是请求方法,GET和POST是最常见的HTTP方法,除此以外还包括DELETE、HEAD、OPTIONS、PUT、TRACE。不过,当前的大多数浏览器只支持GET和POST,Spring 3.0提供了一个HiddenHttpMethodFilter,允许你通过"_method"的表单参数指定这些特殊的HTTP方法(实际上还是通过POST提交表单)。服务端配置了HiddenHttpMethodFilter后,Spring会根据_method参数指定的值模拟出相应的HTTP方法,这样,就可以使用这些HTTP方法对处理方法进行映射了。
②为请求对应的URL地址,它和报文头的Host属性组成完整的请求URL,③是协议名称及版本号。
④是HTTP的报文头,包含若干个属性,格式为"属性名:属性值"服务端据此获取客户端的信息。
⑤是报文体,它将一个页面表单中的组件值通过param1=value1¶m2=value2的键值对形式编码成一个格式化串,它承载多个请求参数的数据。不但报文体可以传递请求参数,请求URL也可以通过类似于"/chapter15/user.html? param1=value1¶m2=value2"的方式传递请求参数。
HTTP 用的什么连接。Http 为什么是无状态的
FPS啥意思?(帧) 帧是什么?你真的理解每秒传输帧数(Frames Per Second是什么吗?
FPS是越高越好,是每秒的帧数,当足够大的时候,肉眼看起来就像是连贯的
测试网络协议有什么思路
qq是怎么实现在线大文件的传输的
如何监控异常流量,如果是脉冲呢?如何和正常流量作区分
如何将大量日志中的异常记录或者错误揪出来
ip地址的ABCD类是怎样分的
IP地址的分类
A类地址:以0开头, 第一个字节范围:1~127(1.0.0.0 - 127.255.255.255);
B类地址:以10开头, 第一个字节范围:128~191(128.0.0.0 - 191.255.255.255);
C类地址:以110开头, 第一个字节范围:192~223(192.0.0.0 - 223.255.255.255);
D类地址:以1110开头,第一个字节范围:224~239(224.0.0.0 - 239.255.255.255)(作多播使用)
E类地址:保留
其中A、B、C是基本类,D、E类作为多播和保留使用。
以下是留用的内部私有地址:
A类 10.0.0.0--10.255.255.255
B类 172.16.0.0--172.31.255.255
C类 192.168.0.0--192.168.255.255
IP地址与子网掩码相与得到网络号:
ip : 192.168.2.110
&
Submask : 255.255.255.0
----------------------------
网络号 :192.168.2 .0
注: 主机号,全为0的是网络号(例如:192.168.2.0),主机号全为1的为广播地址(192.168.2.255)
http状态码
200 - 服务器成功返回网页,客户端请求已成功。
201 -(已创建) 请求成功并且服务器创建了新的资源。
302 - 对象临时移动。服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
304 - 属于重定向。自上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。
401 - 未授权。请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
430 -(禁止) 服务器拒绝请求。
404 - 未找到。服务器找不到请求的网页。
503 - 服务不可用
1xx-临时响应。表示临时响应并需要请求者继续执行操作的状态代码。
2xx - 成功。表示服务器成功地接受了客户端请求。
3xx - 重定向。表示要完成请求,需要进一步操作。客户端浏览器必须采取更多操作来实现请求。例如,浏览器可能不得不请求服务器上的不同的页面,或通过代理服务器重复该请求。
4xx - 请求错误。这些状态代码表示请求可能出错,妨碍了服务器的处理。
5xx - 服务器错误。表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。
ipv6的位数
IPv4的地址长度是32位,IPv6的地址长度是128位。
IPv4和IPv6分别是互联网协议的第四版和第六版。
IPv4:IP地址由4个字节(0~255)构成,共32位。
IPv6:IP地址由16个字节(0~255)构成,共128位。
DNS解析过程
答:当DNS客户机需要在程序中使用名称时,它会查询DNS服务器来解析该名称。客户机发送的每条查询信息包括三条信息:包括:指定的DNS域名,指定的查询类型,DNS域名的指定类别。基于UDP服务,端口53. 该应用一般不直接为用户使用,而是为其他应用服务,如HTTP,SMTP等在其中需要完成主机名到IP地址的转换。
PC网络故障,如何排除障碍
首先判断物理链接是否正常,就是网线有没有接好,路由是否掉线等。然后检查网络连接是否正常,这一步通常是用ping网关来判断,如果能ping通,那就接着检查DNS解析是否正常,通常用nslookup来判断。如果DNS也没有问题,那就是协议层出问题了,查找局域网是否存在ARP攻击。
1. 对称加密算法
一个对称加密算法由五个部分组成:
- 明文:原始消息或数据
- 加密算法
- 密钥
- 密文:使用密钥通过加密算法对明文计算后的结果
- 解密算法:使用密文和相同密钥通过解密算法产生原文
2. 非对称加密算法。与对称加密算法不同的是,非对称加密算法使用的加密密钥和解密密钥是不同的。
https中SSL层原理
SSL证书的原理
在介绍SSL证书前,需要先知道证书的指纹和指纹算法。
指纹是在证书信息(证书机构,公司名,证书有效期等)后面加上一段内容,保证信息没有被修改过。具体操作是将将原来的信息通过指纹算法算法(一个hash算法)计算得到指纹与原信息一起发出去。用户收到这份数据后,首先将原信息用同样的指纹算法计算结果,将得到的结果与指纹对比,如果一致,则说明信息没有被修改过。当然这个过程是有危险的,黑客完全可以修改内容并重新通过指纹算法生成指纹。这里需要使用加密算法来解决这个隐患。
假设一个公司B company向证书机构xxx CA申请SSL证书,他会得到一张类似下面这张图的证书
B company得到这张证书后,会在与用户通信的过程中将证书发送给用户,用户首先会检测办法证书的机构,如果是大家都公认的证书机构,操作系统在出厂时会内置这个机构的机构信息和公钥,例如xxx CA,如果是一个不受信任的证书机构,应用程序(比如浏览器)会发出警告,如果是受信任的证书机构,应用程序会使用预置的xxx CA的公钥去解密最后的指纹内容和指纹算法,然后再把前面的证书内容用指纹算法计算后与指纹内容比对,由于指纹内容是由证书机构唯一的私钥加密的,因此只要比对成功说明证书是没有人被人修改过的。接下来用户就可以放心使用该公司的公钥了。
防火墙:它是一种位于内部网络与外部网络之间的网络安全系统。
4. 抓包
从网络日志中,提取出 date 字段,并排序。
1-100,100个数,取走一个,怎么快速知道我取走了哪个数。
一个数组有一万个数据,只有10个是没有排序的(分布均匀),进行排序。
eclipse的常用操作快捷键
python基础:list和set区别,
python函数传参是值还是引用
python的get和post python的with
大数据会不会?说说hadoop
如何解决IOS与Android的不兼容问题?
Android四大组件;
Android的生命周期;
Android的handle();
讲讲自己印象最深刻的算法题
高流量应对措施
你所了解的大数据的整个流程
场景题,爬虫把多个电商的数据爬取,如何存放,如何找到同一商品最便宜的网址
同步和异步(线程通信的方法、线程的五种状态)
- 建立TCP服务器的各个系统调用。说明socket网络编程有哪些系统调用?其中close是一次就能直接关闭的吗,半关闭状态是怎么产生的?
(3) 对路由协议的了解与介绍。内部网关协议IGP包括RIP,OSPF,和外部网关协议EGP和BGP.
(4) 路由协议所使用的算法。
(7) TCP(UDP,IP)等首部的认识(http请求报文构成)
(8) 网页解析的过程与实现方法
(10)网络层分片的原因与具体实现
(15) 超时重传机制(不太高频)
(16) TCP怎么保证可靠性(面向字节流,超时重传,应答机制,滑动窗口,拥塞控制,校验等)?
(17) 流量控制的介绍,采用滑动窗口会有什么问题(死锁可能,糊涂窗口综合征)?
(18) tcp滑动窗口协议
(19) 拥塞控制和流量控制的区别
(20) TCP拥塞控制,算法名字?(极其重要)
(21) http协议与TCP联系
(22) http/1.0和http/1.1的区别
(23) http的请求方法有哪些?get和post的区别。
(25) http和https的区别,由http升级为https需要做哪些操作
(26) https的具体实现,怎么确保安全性
(27) http中浏览器一个URL的流程,这个过程中浏览器做了什么,URL包括哪三个部分?
(28) 一个机器能够使用的端口号上限是多少,为什么?可以改变吗?那如果想要用的端口超过这个限制怎么办?
(29) 对称密码和非对称密码体系
(30) 数字证书的了解(高频)
(31) 客户端为什么信任第三方证书
(32) RSA加密算法,MD5原理(MD5不算加密算法)
(33) 单条记录高并发访问的优化
(34) 介绍一下ping的过程,分别用到了哪些协议
(35) TCP/IP的分片粘包过程
(36) 有没有抓过TCP包,描述一下
(37) 一个ip配置多个域名,靠什么识别?
(38) 服务器攻击(DDos攻击)
TCP相关技术
1. TCP重发机制,Nagle算法
2. TCP的拥塞控制使用的算法和具体过程
3. TCP的窗口滑动 - TCP客户与服务器模型,用到哪些函数
- UDP客户与服务器模型,用到哪些函数
- 域名解析过程,ARP的机制,RARP的实现
1. RARP用于无盘服务器,开机后通过发送RARP包给RARP服务器,通过mac地址得到IP地址 - Ping和TraceRoute实现原理
(1) Ping是通过发送ICMP报文回显请求实现。
(2) TraceRoute通过发送UDP报文,设置目的端口为一个不可能的值,将IP首部中的TTL分别设置从1到N,每次逐个增加,如果收到端口不可达,说明到达目的主机,如果是因为TTL跳数超过,路由器会发送主机不可达的ICMP报文。
http/https 1.0、1.1、2.0
1. http的主要特点:
简单快速:当客户端向服务器端发送请求时,只是简单的填写请求路径和请求方法即可,然后就可以通过浏览器或其他方式将该请求发送就行了
灵活: HTTP 协议允许客户端和服务器端传输任意类型任意格式的数据对象
无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接,采用这种方式可以节省传输时间。(当今多数服务器支持Keep-Alive功能,使用服务器支持长连接,解决无连接的问题)
无状态:无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。即客户端发送HTTP请求后,服务器根据请求,会给我们发送数据,发送完后,不会记录信息。(使用 cookie 机制可以保持 session,解决无状态的问题)
2. http1.1的特点
a、默认持久连接节省通信量,只要客户端服务端任意一端没有明确提出断开TCP连接,就一直保持连接,可以发送多次HTTP请求
b、管线化,客户端可以同时发出多个HTTP请求,而不用一个个等待响应
c、断点续传ftghh
3. http2.0的特点
a、HTTP/2采用二进制格式而非文本格式
b、HTTP/2是完全多路复用的,而非有序并阻塞的——只需一个HTTP连接就可以实现多个请求响应
c、使用报头压缩,HTTP/2降低了开销
d、HTTP/2让服务器可以将响应主动"推送"到客户端缓存中
get/post 区别
1 2 3 4 5 6 7 8 9 10 11 | 区别一: get重点在从服务器上获取资源,post重点在向服务器发送数据; 区别二: get传输数据是通过URL请求,以field(字段)= value的形式,置于URL后,并用"?"连接,多个请求数据间用"&"连接,如http://127.0.0.1/Test/login.action?name=admin&password=admin,这个过程用户是可见的; post传输数据通过Http的post机制,将字段与对应值封存在请求实体中发送给服务器,这个过程对用户是不可见的; 区别三: Get传输的数据量小,因为受URL长度限制,但效率较高; Post可以传输大量数据,所以上传文件时只能用Post方式; 区别四: get是不安全的,因为URL是可见的,可能会泄露私密信息,如密码等; post较get安全性较高; |
返回状态码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 200:请求被正常处理 204:请求被受理但没有资源可以返回 206:客户端只是请求资源的一部分,服务器只对请求的部分资源执行GET方法,相应报文中通过Content-Range指定范围的资源。 301:永久性重定向 302:临时重定向 303:与302状态码有相似功能,只是它希望客户端在请求一个URI的时候,能通过GET方法重定向到另一个URI上 304:发送附带条件的请求时,条件不满足时返回,与重定向无关 307:临时重定向,与302类似,只是强制要求使用POST方法 400:请求报文语法有误,服务器无法识别 401:请求需要认证 403:请求的对应资源禁止被访问 404:服务器无法找到对应资源 500:服务器内部错误 503:服务器正忙 |
http 协议头相关
http数据由请求行,首部字段,空行,报文主体四个部分组成
首部字段分为:通用首部字段,请求首部字段,响应首部字段,实体首部字段
https与http的区别?如何实现加密传输?
- https就是在http与传输层之间加上了一个SSL
-
对称加密与非对称加密
浏览器中输入一个URL发生什么,用到哪些协议?
浏览器中输入URL,首先浏览器要将URL解析为IP地址,解析域名就要用到DNS协议,首先主机会查询DNS的缓存,如果没有就给本地DNS发送查询请求。DNS查询分为两种方式,一种是递归查询,一种是迭代查询。如果是迭代查询,本地的DNS服务器,向根域名服务器发送查询请求,根域名服务器告知该域名的一级域名服务器,然后本地服务器给该一级域名服务器发送查询请求,然后依次类推直到查询到该域名的IP地址。DNS服务器是基于UDP的,因此会用到UDP协议。
得到IP地址后,浏览器就要与服务器建立一个http连接。因此要用到http协议,http协议报文格式上面已经提到。http生成一个get请求报文,将该报文传给TCP层处理。如果采用https还会先对http数据进行加密。TCP层如果有需要先将HTTP数据包分片,分片依据路径MTU和MSS。TCP的数据包然后会发送给IP层,用到IP协议。IP层通过路由选路,一跳一跳发送到目的地址。当然在一个网段内的寻址是通过以太网协议实现(也可以是其他物理层协议,比如PPP,SLIP),以太网协议需要直到目的IP地址的物理地址,有需要ARP协议。安全相关
- SQL注入
- XSS
- RCFS
- APR欺骗
传输层
既然有了IP协议,能将数据发送到指定的主机为什么还要由传输层。原因有两点:
-
IP协议提供的是不可靠的传输协议,它只是尽力将数据发送到目标主机,但是如果数据丢包,数据损坏,它都不能提供任何解决办法;
-
IP协议只是将数据发送到了目标主机,但是应该由哪个应用程序来接受这个数据包呢?IP协议没有办法告诉我们。
因此传输层的作用就是为了实现以上两点目的。
传输层协议有 TCP 协议和 UDP 协议。TCP 协议是面向有连接的协议,也就是说在使用 TCP 协议传输数据之前一定要在发送方和接收方之间建立连接。一般情况下建立连接需要三步,关闭连接需要四步。
TCP概述: TCP 协议是面向有连接的协议,还有数据重传、流量控制等功能,TCP 协议能够正确处理丢包问题,保证接收方能够收到数据,与此同时还能够有效利用网络带宽。然而 TCP 协议中定义了很多复杂的规范,因此效率不如 UDP 协议,不适合实时的视频和音频传输。
UDP概述: UDP 协议是面向无连接的协议,它只会把数据传递给接收端,但是不会关注接收端是否真的收到了数据。但是这种特性反而适合多播,实时的视频和音频传输。因为个别数据包的丢失并不会影响视频和音频的整体效果。
IP 协议中的两大关键要素是源 IP 地址和目标 IP 地址。而刚刚我们说过,传输层的主要作用是实现应用程序之间的通信。因此传输层的协议中新增了两个要素:源端口号,目标端口号。再加上IP首部中的协议号,通过这五个信息,可以唯一识别一个通信。用一句话来概括就是:"源 IP 地址,目标 IP 地址,源端口号,目标端口号和协议号"这五个信息只要有一个不同,都被认为是不同的通信。
端口号
作用:用于区分同一台主机中正在通信的不同应用程序,因此也被称为程序地址。不同的端口用于区分同一台主机上不同的应用程序。假设你打开了两个浏览器,浏览器 A 发出的请求不会被浏览器 B 接收,这就是因为 A 和 B 具有不同的端口。
分为两种:
1. 知名端口号:这种端口号是固定的,用于服务器程序,使用对应协议的程序就将端口号设为对应的数字。比如DNS的端口号就是53.
2. 动态端口号:这种端口号是不固定的,用于客户端程序,客户端程序对端口号要求不高,只要该端口号在本机中唯一就行。
常见的知名端口号:
端口号 | 协议 |
53 | DNS |
80 | HTTP |
20 | FTP数据 |
21 | FTP控制 |
23 | SSH |
25 | SMTP |
TCP与UDP区别
-
TCP基于有连接,UDP基于无连接。有连接就是TCP在传输前先发送连接请求和应答包,确定双方能够正常传输后,才开始进行数据传输。无连接就是UDP在发送数据之前,并不考虑对方能否接受到,甚至目的地址可能都是无效;
-
TCP能保证可靠传输,UDP不能保证可靠传输TCP。所谓可靠就是TCP能保证把数据一定送到目的地址。为了实现可靠,TCP采用有连接的,超时重传,应答机制等。而UDP则没有这些,也不能保证数据一定能送到;
-
TCP结构复杂,消耗资源多,建立过程较慢较复杂。UDP结构简单,消耗资源少,建立过程较快;
-
TCP基于流模式,UDP是数据报模式。TCP把数据看成一连串无结构的字节流,没有边界,一段段传输构成了整个数据块。通过发送缓冲区和接受缓冲区来存储数据流。而UDP数据报模式,每一个数据报都是一个独立的对象,有着指定的大小。
-
TCP连接只能是点到点,而UDP可以一对一,一对多或者多对多。TCP只能是点到点原因很简单,因为TCP的传输前要先建立连接。因此,广播和多播只能采用UDP数据报的方式。
-
TCP有确认,重传,拥赛控制机制,UDP在没有建立连接或者对方已经退出的情况下任然会继续发送数据,导致通信流量的浪费。
用途
TCP:用于实现可靠传输的情况,文件非常重要,对网络拥堵有较高要求的情况。
UDP:
1. 用于高速传输和实时性较高的场合(即时通信)。对于采用UDP的实事视频通信,如果出现丢包也只会出现短暂卡顿,但是如果采用TCP丢包后需要重发,会导致很长时间的卡顿。
2. 包总量较少的通信(DNS),客户端较多
3. 广播通信
UDP首部
-
源端口号:表示发送端端口号,不需要时设为0
-
目标端口号:表示接收端端口号
-
包长度:表示整个UDP包的长度
-
校验和:为了提供可靠的UDP首部和数据而设计,只要源IP地址,目标IP地址,源端口号,目标端口号,协议号有一个发生了篡改校验和都会不正确。
TCP首部
-
源端口号:发送端端口号
-
目标端口号:接受端端口号
-
序列号:发送数据时,表示发送数据的位置,发送完一次数据后,序列号的值都等于原来的序列号加上数据的长度
-
应答号:用于接受端告诉发送端下次应该从哪个位置开始发送,表示前面的数据已经都收到了
-
数据偏移:实际就是TCP首部长度
-
保留:一般设置为0,用于后续扩展
-
控制位:长度为8,从左到右分别是CWR,ECE,URG,ACK,PSH,RST,SYN,FIN
-
窗口大小:能够发送数据的最大值,为0时可以发送探测窗口
-
校验和:与UDP校验和作用相同
-
紧急指针:用于处理紧急情况
-
选项:其他控制设置
TCP是如何确保可靠传输的?
为了保证可靠传输,TCP比UDP多了很多控制协议和算法。
-
连接管理——3次握手和4次握手
-
数据破坏——通过校验和
-
丢包——应答与超时重发机制
-
分片乱序——序列号
-
窗口滑动——提高发送效率,对发送端和接收端流量进行控制
-
加快通信速度——快速重发,三次收到重发消息进行重发
-
流控制——避免网络流量浪费
-
拥塞控制——慢启动算法,拥塞窗口
TCP中的确认应答机制
在TCP中当发送端的数据达到接受主机时,接受主机端都会返回一个消息,告诉对方我已经收到了。这个消息叫确认应答。发送确认应答时,TCP首部中的ACK标志位设1。
TCP中的确认应答通过序列号和确认应答号来实现。如下图所示,主机A发送第一个包时序列号为1,数据长度为1000,那么主机B收到包后发送一个数据包给主机A,在该包中将TCP首部中的32位确认号设为1001.相当于告诉对方1001之前的我都收到了,下次从1001开始发。
经受时延的确认应答:为了降低确认应答包的数量,TCP提出了经受时延的确认应答。接受端在收到数据后并不立即发送一个应答数据包,而是等待一段时间,如果有新的数据被接受就更新应答号,如果有其他数据要发送就坐上该数据包的顺风车。在系统的内核中维持了一个定时器,一般是200ms如果定时器溢出,即使没有其他数据到达,也发送该应答数据包。
Nagle算法: TCP是基于流的传输协议,在Rlogin和Telnet传输中会出现只有一个字节数据的TCP数据包。而一个TCP数据包的首部加上IP首部就有40个字节,很显然发这样的数据包划不来。为了减少这样的数据包,有人提出了Nagle算法。
Nagle算法简单讲就是,等待服务器应答包到达后,再发送下一个数据包。数据在发送端被缓存,如果缓存到达指定大小就将其发送,或者上一个数据的应答包到达,将缓存区一次性全部发送。
Nagle算法是从发送端角度考虑减少了数据包的个数,时延应答从接收端角度考虑减少了数据包的个数。
TCP的连接与断开(3次握手和4次握手)
-
建立连接
-
客户端发送请求包,告诉服务器:"我想和你通信?"数据包中SYN位置为1,假设其序列号为x,客户端状态变成SYN_SENT;
-
服务器端接受到请求包后也发送一个请求包,告诉客户端:"现在可以建立连接"。数据包中SYN位置位1,假设其序列号为y,注意客户端序列号和服务器端序列号并没有关系,他们是由各自的内核按照一定的规则生成的。但是这个应答包的32位应答号,必须是x+1,之所以加1是因为客户端发过来的包SYN位被认为占一个数据。因此,告诉下一包从x+1开始发。发送后,服务器从监听状态变成SYN_RCVD状态。
-
客户端发送应答数据包,告诉服务器:"那我们开始发送数据吧"。数据包应答号为y+1。客户端变成ESTABLISHED状态,即可以传输状态。
-
服务器端接受到应答数据包后,变成ESTABLISHED状态。
-
-
发送数据
-
客户端发送一个一个字节的数据,因此序列号为x+1;
-
服务端发送一个应答包,应答号为x+2,告诉客户端下次从x+2开始发;
-
-
断开连接
-
客户端发送请求断开的数据包,告诉服务器:"数据传完了,我要断开了"。发送一个FIN包,序列号x+2。客户端转移到FIN_WAIT_1状态。
-
服务器端发送应答包,告诉客户端:"行,我知道了,你断开吧!"。应答号为x+3,服务器进入CLOSE_WAIT状态。客户端收到应答后,转移到FIN_WAIT_2状态。
-
服务器发送一个断开数据包,告诉客户端:"既然传完了,那我这边的开关也准备关了"。序列号为y+1,发送完后服务器进入LAST_ACK状态。
-
客户端发送一个应答包,告诉服务器:"好的,我知道你要断开了。"应答号为y+2。客户端进入TIME_WAIT状态。
TIME_WAIT又称为2MSL等待状态,MSL是系统中定义的最大报文生存时间,任何TCP报文在网络中生存时间超过这个值就必须被丢弃。
等待MSL的原因是防止最后一个ACK丢失后可以进行重发,如果ACK丢失后,服务器会重发FIN。
-
TCP状态迁移图:
其中:CLOSING状态是同时打开才发生的
为什么是3次和4次
为什么是3次
可能你会认为第3次好像是多余的。是因为信道是不可靠的,可能存在延时或者丢包,而三次是满足可靠传输的最小次数。
举例说明:如果只有两次,假设主机A发送的第一个请求包延时,主机A在等待一段时间后重新发送一个请求包,完成数据连接并断开。但是这个时候上次的发的请求包才到达主机B,这时主机B认为是又一次连接,因此发送一个请求包给A,但是A并没有发送新的请求因此会丢失该数据包。最后,B就一直等待A发送数据,浪费了资源。
除此之外,我个人认为3次握手更加安全,加大了攻击的难度。如果只有两次,一个发送一个应答,那么攻击着可以采用IP欺骗,发动SYN洪水攻击,并且服务端还都是ESTABLISHED状态。如何防御?难度更大了。对于三次握手的可以限制半连接的数量来达到一个防御的作用。
为什么是4次
TCP通信是一种全双工的通信,可以进行半关闭(与半打开区别:半打开是连接后的客户端和服务端有一端异常关闭了),所谓半关闭是指可以只关闭从A到B的方向,而B到A的方向还可以继续传输。因此,在客户端和服务器端分别进行关闭。
TCP窗口
窗口是TCP中为了解决应答机制等待时间过长而引入的方法,如果没有窗口,则TCP每发送一次数据就必须等待应答,收到应答后继续发送,如果没有收到则等待一段时间后重发,如果很长时间都无法收到应答则判断为网络断开。而使用窗口后,窗口的大小指无需等待应答可以连续发送多个数据包。
下图中窗口的大小为4000,一次性发送了4个数据包,每个数据包大小为1000。
TCP窗口在每个传输方向都有两个窗口,发送端窗口和接受端窗口,又因为TCP是全双工通信,因此有四个窗口。
发送端窗口
接收端窗口
发送端窗口分为已经发送但是未接到回应的部分和可以被发送的部分
接收端端口大小 = 被分配缓存区 - 已接受确认等待被进程消耗的区域,发送端窗口的大小有ACK应答包中的窗口大小确认。
窗口滑动
发送端窗口,根据应答包的确认号确定窗口的位置,根据应答包中窗口的大小确定窗口的大小,窗口是从左向右逐渐滑动。
窗口合拢:由左端边缘向右靠近,称为窗口合拢,在接受到数据后发生。
窗口张开:右右端向右移动,称为窗口打开,在处理完数据后发生。
如果接收端发送的应答包中窗口大小为0,则客户端会等待一段时间后发送探测包,重新确认窗口的大小。接受端如果处理完了数据也会重新发送应答包,通知发送端。反正死锁的发生。
引入窗口后,TCP的应答包如果部分丢失,无需重传,由后面的应答包保证。TCP为了提高效率,采用延时再确认应答,和选择性确认应答,即收到数据包后不立即发送应答包,而是等待收到下一个或多个包后发一个应答。
超时和重传
TCP是可靠的传输协议,意味着必须按序,无差错的传送数据和目的端。通过校验和,确认应答,重传来保证。校验和应答已经介绍过,这里主要讲解重传机制。重传分为两种:超时重传和快速重传。
超时重传(RTO)
当一个包被发送后,就开启一个定时器,如果定时时间到了,还未收到能确认该发送包的应答包,就重传一份数据。注意收到的应答包可能是该包也可能是后面包的,但是只要能确认该包被收到就行。另外如果,是因为网络延时造成重传,则接受端收到重复数据包后丢弃该包。
快速重传
当如果发送端收到一个包的三次应答包后,立即重传,比超时重传更高效。
拥塞控制
流量是根据发送方和接受方的缓冲区大小来确定的,保证数据处理不出现拥堵,具体实现方法是窗口滑动。而拥塞机制是考虑到网络中的拥堵,比如路由器要处理的数据过多,导致缓冲区溢出而丢包。而拥塞处理就是来解决这种情况,避免网络出现过载的现象。
判定拥塞出现的条件:网络中出现分组丢失(发生超时或收到重复确认)
拥塞避免算法中用到了慢启动,快速重传,快速恢复。
拥塞避免算法需要维持两个变量:拥塞窗口和慢启动阀值。
慢启动算法(工作过程如下图所示):设置初始拥塞窗口大小为1,以后每收到一个应答拥塞窗口大小就加1(图中指定一个窗口大小是1000个字节),窗口大小呈指数级增长。客户端可发送数据的取拥塞窗口和应答包窗口两者中较小的那个。
拥塞避免算法:拥塞避免算法与慢启动的区别在于,收到一个应答后,拥塞窗口大小cwnd只增加1/cwnd。窗口大小整体呈现线性增长。
拥塞控制算法:
拥塞控制算法先采用慢启动算法,到达慢启动阀值后采用拥塞避免算法。
-
通信开始时,发送方的拥塞窗口大小为 1。每收到一个 ACK 确认后,拥塞窗口大小加1。
-
由于指数级增长非常快,很快地,就会出现确认包超时,认为发生了拥塞。
-
此时设置一个"慢启动阈值",它的值是当前拥塞窗口大小的一半。
-
拥堵发生后将拥塞窗口大小设置为 1,重新进入慢启动过程。
-
由于现在"慢启动阈值"已经存在,当拥塞窗口大小达到阈值后,停止使用慢启动算法,开始采用拥塞避免算法。窗口大小开始线性增加。
-
随着窗口大小不断增加,如果收到三次重复确认应答,则进入"快速重发"阶段。对于这用拥塞情况,TCP 将"慢启动阈值"设置为当前拥塞窗口大小的一半,再将拥塞窗口大小设置成阈值大小(也有说加 3)。然后采用拥塞避免算法增加窗口大小。
-
随着窗口大小不断增加,如果发生超时。对于这种拥塞情况,TCP将满启动阀值设置为当前拥塞窗口的一半,然后将拥塞窗口设置为1。
下图为拥塞控制过程中,拥塞窗口的大小变化图。有了拥塞窗口后,实际窗口的大小为拥塞窗口和ACK包中传递的窗口大小两个中的最小值。
TCP不对ACK应答报文进行确认,如果接受端缓冲被占满,发送一个窗口为0的应答,过了一段时间数据处理完毕,重新发送一个应答,告诉发送端窗口大小。不幸的是,如果这个包丢了,就会进入死锁状态——发送端等待更新窗口的应答包,接收端等待接收数据。
为了避免死锁了发生,TCP使用了一个坚持定时器来周期性地向接收方查询,以便发现窗口是否已经增大。这一过程也被称为窗口探查。
远景能源
跟CVTE的一面类似,也是C++基础和网络基础占主体,其中有道题比较有意思,问的是堆排序和快排的时间复杂度都是nlogn,那两者的区别是啥?用哪个会更快一点,为什么?(快排更好,高速缓存的原因,堆排序的局部性差)
TCP的粘包和拆包问题(问的很深)
说了一下5G目前的进展
三次握手中可能出现的攻击与防范
服务端的socket构建过程,不是简单说bind,listen用来怎么怎么做,细化到具体参数怎么设计(不会)。
抓过TCP包吗?TCP包怎么构成
端口号最大是多少,如果需要更多的呢?
详细聊聊ICMP
路由协议了解吗?说说
http请求报文的组成
聊聊traceroute
在浏览器输入一个URL后发生的事情
OSA七层协议,交换机(XXX)属于哪一层
了解网络层的协议吗,分别有哪些
端口号的上限,以及原因
https属于哪个端口,FTP呢?
https和http的区别
描述三次握手四次挥手的11种状态,三次握手之间可能存在什么攻击(DDos攻击)
说说DNS的原理,具体工作原理(我没说清楚)
讲讲ping的具体工作,用到哪些协议(这一块要熟一点,不要只记住用了哪些协议,要深挖怎么工作)