udp不存在粘包的问题,因为udp是个数据包协议,也就是两段数据间有界限的。要么收不到,要么全收。
产生粘包的原因:nagle算法为了改善网络传输效率,延迟发送数据。应用层由于某些原因不能及时取出TCP的数据,导致TCP缓冲区存放了多段数据。
解决方式:封包和拆包。包头存放一个变量记录包体的长度。在所发送的内容前,加上发送内容的长度。
使用cookie来管理session以弥补http中无状态特性。通过对set-cookie头域写入session ID可以免登录,提高访问的效率。
握手优化:session缓存, session key 放在内存,有内存消耗, 负载均衡后找不session key。session ticket 集群可以共享。
TCP三次握手:客户端向服务器端:发送SYN=1和序号seq 服务器端向客户端:回应确定信号同意连接ACK=1以及自己的连接请求SYN=1还有序号seq 客户端回应服务器端:ACK=1告诉对方它已经知道了服务器端同意,连接成功。
TCP四次挥手:主动关闭方发送关闭信号,被动关闭方收到信号。然后进入半关闭状态,关闭的一方能接收数据但是不能发送数据。 等到另一个未关闭的一方,发起关闭信号以后,进入TIME_WAIT状态,等待对方2MSL之后,彻底关闭。
超时进入的是慢启动,重复确认才进入快恢复。
选择性重传在options中left edge和right edge告诉发送方已经收到的报文序号
udp不会出现粘包。发送方发送的若干包数据到接收方接收时,包粘在了一起。
造成粘包的原因时因为发送端延迟发送或者接收方没有及时接收缓冲区中的数据。
HTTP协议是一种使用明文数据传输的网络协议。HTTPS协议可以理解为HTTP协议的升级,就是在HTTP的基础上增加了数据加密。在数据进行传输之前,对数据进行加密,然后再发送到服务器。这样,就算数据被第三者所截获,但是由于数据是加密的,所以你的个人信息让然是安全的。这就是HTTP和HTTPS的最大区别。
基于UDP的协议
物数网传会表应 ping是从应用层直接使用网络层的ICMP协议的,不经过传输层。原始套接字直接使用网络层的IP。 两台电脑通信:网线+不同的IP地址和子网掩码,即处于同一网段。 TCP和UDP可以同时使用相同的端口。 应用程序可以同时使用TCP和UDP两个协议。
可以实现多个IP主机通信,但是hub的实现方式是广播,容易产生拥堵。
是集线器的升级版,可以广播可单播。ARP不知道对方MAC地址时,先广播6个ff的MAC地址,所有网卡都会接收,但是只有目的IP会单播回应,其他的都会丢弃。然后发送方收到正确的MAC后再单播传输数据。
给两个MAC地址响应ARP广播的目的IP,经由中间人,窃取信息后再转发到正确的地址。
在同一个交换机连接的网络中,属于同一网段,用不到默认网关。网关用来传递两个不同网段的通信,默认网关通常是路由器。当通信的数据不在当前网段时,即发给默认网关。路由器就是用来连接不同网段的,用来构建一个更大的网络。在传输不同的网段信息时,源IP和目的IP是不变的,源MAC和目的MAC是改变的,每经过一个路由器修改一次,记录的是下一次的目的,和这一次的发送MAC。
ack会随着响应数据发送给对方,如果没有响应的数据就会等待200ms左右,在这期间如果有对方确认到达则立即发送。如果200ms后仍然没有数据需要发送则单独发送ACK。目的是节省带宽。
同时有nagle算法和延迟确认存在时会导致网络效率下降,通常会关闭延迟确认和nagle算法。
setsockopt(s,IPPROTO_TCP,TCP_QUICKACK,(int*){1}, sizeof(int)); //关闭延迟确认
setsockopt(client_fd, SOL_TCP, TCP_NODELAY,(int[]){1}, sizeof(int)); //关闭nagle算法
signal(SIGPIPE, SIG_IGN)
SIGSEGV 11 访问地址无效 SIGIO 29异步通知信号 SIGKILL 9 无条件终止
服务器端处理的时间过长,客户端主动关闭了连接。
transfer-encoding:chunked 响应头域 它允许服务器发送给客户端的数据分成多个部分,并且不需要预先直到发送数据的总大小。
301 move permanently
302 found POST方法的重定向在未询问用户的情况下就变成GET
303 see other POST重定向为GET
307 temporary redirect 当客户端的POST请求收到服务端307状态码响应时,需要跟用户询问是否应该在新URI上发起POST方法,也就是说,307是不会把POST转为GET的。
http2.0 spdy
服务器推送
http3.0 quic+udp
实现机制:由滑动窗口协议(连续ARQ协议)实现。滑动窗口协议既保证了分组无差错、有序接收,也实现了流量控制。主要的方式就是接收方返回的 ACK 中会包含自己的接收窗口的大小,并且利用大小来控制发送方的数据发送
可能会引发死锁,怎么避免:当发送者收到了一个窗口为0的应答,发送者便停止发送,等待接收者的下一个应答。但是如果这个窗口不为0的应答在传输过程丢失,发送者一直等待下去,而接收者以为发送者已经收到该应答,等待接收新数据,这样双方就相互等待,从而产生死锁。为了避免流量控制引发的死锁,TCP使用了持续计时器。每当发送者收到一个零窗口的应答后就启动该计时器。时间一到便主动发送报文询问接收者的窗口大小。若接收者仍然返回零窗口,则重置该计时器继续等待;若窗口不为0,则表示应答报文丢失了,此时重置发送窗口后开始发送,这样就避免了死锁的产生。
流量控制与拥塞控制的区别
拥塞控制:拥塞控制是作用于网络的,它是防止过多的数据注入到网络中,避免出现网络负载过大的情况;常用的方法就是:
流量控制:流量控制是作用于接收者的,它是控制发送者的发送速度从而使接收者来得及接收,防止分组丢失的。
拥塞控制算法
假定:1、数据是单方向传递,另一个窗口只发送确认;2、接收方的缓存足够大,因此发送方的大小的大小由网络的拥塞程度来决定。
发送方维持一个叫做拥塞窗口cwnd(congestion window)的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口等于拥塞窗口,另外考虑到接受方的接收能力,发送窗口可能小于拥塞窗口。
慢开始算法的思路就是,不要一开始就发送大量的数据,先探测一下网络的拥塞程度,也就是说由小到大逐渐增加拥塞窗口的大小
这里用报文段的个数作为拥塞窗口的大小举例说明慢开始算法,实际的拥塞窗口大小是以字节为单位的。如下图:
从上图可以看到,一个传输轮次所经历的时间其实就是往返时间RTT,而且没经过一个传输轮次(transmission round),拥塞窗口cwnd就加倍。
为了防止cwnd增长过大引起网络拥塞,还需设置一个慢开始门限ssthresh状态变量。ssthresh的用法如下:当cwnd < ssthresh时,使用慢开始算法。
注意,这里的“慢”并不是指cwnd的增长速率慢,而是指在TCP开始发送报文段时先设置cwnd=1,然后逐渐增大,这当然比按照大的cwnd一下子把许多报文段突然注入到网络中要“慢得多”。
拥塞避免算法让拥塞窗口缓慢增长,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍。这样拥塞窗口按线性规律缓慢增长。
无论是在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有按时收到确认,虽然没有收到确认可能是其他原因的分组丢失,但是因为无法判定,所以都当做拥塞来处理),就把慢开始门限ssthresh设置为出现拥塞时的发送窗口大小的一半(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。这样做的目的就是要迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕
快重传要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方,可提高网络吞吐量约20%)而不要等到自己发送数据时捎带确认。快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期
https是安全版的http协议。
get用来获取资源,post用来创建资源。
get将数据放在url地址栏中,使用问号与url分割,数据间用取地址符分割。post将数据放在请求体中。
安全性上get放在url容易暴露隐私信息,而post放在请求体中可以适当的避免。
get在传输的数据受url地址栏的限制,post不受这种限制
get的操作是幂等的,多次操作产生的影响相同,而post是非幂等的
TLS握手协议:1.交换加解密的安全套件 2.验证通讯双方的身份 3.协商加密的参数。
https是在TCP之上增加了一层TLS层
TLS1.3版本限定了安全套件的数量,防止低版本的安全组件被暴力破解。开始时客户端发送hello并携带一个自己生成的公钥,服务器端选择一个安全套件并将自己生成的公钥发给客户端,客户端收到公钥以后,两段此时都有一个对方发来的公钥和自己的私钥。此时使用ECDH椭圆曲线非对称加密算法,生成一个相同的密钥,这个密钥就用来进行后续的对称加密。
校验过程:判断数字证书中的哈希值和公钥解码的哈希值是否一致。
长期处于半连接状态可能会造成TCP内核中SYN队列的爆满,服务器会在一定时间内终止半连接,并回收资源。如果使用syn洪泛攻击,也可能造成SYN队列爆满,可以使用SYN cookie来解决这个问题。即SYN到达时并不放入SYN队列中,而是将所有的信息写入cookie,当客户端ACK到达时验证cookie中的信息后再分配资源。
TCP两次握手会产生什么问题:已经失效的连接报文段突然又被服务器端收到,造成双方的不一致,进而造成资源浪费。此时如果服务器端发送连接到失效的请求,并返回SYN和ACK后,自认为连接已经建立好了,所以会频繁的发送数据到客户端,而客户端处于closed状态,直接把数据丢弃。同时如果此时客户端想要建立新连接,但是已经又连接占用,也会导致客户端无法建立真正的需求。当客户端老是收到丢弃的数据,客户端就会发一个RST强制服务端关闭连接。
RST和ACK收到时不用再回ACK
中间人对DNS进行了一些操作导致无法通过域名获得正确的IP。
解决方法:1. 使用第三方DNS解析服务 2.搭建自己的DNS服务器
http协议用韵都是客户端发起请求,服务器返回响应,这样就会使得无法实现客户端未发起的请求,而服务器将消息推送给客户端。
请求报文组成部分:1. 请求行 2.请求头 3. 请求空行 4. 请求体
http在1.1版本中,所有的请求头除host外都是可选的。host主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP的URL中提取出来的。不包含host主机头域,服务器会返回400状态码。
1xx: 提示信息,表示请求已接收,继续处理。
2xx: 成功, 表示请求已被成功接收,理解,接受。
3xx: 重定向, 要完成请求必须进行更进一步的操作。
4xx: 客户端错误,请求有语法错误或请求无法实现。
5xx: 服务器错误,服务器未能实现合法的请求。
ssl通信机制:1. 客户端发送client hello报文开始通信。报文中包含SSL指定版本号,加密组件列表,有加密算法和密钥长度。2. 服务器端回应server hello报文作为应答。筛选出SSL版本和加密组件,并发送CA证书,其中包括公钥。3. 第二次交互,客户端生成一个pre-master secret的随机密码串。并使用CA证书中的公钥加密。
主要区别在于:
https增加了ssl层,用于确保传输的安全性。
通信前先进行ssl层的握手,首先客户端ssl版本号和加密组件发送给服务器端。
服务器端筛选出可用的ssl版本号和加密算法同时加上CA证书发送给客户端。
客户端验证CA证书的有效性,如果无效则中断通信。
若有效客户端发送加密的pre-master secret随机密码串,这一步使用的是非对称加密,用于协商后面对称加密的密钥,所以这一步不能被篡改和截获。客户端得到服务器端的响应后,且验证通过后,后续就使用对称加密加密算法进行加密。然后进行TCP三次握手。