网络通信基础知识总结(一)应用层+传输层TCP/UDP

如果客户端要向服务端发送访问网站的请求,例如“www.baidu.com",首先会进行DNS域名解析得到IP地址。通过应用层,浏览器从访问的IP地址解析出默认的端口号80;再用端口号和IP地址与web服务器(我们常说的web是网站服务器)建立一条tcp连接通道,建立TCP连接之后,浏览器向web服务器发送一条HTTP请求报文web服务器响应并读取浏览器的请求信息,然后返回一条HTTP响应报文。web服务器关闭HTTP连接,关闭TCP连接,web服务器显示访问的网站内容到屏幕上。

在应用层:

下面介绍DNS和域名解析流程:
首先,DNS是域名系统,是域名与IP地址相互映射的一个分布式数据库,作用就是不让机器去通过域名去解析IP地址这一复杂的流程,能更方便的得到IP地址。其实就是通过主机名解析出IP地址的过程叫域名解析或者叫主机名解析,解析的方法流程是DNS协议。DNS协议运行在UDP协议之上,它的端口号为53,。解析完成后转向其网站。
域名解析流程:
1.首先系统会在本机host文件信息和缓存中是否有与域名所对应的IP地址,如果有,直接去访问IP对应的域名服务器。
2.若没有在本地和缓存中找到,浏览器就会向本地主机所指定的DNS服务(LDNS)发送请求,进行查询,有则返回给客户端浏览器,没有则访问其他服务器。
3.若没有在LDNS中找到,则LDNS会向根域名服务器发送域名请求解析,根域名服务器全球只有13台,它没有域名解析的地址,所以它会返回.com对应的服务器地址返回给LDNS.
4.LDNS拿到地址去找.com域名服务器,就会找到baidu.com的地址服务器。
5.baidu.com域名服务器就是企业购买域名时用于管理解析的服务器,此时www.baidu.com的地址就会被解析出来,然后返回给浏览器。
6,返回到浏览器后就会将此时的IP地址与域名映射放到本地host文件信息和缓存中,方便下次访问。
这里不得不说URL和常见的应用层协议HTTP/HTTPS
URL:统一资源定位符;
HTTP/HTTPS URL:scheme://:/ ?#;
scheme:使用的协议。
host:域名/点分IP地址
port:端口号(资源宿主监听的端口)
path:资源服务器的相对路径。
query:某些方案会用这个组件传递参数以激活应用程序,查询组件的内容没有通用格式.
frag:客户端内部使用的字段,一部分资源的名字,访问改网站会直接跳到该字段
例如: http://www.baidu.com:80/path?k1=v1&k2=v2#frag
scheme:http
host:www.baidu.com
port:80
path:/path
query:k1=v1&k2=v2
HTTP协议请求报文
如图
在这里插入图片描述
在这里插入图片描述
http请求报文字段可以分为:首行+头部+空行+正文
首行就是post:方法+URL+版本号
头部内容分为好多,具体该博主的博客,很详细https://www.cnblogs.com/zawier/p/5686124.html
空行为了和正文区分。
HTTP协议响应报文
在这里插入图片描述
在这里插入图片描述
http相应报文字段:首行+头部+body
首行: [版本号] + [状态码] + [状态码解释]
Header: 请求的属性, 冒号分割的键值对;每组属性之间使用\n分隔;遇到空行表Header部分结束
Body: 空行后面的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有一个Content-Length属性来标识Body的长度; 如果服务器返回了一个html页面, 那么html页面内容就是在body中.

传输层–TCP传输

在这里又不得不说TCP协议了,一步一步来。
TCP(Transmission Control Protocol 传输控制协议) 是一种面向连接的,可靠,传输数据流的传输方式。
TCP的三次握手与四次挥手:看图
在这里插入图片描述
三次握手:(首先搞明白A发送B接收到,叫做1次握手)
下面所有S端为server端,C端为client端。
第一次握手:client端进行connect操作向server端发送SYN报文请求。此时client端处于SYN_SEND状态。server端接收到client端的SYN请求报文。
第二次握手:sever端向client回复ACK确认收到报文和SYN请求报文,此时sever端处于SYN_RCVD状态。client端接收到ACK和SYN。
第三次握手:client端接收到ACK和SYN之后,发送ACK确认报文,处于ESTABLISHED就绪状态,sever端接收到确认请求后,进入ESTABLISHED就绪状态。
到这此此时出现了问题,为什么是三次握手?为什么不是一次?两次?四次?
首先,一次肯定是不行的,如果握一次,C方发送请求,S方收到不回复,C方不能判断其是否建立连接成功,是不可靠的连接。
如果握手两次,那么若Client向Server发起的包A1如果在传输链路上遇到的故障,导致传输到Server的时间相当滞后,在这个时间段由于Client没有收到Server的对于包A1的确认,那么就会重传一个包A2,假设服务器正常收到了A2的包,然后返回确认B2包。由于没有第三次握手,这个时候Client和Server已经建立连接了。再假设A1包随后在链路中传到了Server,这个时候Server又会返回B1包确认,但是由于Client已经清除了A1包所带信息的连接,所以Client会丢弃掉这个确认包,但是Server会保持这个相当于“僵尸”的连接。
四次握手没必要,三次握手建立了可靠连接。
其实更底层的原因是,TCP为了更可靠的传输引出序号(sequence number) 和 确认号(acknowledgement number) 的使用。C端第一次发送了SYN请求时,会发送一个随机的序号seq=x,S端接收到SYN后,发送ACK=X+1,这样C端收到后就知自己发送的数据可靠,上步中S端也发送了SYN请求,此时C端也回ACK=Y+1,S端收到后,也就确认自己发送的数据可靠。这样就完成了可靠的连接。三次握手是为了更可靠,1次和2次都做不到,4次也没必要,一切都是为了面向连接的可靠传输。
TCP四次挥手:
当client端选择要与server端断开连接时
第一次挥手,C端会向S端发送一个FIN包和ACK包,然后C端处于FIN_WAIT1状态,S端收到,S端处于CLOSE_WAIT状态。
第二次挥手,S端收到C端请求后,然后发送ACK包,C端收到,并处于FIN_WAIT2状态。
第三次挥手,S端又发送FIN包,处于LAST_ACK状态,做最后确认,C端收到处于TIME_WAIT状态。
第四次挥手,C端发送ACK包,S端收到,断开连接完成。
问题又来了,为什么挥手不是1次,2次,3次,5次呢?
首先1次直接否定,C端发送分后信号,S端收到不响应,C端不知分手是否成功,万一S端没有收到FIN包丢了,S端还在自己认为连接的状态,浪费资源。
2次也不行,第2次C端收到S端的确认包,如果认为此时只有2次挥手,那么现在连接应该断开了,但是很可能S端的信息没有发送完,断开的话,数据丢失了,那么这样的连接就不可靠。
3次也不行,第三次挥手发起人是S端,说明此时S端的数据已经发送完毕并且准备好了,然后S端发送FIN包,C端接收到,若此时就结束的话,S端不知道C端是否收到FIN包,C端也不一定能接收到FIN包,此时C端就僵硬了不能及时退出。
4次可以是因为C端收到FIN包之后,会发送ACK给S端,S端收到就关闭套接字了。
5次挥手没必要了。
需要注意的是,第四次挥手C端并没有立即退出,而是处于TIME_WAIT状态并且是2个MSL时间
MSL(报文最大生命时长)
问题来了为什么要进入TIME_WAIT状态,并且是2个MSL时间?
进入TIME_WAIT状态是为了确认ACK能到达对端,若ACK没有到达对端或者FIN包因为网络延时没有到达C端,对端发现长时(超过了MSL)没有收到ACK,以为FIN包丢了,会重新发送FIN包,刚好这是2个MSL时间。在这个时间里,如果上次网络延迟的FIN包如果到达后,经过这个时间也会消失,不会影响下次连接。
如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
TCP报文格式
在这里插入图片描述
可靠传输:
确认应答机制:超时重传机制;协议字段中的序号/确认序号
滑动窗口机制:流量控制;拥塞控制;快速重传机制,捎带应答机制,延迟应答机制
因为TCP为了实现可靠传输牺牲了部分传输性能,并且有可能因为ack确认应答也要重传输数据;因此有人提出了以下几种机制来避免大量的丢包重传以及ack重传来保证性能不在降低;
滑动窗口机制:
通过协议字段中的窗口大小,双方进行协商,一次可以最多传输多少条数据,之后等待确认应答,不需要进行一一等待。
tcp通过双方协商窗口大小进行流量控制,避免因为缓冲区区数据塞满而大量丢包重传。
滑动窗口中的快速重传机制:
1.每条数据的确认回复都必须按序回复,若前边的数据没有收到,则不会对后边的数据进行回复(乱序情况);
意味着:若接收到一条回复,表示ACK确认序号之前的数据全部到达,不会因为ACK丢失而数据重传。
若前边的数据丢失,则接收方收到后发的数据立即发送重传请求,若发送方连续收到三条重传请求,则认为数据丢失,进行重传。
滑动窗口中的拥塞控制:慢启动,快增长。
发送端控制一个拥塞窗口的大小,在进行数据传输的时候,进行网络试探性的发送,若网络状况良好则发送的数据快速增长,达到阙值时(窗口大小)时,则不在继续增长;若传输过程出现丢包,则重新初始化拥塞窗口拥塞控制为了避免因为网络不好导致通信初始,大量的数据报丢失,降低性能。
流量控制机制+拥塞机制+快速重传机制。
延迟应答机制:
接收方收到数据后并不立刻进行确认回复,而是等待一段时间,因为这段时间内,有可能用户已经recv将缓冲区中的数据取走,窗口就可以尽可能的保证最大大小,保证传输吞吐量;
捎带应答机制:
接收方对每一条数据的确认回复,都需要发送一个tcp数据报;但是空报头的传输会降低性能,因此会考虑在即将要发送的数据报中包含有确认信息(可以少发一个确认的空报头)。

传输层—UDP传输

UDP的特点是无连接,不可靠,面向数据报的传输方式。
UDP报文格式:
在这里插入图片描述
16位源端口号:在对端回复时选用。
16位目的端口号:对端的端口号必用
16位用户数据报长度:数据报长度最小为8(无数据)
uint16_t,所以数据报的长度最大为64k,数据最大长度为64k-8
16位校验和:校验数据是否正确,若错误则丢弃(二进制反码求和)

传输层----UDP与TCP比较

粘包问题:
首先,UDP和TCP都是传输层协议,UDP是面向数据报的传输方式,TCP是面向字节流的传输方式,这就导致一个问题,TCP由于是字节流传输会出现粘包问题,TCP协议栈对数据没有明确的划分,而UDP不会出现,因为UDP有数据报长度(最大长度为64k,若超过64k,则会报错,所以需要用户在应用层时就将数据分割成一个个小段进行发送)。而TCP是将发送的数据send到内核缓冲区,然后内核选择合适时机发送到对端,对端也就是接收网卡收到数据后放到缓冲区,然后合适时机对端recv这段数据,问题就出现在数据两次缓冲区的时候,都会导致多次数据粘连。
解决粘包问题:
从本质上解决,那就是用TCP传输时,在应用层对数据进行边界处理;例如http协议中特殊字符的间隔,或者对数据进行定长发送。
可靠性:
TCP是一个可靠的传输方式原因有一下:
1.TCP有校验和,如果对端受到数据后校验和不对,则会将此数据丢弃或者不处理,目的是等待对端超时重传。
2.TCP协议栈有自身的存活机制,若长时间没有受到应答,它会发送一个探测包,探测没有响应,则认为连接断开。
3.TCP/IP协议定义了一个在因特网上传输的包叫做IP数据报,发送多个IP数据包后由于网络延迟等各种原因会导致包序混乱,对端此时会进行包序管理,重新排序然后再交给应用层。
4.协议字段中的序号/确认序号。序号:每个传输的字节都有自己的序号,保证了传输过程的有序性。确认序号,即ACK,指明下一个收到的字节序号,ACK=1表示收到的序号无误。
5.TCP还能提供流量控制。TCP连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区所能接纳的数据。这将防止较快主机致使较慢主机的缓冲区溢出。
UDP是不可靠的传输:
UDP不保证包序,且UDP只有一个socket接收缓冲区,没有发送缓冲区,它只管发送,不管对方有没有接收到,当对端接收缓冲区接收满时,发送端还在发送数据,则到达对端的数据无法进入缓冲区则会被丢弃,UDP没有流量控制。

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值