一、网络与网卡
网络:进程与进程间跨主机(Host)通信
网卡:
网卡发送数据:1.填充数据 2.触发发送
网卡接收数据:1.接收数据 2.通过中断把控制权交给OS 3.OS把数据搬给进程
数据经过不断的封装之后才能发送,有不同层次来实现网络,现代网络都是分层讨论的。
二、网络分层
OSI/RM协议:包括体系结构,服务定义,协议规范三级抽象,将网络分为七层。
物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。
TCP/IP协议:分为五层,物理层、数据链路层、网络层、传输层、应用层。
三、UDP 与 TCP
(一)UDP协议(User Datagram Protocol)
职责:在网络层的基础上实现了进程to进程的的通信
特点:不可靠、无连接、面向数据报文
1.包头
UDP协议的包头信息:UDP添加的封装(解包、分用)
特点:
- 定长(8字节):很容易做解包
- 源端口 + 目的端口 :做分用(进程 to 进程)
- 校验和(checkusm):防止错误数据的类似哈希的算法
发送端:hash(有效数据) => h1
接收端:hash(有效数据) => h2
当h1 != h2时,数据一定出错,直接丢弃;h1 == h2时,大概率认为还是数据源数据。
2.发送
- 填充端口
- 计算长度 + 填充长度
- 计算checkusm + 填充checkusm
- 立即将数据交给网络层(UDP协议栈内部没有发送缓冲区)
3.接收
-
从网络层接收数据
-
通过计算校验和检测数据是否出现错误,如果出现错误则直接丢弃
-
数据没有错,根据自己内部维护Map<port,pid>找到对应接收进程(如果找不到对应进程,丢弃)
-
看对应进程是否准备好一块内存,如果暂时没有,需要暂时把数据保存一段时间
-
把数据复制到对应的内存空间 byte[] buf
(二)TCP协议(Transmission Control Protocol)
特点:可靠、有连接、面向字节流
1.包头
特点:
- 源/目的端口号:表示数据从哪个进程来,到哪个进程去
- 32位序号:携带本次发送数据的编号
- 32位确认序号:填写下一个期望收到的第一个字节的编号,该编号之前的数据都已收到
- 4位首部长度:表示头部有多少个4字节,所以TCP头部最大长度为60字节
- 标注位:
URG:紧急指针是否有效
ACK:确认号是否有效
PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走
RST:对方要求重新建立连接;我们把携带RST标识的称为复位报文段
SYN:请求建立连接;我们把携带SYN标识的称为同步报文段
FIN:通知对方,本端要关闭了,我们称携带FIN标识的为结束报文段 - 16位窗口大小:接收端缓冲区大小,用于流量控制
- 16位校验和:发送端填充,CRC校验。接收端校验不通过,则认为数据有问题。
- 16位紧急指针:标识哪部分数据是紧急数据
2.TCP的可靠性
- TCP会尽最大努力讲数据发送给对方
- 如果遇到发送不过去的情况,TCP会告诉进程发送失败
- 保证不会收到错误的数据
- 保证收到的数据一定是有序的
- TCP会根据对方的接收能力和网络线路的承载能力进行流量控制
实现可靠性的机制:确认应答机制(数据编号机制+超时重传机制)、流量控制
3.确认应答机制
(1)应答
确认应答机制:接收方有责任对收到的数据进行确认应答
如果同时收到多份数据,如何确认应答的是那份数据?
对数据进行编号——序列号
报头中的32位序号部分携带本次发送时数据的编号,每个字节占用一个序号,序号采用本次发送数据的第一个字节的编号。
例如:
序号从1开始 [abcd] SN =1 [efgh] SN=5
(2)确认
确认段:一个数据既可以起到发送数据的角色,也可以取到确认的角色。
发送:携带有数据,填写正确的SN,就是发送段。
确认:标志位ack置1,代表起到了确认的作用,需要填写确认序列号(ASN)。
确认序列号:填写下一个期望收到的第一个字节的编号,换言之,ASN之前的数据已经全部收到了。
例如:
序号从1开始 发送[abcd] SN=1 ;确认ack=1,ASN=5
发送[efgh] SN = 5 ; 确认ack=1,ASN=9
ps:发送端和接收段的TCP会维持着各自的发送SN。
(3)超时重传机制
当我们发送了一份数据没有收到应答时,可能发生了什么?
- 对方没有收到 2. 对方收到并且应答了,但应答没有发送过来
我们不应该无限制等下去(超时timeout机制),重新发送数据。
TCP的发送端不用关心没收到应答的原因是什么,统一采用超时重传机制即可。如果接收端真的收到了重复数据,直接丢弃即可。这需要接收端根据数据中的序号进行去重操作。
超时时间的设置:一般这个时间不是一个定长,而是逐步变长。
例如: 在Linux中以500ms为一个单位进行控制,每次判定超时重发的超时时间都是500ms的整数倍。
500ms —> 500ms * 2 —> 500ms * 4 —> 500ms * 8
超时重传具有次数上限,达到上限发送方(TCP)认为本次数据线路出现重大问题。
1. TCP关闭本次连接;
2. TCP会通知进程(在Java中,采用异常方式IOException);
3. TCP会发送一个 reset segment出去。
作为TCP的发送方,经过一段时间之后可以知道线路有问题。
作为TCP的接收方,无法得到线路有问题(无法确定对方没有发送数据,还是发送失败)。
4.连接管理机制(3次握手、4次挥手)
TCP为什么要建立连接?
1.必须确认对方存在才能”可靠“地传输
2.交换一些必要的数据:SN不是直接从1开始,由双方各自随机生成,随后需要交换
(1)三次握手
建立连接阶段:
由于(2)和(3)几乎是同一时间发生的,TCP的segment可以既承载发送数据又承载应答功能,所以(2)(3)会被合并:
从标志位的角度看:
从序列号角度:
从TCP状态变更角度:
CLOSED:虚拟状态
LISTEN:被动连接方(服务器)已启动,但还未建立连接
SYN_RCVD:收到了sync
SYN_SENT:sync已经发送
当双方都处于ESTABLISHED状态时,连接建立。TCP连接是全双工的,双方地位相等,谁都可以通过这条连接发送数据或接收数据。
(2)四次挥手
主动连接方不一定是主动断开方,断开连接中的应答和请求可以合并、也可以不合并,所以分为:三次挥手、四次回收、同时回收。
三次挥手:
四次挥手:
同时回收:
为什么主动关闭方要有TIME_WITE状态,不能直接走到CLOSED?
1.TCP协议内部通过五元组信息区分连接,当一个连接关闭之后,如果直接释放,则五元组信息可能被再次使用。此时收到发送给这条连接的数据时,不知道是发送给旧连接和新连接。
2.防止最后一个ACK丢失,对方超时重发FIN。(当收到重传的FIN时,重制2MSL的等待时间)。
TCP状态转化汇总:
(3)异常关闭
进程收到一个 reset segment之后,TCP直接关闭连接。
TCP异常情况:
- 进程终止:进程 终止会释放文件描述符,任然可以发送FIN,和正常关闭没有区别。
- 机器重启:和进程终止情况相同。
- 机器断电/网线断开:接收端认为连接还在,一旦接收端有写入操作,接收段发现连接已经不在了,就会reset。即使没有写入操作,TCP自己内置了一个保活定时器,会定期询问对方是否还在。一旦对方不在,就会释放连接。
应用层的某些协议也会有这样的检测机制。例如HTTP长连接中,也会定期检测对方的状态。比如QQ断线之后会定期尝试重连。
5.流量控制
(1)滑动窗口机制
刚才我们讨论了确认应答策略,对每一个发送的数据段,都要给一个ACK确认应答。收到ACK后再发送下一个数据段。这样做有一个比较大的缺点,就是性能较差。尤其是数据往返的时间较长的时候。那么我们一次发送多条数据,就可以大大的提高性能(其实是将多个段的等待时间重叠在一起了)。
- 窗口大小指的是无需等待确认应答而可以继续发送数据的最大值。上图的窗口大小就是4000个字节(四个段);
- 发送前四个段的时候,不需要等待任何ACK,直接发送; 收到第一个ACK后,滑动窗口向后移动,继续发送第五个段的数据;依次类推;
- 操作系统内核为了维护这个滑动窗口,需要开辟 发送缓冲区 来记录当前还有哪些数据没有应答;只有确认应答过的数据,才能从缓冲区删掉;
- 窗口越大,则网络的吞吐率就越高;
那么如果出现了丢包,如何进行重传?
- 数据包已经抵达,ACK被丢了。
这种情况下,部分ACK丢了并不要紧,因为可以通过后续的ACK进行确认; - 数据包就直接丢了。
当某一段报文段丢失之后,发送端会一直收到 1001 这样的ACK,就像是在提醒发送端 “我想要的是 1001” 一样;
如果发送端主机连续三次收到了同样一个 “1001” 这样的应答,就会将对应的数据 1001 -2000 重新发送;
这个时候接收端收到了 1001 之后,再次返回的ACK就是7001了(因为2001 - 7000)接收端其实之前就已经收到了,被放到了接收端操作系统内核的接收缓冲区中;
这种机制被称为 “高速重发控制”(也叫 “快重传”)。
(2)流量控制
接收端处理数据的速度是有限的。如果发送端发的太快,导致接收端的缓冲区被打满,这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应。因此TCP支持根据接收端的处理能力,来决定发送端的发送速度。这个机制就叫做流量控制(FlowControl)。
- 接收端将自己可以接收的缓冲区大小放入 TCP 首部中的 “窗口大小” 字段,通过ACK端通知发送端;
- 窗口大小字段越大,说明网络的吞吐量越高; 接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送端;
- 发送端接受到这个窗口之后,就会减慢自己的发送速度;
- 如果接收端缓冲区满了,就会将窗口置为0;这时发送方不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端。
(3)拥塞控制
虽然TCP有了滑动窗口这个大杀器,能够高效可靠的发送大量的数据。但是如果在刚开始阶段就发送大量的数据,仍然可能引发问题。
如何得知网络承载能力? 拥塞窗口
拥塞窗口没有一个精确的值,只能采用一些算法来推算拥塞窗口,这个算法在不断发展中。
方法:慢开始+快增长
当TCP开始启动的时候,慢启动阈值等于窗口最大值;在每次超时重发的时候,慢启动阈值会变成原来的一半,同时拥塞窗口置回1。发送窗口取拥塞窗口和接收窗口的最小值,同样按照滑动窗口机制进行控制。
四、IP协议
- 4位版本号(version):指定IP协议的版本,对于IPv4来说,就是4。
- 4位头部长度(header length):IP头部的长度是多少个32bit,也就是 length * 4 的字节
数。4bit表示最大的数字是15,因此IP头部最大长度是60字节。 - 8位服务类型(Type Of Service):3位优先权字段(已经弃用),4位TOS字段,和1位保留字段(必须置为0)。4位TOS分别表示:最小延时,最大吞吐量,最高可靠性,最小成本。这四者相互冲突,只能选择一个。对于ssh/telnet这样的应用程序,最小延时比较重要;对于 ftp这样的程序,最大吞吐量比较重要。
- 16位总长度(total length):IP数据报整体占多少个字节。
- 16位标识(id):唯一的标识主机发送的报文。如果IP报文在数据链路层被分片了,那么每一个片里面的这个id都是相同的。
- 3位标志字段:第一位保留(保留的意思是现在不用,但是还没想好说不定以后要用到)。第二位置为1表示禁止分片,这时候如果报文长度超过MTU,IP模块就会丢弃报文。第三位表示"更多分片",如果分片了的话,最后一个分片置为1,其他是0。类似于一个结束标记。
- 13位分片偏移(framegament offset):是分片相对于原始IP报文开始处的偏移。其实就是 在表示当前分片在原报文中处在哪个位置。实际偏移的字节数是这个值 * 8得到的。因此, 除了最后一个报文之外,其他报文的长度必须是8的整数倍(否则报文就不连续了)。
- 8位生存时间(Time ToLive,TTL):数据报到达目的地的最大报文跳数。一般是64。每次经过一个路由,TTL -=1,一直减到0还没到达,那么就丢弃了。这个字段主要是用来防止出 现路由循环。
- 8位协议:表示上层协议的类型。
- 16位头部校验和:使用CRC进行校验,来鉴别头部是否损坏。
- 32位源地址和32位目标地址:表示发送端和接收端。
五、数据链路层重点协议
(一)以太网帧格式
- 源地址和目的地址是指网卡的硬件地址(也叫MAC地址),长度是48位,是在网卡出厂时固化的;
- 帧协议类型字段有三种值,分别对应IP、ARP、RARP;
- 帧末尾是CRC校验码。
(二)MTU
MTU相当于发快递时对包裹尺寸的限制。这个限制是不同的数据链路对应的物理层,产生的限制。
以太网帧中的数据长度规定最小46字节,最大1500字节,ARP数据包的长度不够46字节,要在后面补填充位;
最大值1500称为以太网的最大传输单元(MTU),不同的网络类型有不同的MTU;
如果一个数据包从以太网路由到拨号链路上,数据包长度大于拨号链路的MTU了,则需要对数据包进行分片(fragmentation);
不同的数据链路层标准的MTU是不同的;
由于数据链路层MTU的限制,对于较大的IP数据包要进行分包。
将较大的IP包分成多个小包,并给每个小包打上标签;
每个小包IP协议头的 16位标识(id) 都是相同的;
每个小包的IP协议头的3位标志字段中,第2位置为0,表示允许分片,第3位来表示结束标记(当前是否是最后一个小包,是的话置为1,否则置为0);
到达对端时再将这些小包,会按顺序重组,拼装到一起返回给传输层;
一旦这些小包中任意一个小包丢失,接收端的重组就会失败。但是IP层不会负责重新传输数据;
MTU对于TCP协议的影响:
TCP的一个数据报也不能无限大,还是受制于MTU。TCP的单个数据报的最大消息长度,称为MSS(Max Segment Size);
TCP在建立连接的过程中,通信双方会进行MSS协商;
最理想的情况下,MSS的值正好是在IP不会被分片处理的最大长度(这个长度仍然是受制于
数据链路层的MTU);
双方在发送SYN的时候会在TCP头部写入自己能支持的MSS值;
然后双方得知对方的MSS值之后,选择较小的作为最终MSS;
MSS的值就是在TCP首部的40字节变长选项中(kind=2)
(三)ARP协议
ARP协议建立了主机 IP地址 和 MAC地址 的映射关系。文章来源:https://www.toymoban.com/news/detail-444082.html
在网络通讯时,源主机的应用程序知道目的主机的IP地址和端口号,却不知道目的主机的硬件地址;
数据包首先是被网卡接收到再去处理上层协议的,如果接收到的数据包的硬件地址与本机不符,则直接丢弃;
因此在通讯前必须获得目的主机的硬件地址;文章来源地址https://www.toymoban.com/news/detail-444082.html
到了这里,关于网络基本原理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!