网络之TCP/UDP/IP协议(1)

传输层的UDP协议(User Datagram Protocol)

职责

在网络层的基础之上,实现了进程与进程的通信

UDP协议的包头信息

UDP添加的封装(解包,分用)

UDP的包头是一个定长的包头:容易做解包

源端口 + 目的端口:做分用 | 进程 到 进程

校验和:防止数据错误的,类似hash的算法,

发送端:有效数据hash(有效数据) ——> h1

将得到的hash值填入校核和部分

接收端:有效数据hash(有效数据) ——> h2

h1 != h2 : 数据一定出错了(直接丢弃)

h1 == h2 : 大概率认为数据还是源数据

UDP发送的工作流程

1.填充端口

2.计算长度 + 填充长度

3.计算校验和 + 填充校验和

4.立即将数据交给网络层

ps:UDP协议栈内部没有发送缓冲区

UDP接收的工作流程

1.从网络层接收到数据

2.通过计算校验和,检查数据是否出现错误,如果出现错误直接丢弃

3.数据没有问题,根据自己内部维护Map<port,pid>找到对应的接受进程,如果找不到对应的进程,就丢弃

4.看对应的进程是否准备好一块内存,如果暂时没有,需要把数据暂时保存一段时间

5.把数据复制到对应的内存空间 byte[] buf

ps: UDP协议内部有一个接受缓存区

UDP的特点

1.不可靠

2.无连接

3.面向数据报文

4.全双工

抓包

0x270f 源端口号

0x1f90 目的端口号

0x0024 UDP长度

0xfda2 校验和

传输层的TCP协议**(Transmission Control Protocol 传输控制协议)

职责

  1. 进程 to 进程

  1. 可靠(承诺的是可靠,从没有承诺过安全)

TCP协议的包头信息

如何解包,如何进行分用

TCP包头是一个变长的包头,找到包头长度后我们可以进行解包

源/目的端口号:表示数据是从哪个进程来,到哪个进程去;

32位序号/32位确认号:后面详细讲;

4位TCP报头长度:表示该TCP头部有多少个32位bit(有多少个4字节);所以TCP头部最大长度是

15 * 4 = 60

6位标志位:

URG:紧急指针是否有效

ACK:确认号是否有效

PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走

RST:对方要求重新建立连接;我们把携带RST标识的称为复位报文段

SYN:请求建立连接;我们把携带SYN标识的称为同步报文段FIN:通知对方,本端要关闭了,我们称携带FIN标识的为结束报文段

16位窗口大小:后面再说

16位校验和:发送端填充,CRC校验。接收端校验不通过,则认为数据有问题。此处的检验和不光

包含TCP首部,也包含TCP数据部分。

16位紧急指针:标识哪部分数据是紧急数据;

40字节头部选项:暂时忽略;

TCP的保证“可靠性”

什么是可靠?

  1. TCP会尽自己最大的努力,将数据发送给对方

  1. 如果真的遇到发送不过去的情况,TCP至少会告诉发送进程,数据发送失败了

  1. 保证不会收到错误的数据(通过校验和)

  1. TCP能保证收到的数据是有序的(按照发送进程发送时的数据)

  1. TCP会根据对方的接受能力和网络线路的承受能力,进行流量的控制

TCP做了哪些机制来确保可靠性

  1. 确认应答机制:接收方(对方的TCP)有责任对收到的数据进行确认(acknowledge)应答

如果同时收到多份数据,如何知道应答的是哪份数据呢?

我们应该对数据进行编号——序列号,也就是TCP包头中的32位序列号,它会携带本次发送时的数

据的编号,某个字节占用一个序号,这个序号就是本次发送的数据的·第一个字节的序号

比如:开始序号从1开始

[abcd] SN = 1

[efgh] SN = 5

确认段:一份数据既可以起到发送数据的角色,也可以起到确认的角色

发送:携带有数据,填写正确的SN,就是发送确认段

确认:标准位ack置1,代表起到了确认的作用。需要填写确认序列号

确认序列号:填写下一次期望收到的第一个字节的编号,换言之就是,确认序列号之前的数据已经 全部收到了

例如: 1.发送[abcd] SN = 1

2.确认ack = 1 ASN = 5

Tips:TCP维护着各自的发送SN,也就是说TCP的发送序列号是独立的

回到发送端(我们没有上帝视角)

当我发送了一份数据,没有收到应答时,可能发生了什么?

可能情况:

  1. 对方没有收到

  1. 对方收到了,并且应答了,但应答没有发送过来

主机B收到过2次1~1000,所以主机B,需要有能力

直到遇到没有收到应答(超时重传机制)

超时timeout机制

  1. 不应该无限期的等待下去

  1. 重新发送数据

TCP的发送端不用关心超时没有收到应答的原因是什么,采用统一的超时重传机制即可,如果接收端真的收到了重复的数据,直接丢弃即可。

超时重传是无限制的吗?

会有一定的上限,达到上限,发送方(TCP)认为本次数据线路出现了重大问题

  1. TCP会关闭本次连接

  1. TCP会通知进程(在Java中,采用异常方式IOExpection)

  1. TCP会发送一个reset segment 出去

关于超时时间的设置

一般这个时间不是一个固定的长度,大多数是逐步变长

10s ->20s -> 40s -> 80s

站在进程角度思考,向一个有问题的TCP线路中发送数据,多久之后,进程会知道线路有问题了

10 + 20 + 40 + 80s 之后,发现

作为TCP的发送方,经过一段时间之后,是可以知道线路有问题的!

作为TCP的接收方,无法得知线路是有问题的(无法确认对方是没有数据发送还是发送失败了)

小结

TCP提供了 确认应答机制(数据编号机制 + 超时重传机制),保证了

  1. TCP在尽自己最大的努力,把数据发送给对方

  1. TCP在最终发送失败之后,通知了进程发送失败的事实

涉及TCP包头:

  1. TCP一个segment,既可以当发送segment,也可以当确认segment使用。

SN + 携带数据(payload) -> 发送作用

ack 标志位 + ASN -> 确认作用

SN:本次数据的第一个字节的编号

ASN:希望下次发送的第一个字节的编号

连接管理机制

  1. TCP有发送缓冲区,发送之后不可以直接丢弃,因为可能要重发,所以至少要一个地方保存这些数据。

  1. TCP有接受缓冲区。

  1. TCP需要维护发送时的序号 SN = x ,才可以用于发送时填充SN字段

TCP 还需维护已经接收的数据的序号 ASN = y,才可以进行去重

为什么TCP要设计建立连接

  1. 必须确认对方存在,才能可靠的传输

  1. 交换一些必要的数据(SN不是直接从1开始的,会双方各自生成,随后需要交换)

所以在正式通信之前,需要一个阶段:

  1. 确认对方在线

  1. 同步一些基本信息

TCP大体分为3个阶段

【建立连接阶段】 【正式通信阶段】 【断开连接阶段】

拨电话 打电话 挂电话

TCP的状态:表示当前连接目前地状态

建立连接阶段

主动连接方(打电话的角色) 大部分是Client

被动连接方(接电话的角色) 大部分是Server

  1. 主动连接方 确认对方在线 + 告诉对方自己的信息

  1. 被动连接方 进行应答

  1. 被动连接方 确认对方在线 + 告诉对方自己的信息

  1. 主动连接方 进行应答

(2和3基本是同一时间发生的,TCP的segment可以既承载发送数据,又承载应答的职责)

结论:2和3是会被合并的也就是三次握手

TCP的三次握手过程

segment的种类:发送segment,确认segment,同步信息(握手阶段使用)segment,挥手segment

ack = 0 没有确认的意思 ack = 1 有确认的意思

syn = 0 没有同步的意思 syn = 1 有同步的意思

fin = 0 没有挥手的意思 fin = 1 有挥手的意思

TCP的状态变更角度

establish:建立连接

closed:虚拟状态

listen:被动连接方(服务器已经启动,但没有真正的建立连接)

syn_rcvd:收到了sync

syn_sent:sync已经发送了

流程图:

从代码角度观察TCP的状态变更

codeA

codeB

codeC

PS:

codeC 的方法(构造)会一直阻塞,直到3次握手阶段,换言之,应用层是看不到三次握手的细节过程

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值