基础网站建设,微信公众号售卖,网站制作的部分,深圳营销型网站建设公司选择哪家好?计算机网络发展简史
1、诞生阶段#xff0c;20世纪60年代中期之前的第一代计算机网络是以单个计算机为中心的远程联机系统。
2、ARPANET#xff0c;多个主机通过通信线路互联起来。60年代初。当时#xff0c;美国国防部为了保证美国本土防卫力量和海外防御武装在受到前苏联…计算机网络发展简史
1、诞生阶段20世纪60年代中期之前的第一代计算机网络是以单个计算机为中心的远程联机系统。
2、ARPANET多个主机通过通信线路互联起来。60年代初。当时美国国防部为了保证美国本土防卫力量和海外防御武装在受到前苏联第一次核打击以后仍然具有一定的生存和反击能力认为有必要设计出一种分散的指挥系统它由一个个分散的指挥点组成当部分指挥点被摧毁后其它点仍能正常工作并且在这些点之间能够绕过那些已被摧毁的指挥点而继续保持联系。这个设计出发点很重要理解了它就能够理解为何后面要学习的TCP要这么设计。为了对这一构思进行验证1969年美国国防部国防高级研究计划署(DODDARPA)资助建立了一个名为ARPANET(即阿帕网)的网络将多个大学的计算机主机联接起来位于各个结点的大型计算机采用分组交换技术通过专门的通信交换机和专门的通信线路相互连接。E-mail、FTP和Telnet在ARPANET上已经诞生。
3、开放性的标准化体系结构OSI诞生。ARPANET兴起后,计算机网络发展迅猛,各大计算机公司相继推出自己的网络体系结构及实现这些结构的软硬件产品。由于没有统一的标准,不同厂商的产品之间互联很困难,人们迫切需要一种开放性的标准化实用网络环境,这样应运而生了两种国际通用的最重要的体系结构, 为了实现网络设备间的互相通讯ISO和IEEE电气和电子工程师协会是世界上最大的非营利性专业技术学会相继提出了OSI参考模型及其TCP/IP模型。由于TCP/IP尽早地制定了可行性较强的协议提出了应对技术快速革新的协议并及时进行后期改良的方案因此打败了OSI模型成为了事实上的标准。
4、Internet互联网
20世纪90年代至今的第四代计算机网络, 就是我们所熟知的Internet互联网。
既然网络是很多的计算设备电脑、手机等等连接在一起的这些计算设备来自不同的公司有不同的体系结构相互之间如何通信呢这就好比我们的语言中国地广人多地方性语言也非常丰富而且方言之间差距巨大。A地区的方言可能B地区的人根本无法听懂所以要为全国进行沟通建立一个语言标准这就是我们的普通话的作用。计算机网络协议同我们的普通话一样帮助我们的计算机之间进行沟通。
想要成为计算机网络领域高手掌握计算机网络领域知识就是必备的而学习计算机网络领域知识过程就是理解网络协议的构成、原理和工作方式的过程。 计算机网络体系结构 osi 学术界大牛提出的理论化角度
tcp是工程师站在实践的角度提出的尽可能实用所以打了很多补丁现在
tcp五层每一层需要记下来
还有osi的七层尽可能记住 OSI七层模型
开放系统互连参考模型 (Open System Interconnect 简称OSI是国际标准化组织(ISO)和国际电报电话咨询委员会(CCITT)联合制定的开放系统互连参考模型为开放式互连信息系统提供了一种功能结构的框架。其目的是为异种计算机互连提供一个共同的基础和标准框架并为保持相关标准的一致性和兼容性提供共同的参考。这里所说的开放系统实质上指的是遵循OSI参考模型和相关协议能够实现互连的具有各种应用目的的计算机系统。
OSI采用了分层的结构化技术共分七层物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。 TCP/IP模型
OSI模型比较复杂且学术化所以我们实际使用的TCP/IP模型分5层物理层、数据链路层也有TCP/IP模型将物理层、数据链路层合称为网络接口层与之对应的协议就被称为TCP/IP四层协议模型、网络层、传输层、应用层。两个模型之间的对应关系如图所示 无论什么模型每一个抽象层建立在低一层提供的服务上并且为高一层提供服务。大致来说可以这么理解只是帮助我们理解实际上肯定会有点出入对于我们的PC机来说物理层可以看成网卡数据链路层可以看成网卡驱动程序网络层和传输层由操作负责处理应用层则是常用的一些网络应用程序和我们自己所编写的网络应用程序。
快速记忆
物理层当成网卡记数据链路层当成驱动记
网络层和传输层当成tcp和ip
应用层当成http mysql这样的自己写的应用 TCP/IP协议族
Transmission Control Protocol/Internet Protocol的简写中译名为传输控制协议/因特网互联协议是Internet最基本的协议、Internet国际互联网络的基础由网络层的IP协议和传输层的TCP协议组成。协议采用了5层的层级结构。然而在很多情况下它是利用 IP 进行通信时所必须用到的协议群的统称。也就是说它其实是个协议家族由很多个协议组成并且是在不同的层 是互联网的基础通信架构。 IP、TCP和UDP
在上述图形中网际协议IP是TCP/IP中非常重要的协议往往用来确定网络中唯一的一台计算设备它的作用就好比我们现实生活中的电话号码或者或者通讯地址。所以这层负责对数据加上IP地址有发送它的主机的地址源地址和接收它的主机的地址目的地址和其他的数据以确定传输的目标。
而TCP和UDP都是传输层的协议传输层主要为两台主机上的应用程序提供端到端的通信。
TCP有点类似于我们日常生活中的打电话电话接通后通过“喂”确认对方身份听不清会要求对方重说对方说的太快了会要求对方说慢点讲完了各说一句“再见”结束通话。TCP提供了一种可靠的数据传输服务TCP是面向连接的也就是说利用TCP通信的两台主机首先要经历一个建立连接的过程等到连接建立后才开始传输数据而且传输过程中采用“带重传的肯定确认”技术来实现传输的可靠性。TCP还采用一种称为“滑动窗口”的方式进行流量控制发送完成后还会关闭连接。
UDPUser Datagram Protocol的简称 中文名是用户数据报协议有点类似于我们日常生活中通过不靠谱的物流系统寄东西。UDP是把数据直接发出去而不管对方是不是在接收也不管对方是否能接收的了也不需要接收方确认属于不可靠的传输可能会出现丢包现象实际应用中要求程序员编程验证。
所以TCP要比UDP可靠的多。
对协议感兴趣的可以去这里看 rfc 注意
我们一些常见的网络应用基本上都是基于TCP和UDP的这两个协议又会使用网络层的IP协议。但是我们完全可以绕过传输层的TCP和UDP直接使用IP比如Linux内核中的LVS负载均衡就可以直接基于IP层进行负载平衡调度这就是越过了tcp这个传输层甚至还可以直接访问链路层比如tcpdump程序就是直接和链路层进行通信的越过传输层和网络层。 TCP/IP网络传输中的数据
每个分层中都会对所发送的数据附加一个首部在这个首部中包含了该层必要的信息如发送的目标地址以及协议相关信息。通常为协议提供的信息为包首部所要发送的内容为数据。在下一层的角度看从上一层收到的包全部都被认为是本层的数据。把上一层的数据封包然后加上本层的东西接着向下层继续发送
网络中传输的数据包由两部分组成一部分是协议所要用到的首部另一部分是上一层传过来的数据。首部的结构由协议的具体规范详细定义。在数据包的首部明确标明了协议应该如何读取数据。反过来说看到首部也就能够了解该协议必要的信息以及所要处理的数据。我们用用户A发送用户B接受来说说明
① 用户A应用程序处理 首先应用程序会进行编码处理产生报文/消息message交给下面的TCP层。
② 用户A TCP 模块的处理 TCP 根据应用的指示负责建立连接、发送数据以及断开连接。TCP 提供将应用层发来的数据顺利发送至对端的可靠传输。为了实现这一功能需要将应用层数据封装为报文段segment并附加一个 TCP 首部然后交给下面的IP层。
③ 用户A IP 模块的处理 IP 将 TCP 传过来的 TCP 首部和 TCP 数据合起来当做自己的数据并在 TCP 首部的前端加上自己的 IP 首部生成IP数据报datagram然后交给下面的数据链路层。
④ 用户A数据链路层的处理 从 IP 传过来的 IP 包对于数据链路层来说就是数据。给这些数据附加上链路层首部封装为链路层帧frame生成的链路层帧frame将通过物理层传输给接收端。
⑤ 用户B数据链路层的处理 用户B主机收到链路层帧frame后首先从链路层帧frame首部找到 MAC 地址判断是否为发送给自己的包若不是则丢弃数据。
如果是发送给自己的包则从以太网包首部中的类型确定数据类型再传给相应的模块如 IP、ARP 等。这里的例子则是 IP 。
⑥ 用户B IP 模块的处理 IP 模块接收到 数据后也做类似的处理。从包首部中判断此 IP 地址是否与自己的 IP 地址匹配如果匹配则根据首部的协议类型将数据发送给对应的模块如 TCP、UDP。这里的例子则是 TCP。
⑦ 用户B TCP 模块的处理 在 TCP 模块中首先会计算一下校验和判断数据是否被破坏。然后检查是否在按照序号接收数据。最后检查端口号确定具体的应用程序。数据被完整地接收以后会传给由端口号识别的应用程序。
⑧ 用户B 应用程序的处理 接收端应用程序会直接接收发送端发送的数据。通过解析数据展示相应的内容。 地址和端口号
MAC 地址
我们常听说 MAC 地址和 IP 地址。
MAC地址全称叫做媒体访问控制地址也称为局域网地址LAN AddressMAC位址以太网地址Ethernet Address或物理地址Physical Address由网络设备制造商生产时写在硬件内部。MAC地址与网络无关也即无论将带有这个地址的硬件如网卡、集线器、路由器等接入到网络的何处都有相同的MAC地址它由厂商写在网卡的BIOS里从理论上讲除非盗来硬件网卡否则是没有办法冒名顶替的。
MAC地址共48位6个字节。前24位由IEEE电气和电子工程师协会决定如何分配后24位由实际生产该网络设备的厂商自行制定。例如FF:FF:FF:FF:FF:FF或FF-FF-FF-FF-FF-FF
MAC地址共48位6个字节。前24位由IEEE电气和电子工程师协会决定如何分配后24位由实际生产该网络设备的厂商自行制定。例如FF:FF:FF:FF:FF:FF或FF-FF-FF-FF-FF-FF IP地址
IP地址Internet Protocol Address的全称叫作互联网协议地址它的本义是为互联网上的每一个网络和每一台主机配置一个唯一的逻辑地址用来与物理地址作区分。
所以IP 地址用来识别 TCP/IP 网络中互连的主机和路由器。IP地址基于逻辑比较灵活不受硬件限制也容易记忆。
IP地址分为IPv4和IPv6。我们这里着重讲的是IPv4地址IP地址是由32位的二进制数组成它们通常被分为4个“8位二进制数”我们可以把它理解为4个字节格式表示为A.B.C.D。其中ABCD这四个英文字母表示为0-255的十进制的整数。例192.168.1.1
TipsIP地址和MAC地址之间的区别
1、对于网络中的一些设备路由器或者是PC及而言IP地址的设计是出于拓扑设计出来的只要在不重复IP地址的情况下它是可以随意更改的而MAC地址是根据生产厂商烧录好的它一般不能改动的一般来说当一台PC机的网卡坏了之后更换了网卡之后MAC地址就会变了。
2、在前面的介绍里面它们最明显的区别就是长度不同IP地址的长度为32位而MAC地址为48位。
3、它们的寻址协议层不同。IP地址应用于OSI模型的网络层而MAC地址应用在OSI模型的数据链路层。 数据链路层协议可以使数据从一个节点传递到相同链路的另一个节点上通过MAC地址而网络层协议使数据可以从一个网络传递到另一个网络上ARP根据目的IP地址找到中间节点的MAC地址通过中间节点传送从而最终到达目的网络。
4、分配依据不同。IP地址的分配是基于我们自身定义的网络拓扑MAC地址的分配是基于制造商。
简化下 mac地址工作在数据链路层 ip地址计算机上网必备的
ip地址和mac地址区别长度不同 一个32位一个48位一个工作网络层一个工作在数据链路层
ip地址好更换mac地址不好更换
同一个子网局域网之类寻址用mac地址做通信子网很多时候以广播形式发送的判定mac地址是不是自己来确定消息是否发送给自己的不同的子网用ip地址 端口号
在传输层也有这种类似于地址的概念那就是端口号。端口号用来识别同一台计算机中进行通信的不同应用程序。因此它也被称为程序地址。
一台计算机上同时可以运行多个程序。传输层协议正是利用这些端口号识别本机中正在进行通信的应用程序并准确地将数据传输。 面试题为什么端口号有65535个
因为在TCP、UDP协议报文的开头会分别有16位二进制来存储源端口号和目标端口号所以端口个数是 2^1665536个但是0号端口用来表示所有端口所以实际可用的端口号是65535个。 端口号的确定
标准既定的端口号这种方法也叫静态方法。它是指每个应用程序都有其指定的端口号。但并不是说可以随意使用任何一个端口号。例如 HTTP、FTP、TELNET 等广为使用的应用协议中所使用的端口号就是固定的。这些端口号被称为知名端口号分布在 0~1023 之间我们在编写自己的网络应用服务时尽量不要使用这些端口号。
时序分配法服务器有必要确定监听端口号以让客户端程序访问服务器上的服务。但是客户端没必要确定端口号。在这种方法下客户端应用程序完全可以不用自己设置端口号而全权交给操作系统进行分配客户端使用的临时端口号操作系统分配的一般都是大于10000的。 观察端口号
Windows下使用netstat -ano 查看所有端口号netstat -ano|findstr “”查看指定端口号。
Linux下可以用root 用户执行 lsof -i:端口号查看指定端口占用。 lsof -i -U显示所有打开的UNIX domain和端口文件
我们用的更多的是netstat
netstat -tunlp 用于显示 tcpudp 的端口和进程等相关情况。
netstat 查看端口占用语法格式
netstat -tunlp | grep 端口号
-t (tcp) 仅显示tcp相关选项
-u (udp)仅显示udp相关选项
-n 拒绝显示别名能显示数字的全部转化为数字
-l 仅列出在Listen(监听)的服务状态
-p 显示建立相关链接的程序名 综述 所以一般来说不管计算机中有多少网卡每个网卡都会有自己的MAC 地址这个MAC 地址是不会变化的。而每个网卡在正常工作的情况下都会有一个IP地址这个IP地址完全是可以变化的。而这台计算机中承载的各种应用程序可以拥有自己的端口号然后通过服务器的网卡正确地进行网络通信。
一台服务器上的不同网络应用程序必须有不同的端口号A程序启动了使用了端口xB程序启动就不能使用端口x否则会报错“Address already in use”。
总的来说操作系统是通过源IP地址、目标IP地址、协议号协议类型、源端口号以及目标端口号这五个元素唯一性的识别一个网络上的通信。 面试题一台主机上只能保持最多 65535 个 TCP 连接对吗
这个说法不对我们分服务器和客户端分开讨论以下的讨论都基于服务器和客户端都只有1个IP地址。
服务端
我们已经知道网络通信五元组是由过源IP地址、目标IP地址、协议号协议类型、源端口号以及目标端口号构成。现在考察的是 TCP 连接自然五元组中的协议号已经定下来了于是网络通信五元组就变化为TCP四元组。
那就是说TCP连接四元组是由源IP地址、源端口、目的IP地址和目的端口构成。
很明显当四元组中任意一个元素发生了改变那么就代表的是一条完全不同的新连接。拿我们常用的MySQL 举例假设它的 IP 是 X端口3306。用户A基于IP地址A1端口PA连接MySQL 于是构成了一个TCP连接四元组(A1,PA,X,3306)。用户B基于IP地址B1端口PB连接同一个MySQL这个时候MySQL需要开启一个新端口来和用户B通信吗从我们日常的开发就可以知道MySQL并不需要这么做所以用户B就和MySQL构成了一个新的TCP连接四元组(B1,PB,X,3306)。
服务端理论上能达成的最高并发数量是多少从我们上面的用户A和用户B构成的TCP连接四元组
(A1,PA,X,3306)
(B1,PB,X,3306)
可以看到目的IP地址和目的端口X,3306是不变的这样就只剩下源IP地址、源端口是可变的。IP 地址是一个 32 位的整数所以源 IP 最大有 2 的 32 次方这么多个。 端口是一个 16 位的整数所以端口的数量就是 2 的 16 次方。2 的 32 次方ip数× 2的 16 次方port数大约等于两百多万亿。所以理论上我们每个 server 可以接收的连接上限就是两百多万亿。
当然实际上做不到目前工程实践中可以达到的连接数在千万级别。基于Java的应用程序大概能支持百万级别。
客户端
前面我们已经说过“客户端应用程序完全可以不用自己设置端口号而全权交给操作系统进行分配”可用的端口号只有6万多从这个角度考虑客户端最多只能发起6万多条 TCP 连接。但其实也不是。
从TCP连接四元组来考虑源IP地址、源端口、目的IP地址和目的端口目的IP地址和目的端口指的是服务器的IP和端口源IP地址、源端口自然就是客户端的。
只要服务器的 IP 或者端口不一样即使客户端的 IP 和端口是一样的。这个四元组也是属于一条完全不同的新连接。比如
连接1客户端IP 10000 服务器IP 10000
连接2客户端IP 10000 服务器IP 20000
虽然客户端的 IP 和端口完全一样但由于服务器侧的端口不同所以仍然是两条不同的连接。问题来了客户端同一个端口可以连接不同的服务器吗答案是可以的。
客户端只要启动时不显示绑定到某个端口上内核是可以使用一个端口连不同的服务端内核会自己进行选择并恰当地复用的而且完全不会产生数据混乱因为“源IP地址、目标IP地址、源端口号以及目标端口号就能唯一性确定一个TCP连接”。
那么对客户端来说四元组里有3个可变自然客户端能同时支持的连接数比服务器还要大得多。就是上面服务端算出来的两百多万亿乘以6W多个源端口 TCP特性
在我们上面的讲述中存在着客户端和服务端两者角色在网络通信里是怎么区分的这个就牵涉到了TCP的相关特性。
TCPTransmission Control Protocol是面向连接的通信协议通过三次握手建立连接然后才能开始数据的读写通讯完成时要拆除连接由于TCP是面向连接的所以只能用于端到端的通讯。
TCP提供的是一种可靠的数据流服务数据有可能被拆分后发送那么采用超时重传机制是和应答确认机制是组成TCP可靠传输的关键设计。
而超时重传机制中最最重要的就是重传超时RTORetransmission TimeOut的时间选择很明显在工程上和现实中网络环境是十分复杂多变的有时候可能突然的抽风有时候可能突然的又很顺畅。在数据发送的过程中如果用一个固定的值一直作为超时计时器的时长是非常不经济也非常不准确的方法这样的话超时的时长就需要根据网络情况动态调整就需要采样统计一个数据包从发送端发送出去到接收到这个包的回复这段时长来动态设置重传超时值这个时长就是为RTT学名round-trip time然后再根据这个RTT通过各种算法和公式平滑RTT值后最终确定重传超时值。
而IP层进行数据传输时是不能保证数据包按照发送的顺序达到目的机器。当IP将把它们向‘上’传送到TCP层后TCP将包排序并进行错误检查。TCP数据包中包括序号和确认所以未按照顺序收到的包可以被排序而损坏的包可以被重传。
TCP还采用一种称为“滑动窗口”的方式进行流量控制所谓窗口实际表示接收能力用以限制发送方的发送速度。
同时TCP还允许在一个TCP连接上通信的双方可以同时传输数据也就是所谓的全双工。
面向连接的服务例如Telnet、FTP、rlogin、X Windows和SMTP需要高度的可靠性所以它们使用了TCP。DNS在某些情况下使用TCP发送和接收域名数据库但使用UDP传送有关单个主机的信息。 TCP三次握手需要知道每一次的具体情况
TCP 提供面向有连接的通信传输。面向有连接是指在数据通信开始之前先做好两端之间的准备工作。
所谓三次握手是指建立一个 TCP 连接时需要客户端和服务器端总共发送三个包以确认连接的建立。在socket编程中这一过程由客户端执行connect来触发所以网络通信中发起连接的一方我们称为客户端接收连接的一方我们称之为服务端。
简易速记版 但是简易速记版在真实的面试中不能让面试官满意很多公司还会考察握手过程中的具体详情 第一次握手客户端将请求报文标志位SYN置为1请求报文的Sequence Number字段简称seq中填入一个随机值J并将该数据包发送给服务器端客户端进入SYN_SENT状态等待服务器端确认。 第二次握手服务器端收到数据包后由请求报文标志位SYN1知道客户端请求建立连接服务器端将应答报文标志位SYN和ACK都置为1应答报文的Acknowledgment Number字段简称ack中填入ackJ1应答报文的seq中填入一个随机值K并将该数据包发送给客户端以确认连接请求服务器端进入SYN_RCVD状态。
第三次握手客户端收到应答报文后检查ack是否为J1ACK是否为1如果正确则将第三个报文标志位ACK置为1ackK1并将该数据包发送给服务器端服务器端检查ack是否为K1ACK是否为1如果正确则连接建立成功客户端和服务器端进入ESTABLISHED状态完成三次握手随后客户端与服务器端之间可以开始传输数据了。 为什么TCP握手需要三次?
TCP是可靠的传输控制协议而三次握手是保证数据可靠传输又能提高传输效率的最小次数。为什么RFC793也就是TCP的协议RFC中就谈到了原因这是因为
为了实现可靠数据传输 TCP协议的通信双方都必须维护一个序列号 以标识发送出去的数据包中哪些是已经被对方收到的。
举例说明发送方在发送数据包假设大小为 10 byte时 同时送上一个序号( 假设为 500)那么接收方收到这个数据包以后 就可以回复一个确认号510 500 10 告诉发送方 “我已经收到了你的数据包 你可以发送下一个数据包 序号从 511 开始” 。 这里解释下seq_no:网络传输有可能丢包丢包就需要重传重传哪些包就根据seq_no来决定
比如服务端3个包收到了就是seq_no3这样的一次确认十个就加10只不过在tcp三次握手里面一次只有一个报文所以就加1 三次握手的过程即是通信双方相互告知序列号起始值并确认对方已经收到了序列号起始值的必经步骤。
如果只是两次握手 至多只有连接发起方的起始序列号能被确认 另一方选择的序列号则得不到确认。
至于为什么不是四次很明显三次握手后通信的双方都已经知道了对方序列号起始值也确认了对方知道自己序列号起始值第四次握手已经毫无必要了。 TCP的三次握手的漏洞-SYN洪泛攻击了解即可
但是在TCP三次握手中是有一个缺陷被称为SYN洪泛攻击。三次握手中有一个第二次握手服务端向客户端应答请求应答请求是需要客户端IP的而且因为握手过程没有完成操作系统使用队列维持这个状态Linux 2.2以后这个队列大小参数可以通过/proc/sys/net/ipv4/tcp_max_syn_backlog设置。于是攻击者就伪造这个IP往服务器端狂发送第一次握手的内容当然第一次握手中的客户端IP地址是伪造的从而服务端忙于进行第二次握手但是第二次握手是不会有应答的所以导致服务器队列满而拒绝连接。
面对这种攻击有以下的解决方案最好的方案是防火墙。 现在默认是1024 无效连接监视释放
这种方法不停监视所有的连接包括三次握手的还有握手一次的反正是所有的当达到一定(与)阈值时拆除这些连接从而释放系统资源。这种方法对于所有的连接一视同仁不管是正常的还是攻击的所以这种方式不推荐。
延缓TCB分配方法
一般的做完第一次握手之后服务器就需要为该请求分配一个TCB连接控制资源通常这个资源需要200多个字节。延迟TCB的分配当正常连接建立起来后再分配TCB则可以有效地减轻服务器资源的消耗。
使用防火墙
防火墙在确认了连接的有效性后才向内部的服务器Listener发起SYN请求 TCP四次挥手分手
四次挥手即终止TCP连接就是指断开一个TCP连接时需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中这一过程由客户端或服务端任一方执行close来触发。过程简易记忆版 由于TCP连接是全双工的因此每个方向都必须要单独进行关闭。首先进行关闭的一方将执行主动关闭而另一方则执行被动关闭。 由上图可见TCP建立一个连接需3个分节终止一个连接则需4个分节。
(1)某个应用进程首先调用close我们称该端执行主动关闭active close)。该端的TCP于是发送一个FIN分节表示数据发送完毕应用进程进入FIN-WAIT-1终止等待1状态。
(2接收到这个FIN的对端执行被动关闭(passive close)发出确认报文。因为FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收接收端进入了CLOSE-WAIT关闭等待状态这时候处于半关闭状态即主动关闭端已经没有数据要发送了但是被动关闭端若发送数据主动关闭端依然要接受。这个状态还要持续一段时间也就是整个CLOSE-WAIT状态持续的时间。主动关闭端收到确认报文后进入FIN-WAIT-2终止等待2状态。
(3)一段时间后被动关闭的应用进程将调用close关闭它的套接字。这导致它的TCP也发送一个FIN表示它也没数据需要发送了。
(4)接收这个最终FIN的原发送端TCP即执行主动关闭的那一端确认这个FIN发出一个确认ACK报文并进入了TIME-WAIT时间等待状态。注意此时TCP连接还没有释放必须经过2∗MSL最长报文段寿命/最长分节生命期 max segement lifetimeMSL是任何IP数据报能够在因特网中存活的最长时间任何TCP实现都必须为MSL选择一个值。RFC 1122[Braden 1989]的建议值是2分钟不过源自Berkelcy的实现传统上改用30秒这个值。这意味着TIME_WAIT状态的持续时间在1分钟到4分钟之间的时间后当主动关闭端撤销相应的TCB后才进入CLOSED状态。
这个msl各个系统设置不同的比如liunx里面是60秒 (5) 被动关闭端只要收到了客户端发出的确认立即进入CLOSED状态。同样撤销TCB后就结束了这次的TCP连接。可以看到被动关闭端结束TCP连接的时间要比主动关闭端早一些。
既然每个方向都需要一个FIN和一个ACK因此通常需要4个分节。我们使用限定词“通常”是因为某些情形下步骤1的FIN随数据一起发送;另外步骤2和步骤3发送的分节都出自执行被动关闭那-一端有可能被合并成一个分节。 所以有可能有时候三个字节就完成了 就下面红色的部分那就是三次挥手了 即步骤2和3就是第二次和第三次挥手之间木有数据传输 tcp握手发起连接的一定是客户端接受的一定是服务端
但是挥手的发起谁都可以木有限死是谁,即客户端和服务端都可以是发起方 为什么TCP的挥手需要四次
TCP是全双工的连接必须两端同时关闭连接连接才算真正关闭。
如果一方已经准备关闭写但是它还可以读另一方发送的数据。发送给FIN结束报文给对方对方收到后回复ACK报文。当这方也已经写完了准备关闭发送FIN报文对方回复ACK。两端都关闭TCP连接正常关闭。 为什么需要TIME-WAIT状态
TIME_WAIT状态存在的原因有两点
1、可靠的终止TCP连接。
2、保证让迟来的TCP报文有足够的时间被识别并丢弃。
根据前面的四次握手的描述我们知道客户端收到服务器的连接释放的FIN报文后必须发出确认。如最后这个ACK确认报文丢失那么服务器没有收到这个ACK确认报文就要重发FIN连接释放报文客户端要在某个状态等待这个FIN连接释放报文段然后回复确认报文段这样才能可靠的终止TCP连接。
关于第二点保证让迟来的TCP报文有足够的时间被识别并丢弃的解释 在Linux系统上一个TCP端口不能被同时打开多次当一个TCP连接处于TIME_WAIT状态时我们无法使用该链接的端口来建立一个新连接。反过来思考如果不存在TIME_WAIT状态则应用程序能过立即建立一个和刚关闭的连接相似的连接这里的相似是指他们具有相同的IP地址和端口号。这个新的、和原来相似的连接被称为原来连接的化身。新的化身可能受到属于原来连接携带应用程序数据的TCP报文段迟到的报文段这显然是不该发生的。这是TIME_WAIT状态存在的第二个原因。 面试题服务器出现大量time-wait状态是什么造成的?如下 程序代码木有close这个连接导致服务器端主动发起close连接超过了上面的2*Msltime-wait是主动关闭连接的那一端才存在 实战观察TCP报文
WireShark
为什么要抓包
1、定位网络问题
大部分场合都可以通过程序调试来定位问题但有些场景使用抓包来定位接口问题更准确、更方便如以下场景
a、你发送数据给后台但后台没有收到可以对接口进行抓包分析看是后台处理有问题还是没有将数据发出去或是发送数据格式有误
b、你和后台接口联调测通但业务数据对不上你认为是后台问题后台认为是你发的问题可以抓包确认问题所在
c、线上出现bug需要定位但你没在公司没有代码可调试可直接抓包分析
d、系统性能不佳抓包看下接口响应时长是不是后台出现性能问题。
2、学习网络协议使用抓包工具分析网络数据更直观。
常用的抓包工具有F12浏览器自带的抓包工具、Fiddler、CharlesWireshark。而Wireshark在支持的协议用户友好度、价格开源、程序支持、支持的操作系统上都很好所以Wireshark也是我们最常用的抓包工具和报文分析工具。
下载与安装 实战用WireShark看看TCP的三次握手
准备
现在我们用平时比较常见的连接mysql服务器来看看打开一个mysql的客户端准备连接IP地址为47.112.44.148的云端mysql。
于是我们设定捕获过滤器只捕获与IP地址47.112.44.148相关的数据包
host 47.112.44.148 开始捕获连接数据库 很明显WireShark捕获到了本机所有和 47.112.44.148通信的报文现在我们只需要观察TCP的三次握手和四次分手的报文所以我们在显示过滤器中写上tcp and !mysql 按照tcp三次握手的规则三次握手包含一个SYN 包、 一个SYN/ACK 包和 一个ACK包。 就是窗口里最上面的三条记录 我们一条条看过来
第一次握手 从这里我们可以看出这是数据链路层相关的信息source部分的地址和我们机器上的mac地址一模一样 接下来就是IP层的相关信息其中表明了它的上一层协议是TCP同时本地和远程服务器的IP地址 接下来就是TCP层的相关信息其中包括了本地端口和远程服务端口既然是syn包里面当然会带上seq值本次通信是1979849485tcp报文格式中的syn字段被设置为1用来表明这是一个syn包。
本次tcp的相对序列号 从0开始 操作系统分配的序列号 第二次握手
数据链路层和IP层的报文我们不再查阅直接看TCP层的报文很明显这是服务器给客户端的ACK报文其中依然包括了远程服务端口和本地端口同时服务器要把自己端的seq值告诉客户端我们看到实际值是3366556883。同时服务器要把客户端传给自己的seq值做个应答确认所以我们看见Acknowledgment number 字段值是 1979849486刚好是第一次握手中客户端传递给服务端的seq值1979849485加1。同时tcp报文格式中的syn字段被设置为1Acknowledgment字段被设置为1用来表明这是一个syn/ack包。 第三次握手
这次握手的的报文分析通过前两次的分析相信大家都能够自行分析出来这里就不在赘述。 UDP和UDT、QUIC
UDP概述 我们已经知道UDPUser Datagram Protocol的简称 中文名是用户数据报协议是把数据直接发出去而不管对方是不是在接收也不管对方是否能接收的了也不需要接收方确认属于不可靠的传输可能会出现丢包现象实际应用中要求程序员编程验证。
UDP单播和广播
单播的传输模式定义为发送消息给一个由唯一的地址所标识的单一的网络目的地。面向连接的协议和无连接协议都支持这种模式。
由于通讯不需要连接所以可以实现广播发送所谓广播——传输到网络或者子网上的所有主机。
UDP因为没有TCP等一系列复杂机制所以使用也非常广泛使用UDP的服务包括NTP网络时间协议和DNSDNS也使用TCP包总量较少的通信DNS、SNMP等2.视频、音频等多媒体通信即时通信3.限定于 LAN 等特定网络中的应用通信4.DHCP等协议就利用了UDP的广播功能。
常用的QQ就是一个以UDP为主TCP为辅的通讯协议。
UDT
基于UDP的数据传输协议UDP-based Data Transfer Protocol简称UDT是一种互联网数据传输协议。UDT的主要目的是支持高速广域网上的海量数据传输最典型的例子就是建立在光纤广域网上的网格计算一些研究所在这样的网络上运行他们的分布式的数据密集程式例如远程访问仪器、分布式数据挖掘和高分辨率的多媒体流。
而互联网上的标准数据传输协议TCP在高带宽长距离网络上性能很差。 顾名思义UDT建于UDP之上并引入新的拥塞控制和数据可靠性控制机制。UDT是面向连接的双向的应用层协议。
UDT的特性主要包括在以下几个方面
基于UDP的应用层协议 有基本网络知识的朋友都知道TCP和UDP的区别和使用场景但是有没有一种协议能同时兼顾TCP协议的安全可靠和UDP协议的高效那么UDT就是一种。
面向连接的协议面向连接意味着两个使用协议的应用在彼此交换数据之前必须先建立一个连接当然UDT是逻辑上存在的连接通道。这种连接的维护是基于握手、Keep-alive保活以及关闭连接。
可靠的协议依靠包序号机制、接收者的ACK响应和丢包报告、ACK序号机制、重传机制(基于丢包报告和超时处理)来实现数据传输的可靠性。
双工的协议每个UDT实例包含发送端和接收端的信息。
新的拥塞算法并且具有可扩展的拥塞控制框架新的拥塞控制算法不同于基于窗口的TCP拥塞控制算法(慢启动和拥塞避免)是混合的基于窗口的、基于速率的拥塞控制算法。可扩展的拥塞控制框架开源的代码和拥塞控制的C类架构可支持开发者派生专用的拥塞控制算法。
带宽估计UDT使用对包(PP -- Packet pair)的机制来估计带宽值。即每16个包为一组,最后一个是对包,即发送方不用等到下一个发送周期内再发送。接收方接收到对包后对其到达时间进行记录,可结合上次记录的值计算出链路的带宽(计算的方法称为中值过滤法), 并在下次ACK中进行反馈。 QUIC
QUIC代表”快速UDP Internet连接”基于UDP的传输层协议它本身就是Google尝试将TCP协议重写为一种结合了HTTP/2、TCP、UDP和TLS用于加密等多种技术的改进技术。
谷歌希望QUIC通信技术逐渐取代TCP和UDP作为在Internet上移动二进制数据的新选择协议QUIC 协议的主要目的是为了整合 TCP 协议的可靠性和 UDP 协议的速度和效率。
由于 TCP 是在操作系统内核和中间件固件中实现的因此对 TCP 进行重大更改几乎是不可能的TCP 协议栈通常由操作系统实现如 Linux、Windows 内核或者其他移动设备操作系统。修改 TCP 协议是一项浩大的工程因为每种设备、系统的实现都需要更新。但是由于 QUIC 建立在 UDP 之上因此没有这种限制。
QUIC 的优势在于
1、采用多路复用 思想一个连接可以同时承载多个 流 ( stream )同时发起多个请求。 请求间完全独立 某个请求阻塞甚至报文出错均不影响其他请求。
2、QUIC只需要1RTTRound-Trip Time的延迟就可以建立可靠安全的连接,相对于TCPTLS的3次RTT要更加快捷。之后客户端可以在本地缓存加密的认证信息再次与服务器建立连接时可以实现0-RTT的连接建立延迟。
3、TCP 采用 重传 机制而 QUIC 采用 纠错 机制。fec 前向纠错机制
TCP 发生丢包时需要一个等待延时判断发生了丢包然后再启动重传机制这个过程会造成一定的阻塞影响传输时间。
fec 前向纠错机制而 QUIC 则采用一种更主动的方案有点类似 RAID5 每 n 个包额外发一个 校验和包 。 如果这 n 个包中丢了一个包可以通过其他包和校验和恢复出来完全不需要重传。
前向纠错 5个报文数据 传递6个报文第三个报文数据丢了不用重新传递利用第六个报文解除第三个报文的数据但是这种丢了两个就解不出来了根据网络丢包率来算比如平均丢两个那就传递7个报文过去。 还有一种 只传递五个报文但是每次传递数据会把一部分上一次传递的报文数据传递过来 4、QUIC 直接基于客户端(应用进程)实现而非基于内核可以快速迭代更新不需要操作系统层面的改造部署灵活。
5、连接保持
QUIC 在客户端保存连接标识当客户端 IP 或者端口发生变化时可以快速恢复连接 —— 客户端以标识请求服务端服务端验证标识后感知客户端新地址端口并重新关联继续通讯。 这对于改善移动端应用连接体验意义重大(从 WiFi 切换到流量)。