以太网尾部:帧校验和FCR:4个字节
6字节:为逻辑链路层的封装。
数据链路层:封装目的Mac地址:6字节;源Mac地址:6字节;网络协议:2字节,共14个字节。
网络层:封装IP目的、源IP及其他标志总共20个字节。
传输层:封装目的、源端口及其他标志总共20个字节。
4 + 6字节数据(这个是以网络传输的solt time时间来决定的) + 14 + 20 + 20 = 64字节。
最小帧第度保证有足够的传输时间用于以太网接口卡精确的检测冲突,这一最小时间是根据网络的最大电缆长度和帧沿电缆长度传播所要求的时间确定的。
CSMA/CD: 带冲突检测的载波侦听多路访问。
特征:
1)空闲发送:先检测链路是否空闲,再判断是否发送数据。
2)边听边发:一边发送,一边侦听冲突。
3)遇到冲突时,停止发送,并伺机重发。
帧长会造成发送主机长时间占用信道,同时发送的接收缓存的设计也要相应增大,会阻碍发送接收效率。
1)面向连接:要连接三次握手来保证连接性建立
2)可靠性:针对比特错误–> 包乱序、包重传、丢包情况进行处理。
---->处理方式:快速重传、超时重传、窗口管理、流量管理、拥塞控制。
---->快速重传、超时重传处理包错误丢包情况;通过TCP接收缓存乱序的包重新排序,结合应用层处理,TCP发发送窗口会动态调整发送速率,根据TCP接收端缓存限制及网络拥塞情况避免网络拥塞或接收缓存满而大量丢包的情况 。
3)字节流:应用层发送的数据会在TCP的发送端缓存起来,统一分片或打包发送,到接收端时,接收端也是按字节流将数据传递给应用层。
环回地址:ip为127.0.0.1
localhost:
环回接口:lo(loopback interface)
应用: 使运行在同一主机的client与server能通过TCP/IP通信。
外网1 - -(skb)- ->> VPN1网关 - -(重新封装成VPN加密包)- ->> 广域网 - -(VPN加密包)- ->> VPN2网关 - -(skb)- ->> 外网2
NITZ : 网络标识和时区,从营运商获取
NTP : 网络时间协议,从NTP Server获取
1)监听网络状态变化
2)当网络状态变化时,发送广播
3)当一种网络类型断开后,可切换到另一种可用网络
4)对外提供可用网络的信息状态
5)应用可以请求选择哪种网络并通过自己想要的数据传输
过程:UI --> FW --> Netd --> Kernel --limit Alert–> Netd --> FW --> UI
UI通过NetworkPolicyManager的setNetworkPolicies()去限定。
1)流量限制
2)流量警告
3)流量统计
4)后台限制
app的流量控制 : 通过各自的UID去判断。
1)流量控制是一种预防发送端过多的向接收端发送数据的机制。
2)TCP流量控制主要用于匹配发送端和接收端的速度,即根据接收端当前的接收能力来调整发送端的发送速度。
3)TCP连接的每一方都要通告自己的接收窗口(rwnd),而作为发送数据的一方,发送窗口绝对不能超过接收方给出的接收窗口。
4)用户平台通常是做为客户端从服务器下载数据,因此用户平台的接收窗口很可能成为瓶颈。
流量控制的影响因素:
早期TCP的实现中,接收缓存实际上是固定大小的,根据不同的网络不同平台不同需求,需要手动去调整大小,这时候就显得很费时费力了。TCP接收缓存设置小了,不能充分利用网络,因为限制了接收窗口的接收上限,也限制了发送端的发送窗口增长,从而导致发送方有空闲的时间去等待对端ack回应,导致无法充分发送数据。然而TCP接收缓存设置大了,则有可能会浪费内存。因为,才有了动态调整算法的出现。
A、接收缓存的动态调整
1)查看/proc/sys/net/ipv4/tcp_moderate_rcvbuf,这个打开,才会进行缓存自动调整,目前默认是打开的,为1
2)如果使用setsockopt去对当前socket打标签,则不会进行缓存区自动调整,这时要注意设置较大的值,以免跟不上发送端拥塞窗口的增长速度,导致无法充分利用网络接收数据。
3)tcp_adv_win_scale
4)接收端的接收窗口上限和接收缓冲区大小,是接收方应用程序在上个RTT内接收并复制到用户空间的数据量的2倍,并且接收窗口上限和接收缓冲区的大小是递增的。这样就能保证接收窗口上限的增长速度不小于拥塞窗口的增长速度,避免接收窗口成为传输瓶颈。
B、接收窗口的动态调整
1)TCP首部中有一个16位的接收窗口字段,它可以告诉对端:“我现在可以接收多少数据”。发送方需要参考接收方ack回来带的windows size来决定自己的发送窗口,如果接收窗口设置小了,那么对发送方来说,会有很多空闲时间是在等待接收方的ack回来。所以,更新window size,才能够继续发送数据,因此对于吞吐量也是有影响的。
2)设置/proc/sys/net/ipv4/tcp_window_scaling为1
3)接收窗口阈值调整算法
tcp协议中的拥塞算法中的慢启动阈值控制拥塞窗口的增长同,在流量控制当中同样有个接收窗口阈值,主要作用是用于作为通告接收窗口的上限。在扩大窗口因子不为0的情况下,接收窗口更新为大概等于剩余缓存的1/2,并且接收窗口也不能大于当前的接收窗口阈值tcp->rcv_ssthresh。因此实际上接收窗口受到了rcv_ssthresh以及接收缓存的限制,如果接收缓存的上限设得太小,那么接收动态调整也受到限制,从而接收窗口受到限制。
tcp_sapce:计算1/2的剩余接收缓存
tcp_full_space:计算当前接收缓存的1/2
ring buffer由block组成,block通过getpagesize()分配内存,每个block划分为多个frame,user依次处理每个block内的数据包,当处理完这个block中的所有frame后,才把这个block返回给kernel。ring buffer是用mmap机制申请的内存并绑定在socket上,所以,只有当socket关闭时,ring buffer才能释放。
数据读取的状态:
1)每个frame抽象为一个结构体,该结构体包含一个field字段
2)Field可以取TP_STATUS_USER或者TP_STATUS_KERNEL,初始化为TP_STATUS_USER
3)如果kernel收到数据包,拷贝到ring buffer的frame后,将该frame的field设置为TP_STATUS_USER
4)user会轮询frame的field字段,如果field为TP_STATUS_USER,user就可以读取该frame存储的数据包。
4个,prequeue,backlog,sk_receive_queue,out_of_oder_queue
1)TCP prequeue中的包会在进程上下文中处理。这时软中断收到的数据放到backlog中。
2)进程在release_sock()中会处理backlog队列中的数据,其实也是把backlog队列中放到sk_receive_queue中最后再处理。所以,backlog可看做是软中断发生时,一个临时存储的queue而已。
3)不处于进程上下文,且当前没有的prequeue没有数据处理,会处理sk_receive_queue
4)还有一个out_of_oder_queue,此队列是用于存放乱序的skb,当接收到skb后,若这个报文可以按seq插入有序的receive队列中,则将其移出out_of_order队列。并更新sk_receive_queue
prequeue作用:是一个TCP接收优化,使得当发生软中断与release_sock之间切换时发生时,可保存数据,使得数据不丢失。但同时也造成ACK的延迟发送。
prequeue的其他弊端:https://blog.csdn.net/dog250/article/details/5464513
目前因为只有使用block socket才会用到prequeue,但大部分server已经使用了epoll方式,所以prequeue在新的kernel版本已经删除了,不再用prequeue了。
commit为: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=v4.19.1&id=e7942d0633c47c791ece6afa038be9cf977226de
网络主要分成:应用层、传输层、网络层IP、逻辑链路层L2、物理层L1
主要是因为网络通信是分层通信的,每层都是独立,网元工作层次不同(如每层的代理不同,如Http代理跟TCP代理是不一样的)