网络基础(三)TCP/UDP详解

传输层

传输层负责端与端之间的数据传输,决定数据怎么传,什么时候传,传多少的问题。

端口号

端口号用来特定标记一台主机上的网络进程,并且和特定的应用层协议捆绑保证将传输层数据交给应用层。端口号由16个bits(两个字节构成)端口号范围是0–65535,0–1023是知名端口号,1024–65535可以由客户端使用

ssh服务器, 使用22端口
ftp服务器21
http服务器:80
https:443

端口号由:“源IP”, “源端口号”, “目的IP”, “目的端口号”, “协议号” 这样一个五元组来标识
IP地址+端口号=套接字Socket

查看知名端口号命令:cat/etc/services
查看网络所以TCP连接:netstat -apnt
查看特定的网络进程: ps aux | grep xxx
查看服务器进程ID:pidof [进程名]
查看主机是否联网:ping www.baidu.com 若有相应则说明有网
查看本地ip地址:ifconfig

一个端口号只能被一个进程使用,但是一个进程可以使用多个端口号

UDP协议

UDP协议端格式

在这里插入图片描述

UDP数据长度

UDP协议首部有一个16位最大长度,因此能传输数据的最大长度是64K,因此UDP每条数据之间都有明显的边界(报头为8字节,剩余都是正文),因此不会出现粘包问题。
传输大数据(超过64K)时,需要在应用层进行切分。因为UDP的不可靠传输,所以无法保证安全也无法保证包序,因此如果应用层进行分段,那么就需要在应用层进行包序的管理,进行手动分包,多次发送,并在接收端手动拼接。

校验和:如果校验和出错, 就会直接丢;校验数据包的完整性和正确性,计算方法:二进制反码求和

udp协议的特点:
  • 无连接:知道对端IP和端口号就直接进行传输,不需要进行连接
  • 不可靠:没有确认机制,没有重传机制,如果因为网络故障无法发到对方,UDP协议层也不会给应用层返回任何错误信息。
  • 面向数据报:不能够灵活的控制数据的次数和数量。应用层交给UDP多长的报文,UDP原样返回,既不拆分,也不合并。

缺点:无法保证数据安全传输;
优点:数据传输速度快,没有粘包问题。

UDP的缓冲区

UDP没有真正意义上的发送缓冲区,调用sendto会直接交给内核,由内核将数据传给网络协议层进行后续传输动作。
UDP就有接收缓冲区,但是不能保证收到的UDP报的顺序和发送的UDP报的顺序一致,如果缓冲区满了,再到达UDP数据就会被丢弃
UDP的socket既能读,也能写,是全双工的

(早期的QQ用的就是UDP协议)
适合UDP的场景:不想有连接,不在意数据可靠性,在意数据的实时性

TCP协议

tcp协议段格式
在这里插入图片描述
TCP与UDP的区别是:一个保证可靠性(面向连接)一个不保证可靠性

TCP的有效载荷和报头分离:TCP报文中包含一个4位(4个4字节)首部长度,因此最大长度是15(报头中的4位首部长度)*4(单位)=60个字节,TCP报头的标准长度是20个字节,因此标准长度20/4=5位,因此二进制表示是0101就是表示的是报头的标准长度

TCP的向上交付:根据目的端口号向上交付

网络通信中没有100%可靠的协议,要保证可靠就必须保证发出去的核心消息有应答。
TCP保证可靠的机制叫做确认应答(ACK)机制,因为不同的报文面临的网络环境可能是不同的,因此TCP引进序号机制保证报文的按序到达,TCP将每个字节的数据都进行了编号,即位序列号。每一个ACK都带有对应的确认序列号,(响应ACK也是一个TCP报文,因此需要序号和确认序号) 意思是告诉发送者, 我已经收到了哪些数据,确认序号比数据序号大一,表示下一次对方应该从哪发 (序号描述自身TCP信息,确认序号描述TCP报文可靠性),TCP是全双工的,因此原报文序号与确认序号是为了保证通信双方的可靠性

半双工:可读可写,但是不能同时进行
全双工:读写可以同时进行
操作系统:先描述再组织

16位窗口大小实现流量控制

TCP是有发送缓冲区和接收缓冲区的,对方的接收缓冲区的剩余空间大小决定了发送TCP发送消息的流量控制,16位窗口大小就是用来存放自己的接收缓冲区的剩余空间大小,能够保证双向发送消息的流量控制。但是窗口并不是真实的16位(65535个字节),在TCP首部40字节中包含一个窗口扩大因子M,实际窗口大小是窗口字段的值左移M位。

6位标志位

SYN:请求建立连接(建立连接有三次握手机制),连接请求报文,在建立请求前,需将SYN置为1,把携带SYN标识的称为同步报文段
FIN:连接断开报文(断开连接有四次挥手机制);FIN与SYN只能有一个置1,带FIN标识的称为结束报文段
ACK:确认号是否有效
URG:紧急指针是否有效(带外数据),置为1时,16位紧急指针指向的数据会优先处理
PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走
RST:对方要求重新建立连接,把携带RST标识的称为复位报文段

三次握手建立连接

主动建立连接的一放需要发送SYN(请求建立连接),接收方响应SYN+ACK,收到响应后请求方再次发送ACK(单纯的ACK不需要响应)
若是两次握手。第一个请求连接报文丢了不会对双方造成损失,都会认为连接不成功。若是服务器的响应报文(最新的报文)丢失,客户端会认为连接建立失败,会再次发送连接请求到服务器,每次建立连接都会需要内存成本,对服务器是一种压力,因此,不能是两次握手
优点:若是前两次报文丢失,双方都会认为连接失败,不会为维护报文花费开销,若是最新的报文丢失,服务器认为连接建立成功,服务器没有收到第三次的报文,认为没有建立连接成功,因此三次握手失败可以使异常连接放在客户端上,减少对服务器的压力。

TCP是面向连接的,因此在连接之前需要创建连接,是保证TCP可靠性的措施之一。双方建立连接成功后,在内存中维护了对应的数据结构描述连接,维护连接需要内存成本。

(窗口大小可以在三次握手建立连接时相互确认)

四次挥手断开连接

客户端发起断开连接请求FIN,客户端收到后响应ACK,再次发送FIN表示断开连接,客户端收到响应也发送ACK。
因为断开连接是双方的事情,因此断开连接需要四次。主动断开连接的一方最后发送ACK。

TIME_WAIT
主动断开连接的一方会进入TIME_WAIT状态,若在等的期间没有收到服务器的FIN说明服务器收到了最后一次的ACK。
若断开出现异常,数据被卡在发送数据的某一环节,在TIME_WAIT期间,客户端与服务器不会再发送时间。
数据从发送到接收所用的时间称作MSL时间,在Centos7上默认配置的值是60s,TIME_WAIT时间长度为2MSL:1.能保证在两个传输方向上的尚未被接收或迟到的报文段都已经消失2.在理论上保证后一个报文可靠到达
TIME_WAIT作用:保证断开连接的高度可靠性;保证发送的数据能充分消散出去。
CLOSE_WAIT
服务器上出现大量的 CLOSE_WAIT 状态, 原因就是服务器没有正确的关闭 socket, 导致四次挥手没有正确 完成. 这是一个 BUG. 只需要加上对应的 close 即可解决问题

超时重传机制

若是发送的数据丢失后,发送数据的主机没有收到ACK,在特定的时间间隔后,就会再次发送数据
若是ACK响应丢失,特定时间间隔后,又会再次发送数据,这样接收方就会收到重复数据,那么TCP协议就能够根据序列号识别到重复的数据,做到去重效果。

超时时间的确定:
由于网络情况不稳定,因此超时时间不能是一个确定的值。
TCP为了保证无论在任何环境下都能比较高性能的通信, 因此会动态计算这个大超时时间.
Linux中(BSD Unix和Windows也是如此), 超时以500ms为一个单位进行控制, 每次判定超时重发的超时 时间都是500ms的整数倍. 如果重发一次之后, 仍然得不到应答, 等待 2500ms 后再进行重传. 如果仍然得不到应答, 等待 4500ms 进行重传. 依次类推, 以指数形式递增. 累计到一定的重传次数, TCP认为网络或者对端主机出现异常, 强制关闭连接。

32位确认序号的作用

1.实现了确认应答机制
2.保证了数据按序到达
3.甄别需重传的数据

发送数据其实是将数据交给了某个协议,协议会在适当的时候将数据发送出去

滑动窗口

确认应答策略, 对每一个发送的数据段, 都要给一个ACK确认应答. 收到ACK后再发送下一个数据段. 这样做有一个比较大的缺点, 就是性能较差. 尤其是数据往返的时间较长的时候。
但是网络利用滑动窗口来提高效率,可以一次发送多条数据,这些数据暂时不需要应答
应用层将自己的数据发送到传输层的发送缓冲区,发送方将多条数据发送出去,滑动窗口在发送缓冲区中,保存的就是已经发出而没有收到应答的数据,在滑动窗口左边的是已发送收到了应答的数据,滑动窗口右边是未发送的数据,滑动窗口受对方的接收缓冲区的影响,我的接收缓冲区收对方的滑动窗口影响。接收到应答后,滑动窗口就会不断右移。
发送而没有收到应答的数据会保存在滑动窗口中,如数据丢失,可以保证重传的数据。
在这里插入图片描述

快速重传

若数据包丢失,没有收到ACK,那么在之后收到的数据包返回的应答中都是需要丢失的数据包应答,当发送端主机连续收到了同样的3次的ACK,就会再次发送数据包,在之后的应答就会是目前最新数据的应答,这样就代表在最新数据之前的数据都全部收到了。

拥塞控制

当大量数据丢包很有可能是网络出现问题导致的,因此不能够进行数据重传,否则会雪上加霜,TCP引入慢启动机制:先发少量数据探探路,再每次逐渐以指数级别数据量递增发送数据,摸清当前网络拥堵状态决定按照多大速度传输数据。慢启动指的是初始慢,但是增长速度快。拥塞窗口不能一直加倍,引入一个慢启动阈值,当拥塞窗口超过阈值,数据量将以线性方式增长。传输的数据量由对方的接收缓冲区和拥塞窗口的较小值决定。
当TCP开始启动的时候, 慢启动阈值等于窗口最大值; 在每次超时重发的时候, 慢启动阈值会变成原来的一半, 同时拥塞窗口置回1

延迟应答

如果能让对方的接收缓冲区的剩余空间增多,那么发送方的发送缓冲区就能够发送更多数据了,提高了传输效率。

捎带应答

发送方每次发送数据都需要应答,在进行应答时可以携带一些数据回给客户端,提高了效率。

TCP的可靠性的保证:1.校验和2.序列号3.确认应答4.超时重传5.面向连接6.流量控制7.拥塞控制
提高性能的保证:1.滑动窗口2.快速重传3.延迟应答4.捎带应答

面向字节流

站在传输层的角度, TCP是一个一个报文过来的. 按照序号排好序放在缓冲区中. 站在应用层的角度, 看到的只是一串连续的字节数据. 那么应用程序看到了这么一连串的字节数据,
TCP数据的使用是面向字节流的,读取数据是按照字节流由用户决定,因此用户在使用TCP时,需要制定应用层协议。

粘包问题

应用程序看到了这么一连串的字节数据(TCP), 但是不知道从哪个部分开始到哪个部分, 是一个完整的应用层数据包. 客户端需要在应用层通过分割符分离包,分离报文与报文的边界。

TCP异常情况

1.在Linux中一切皆文件,网络连接也看成文件
2.打开文件的生命周期是随进程的

进程终止: 进程终止会释放文件描述符, 仍然可以发送FIN. 和正常关闭没有什么区别.
机器重启: 和进程终止的情况相同
机器掉电/网线断开: 接收端认为连接还在, 一旦接收端有写入操作, 接收端发现连接已经不在了, 就会进行reset. 即 使没有写入操作, TCP自己也内置了一个保活定时器, 会定期询问对方是否还在. 如果对方不在, 也会把连接释放

TCP 相关实验 理解 listen 的第二个参数

TCP是面向连接的,因此使用TCP首先要建立连接,建立连接的过程会消耗资源管理连接。在网络服务器中,服务在操作系统底层会维护一个队列(全连接队列),这个队列长度由listen的第二个参数决定,用来保存处于established状态,但是应用层没有调用accept取走的请求
半链接队列:用来保存处于SYN_SENT和SYN_RECV状态的请求

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值