中国男女做网站,潍坊大型网站建设平台,网站建设的目地,兰州百度公司开户文章目录 1.引入2.协议段格式4位首部长度16位窗口大小32位序号思考三个问题【demo】标记位URG: 紧急指针是否有效提升某报文被处理优先级【0表示不设置1表示设置】ACK: 确认号是否有效PSH: 提示接收端应用程序立刻从TCP缓冲区把数据读走RST: 对方要求重新建立连接; 我们把携带R… 文章目录 1.引入2.协议段格式4位首部长度16位窗口大小32位序号思考三个问题【demo】标记位URG: 紧急指针是否有效提升某报文被处理优先级【0表示不设置1表示设置】ACK: 确认号是否有效PSH: 提示接收端应用程序立刻从TCP缓冲区把数据读走RST: 对方要求重新建立连接; 我们把携带RST标识的称为复位报文段SYN: 请求建立连接; 我们把携带SYN标识的称为同步报文段FIN: 通知对方, 本端要关闭了, 我们称携带FIN标识的为结束报文段 总结标记位总结报头属性 1.引入 之前讲的网络版计算机/http协议 都是基于tcp协议 哪里体现出来我们用了tcp套接字编程及三次握手等。 TCP协议 TCP全称为 “传输控制协议(Transmission Control Protocol”). 人如其名, 要对数据的传输进行一个详细的控制; 用户级缓冲区 自己定义的string/char buffer write/read/recv/send --》不是发送函数 而是拷贝函数 这些接口本质不是把数据发送到网络中 而是把数据从用户级缓冲区拷贝到发送缓冲区里。发送缓冲区里的数据什么时候发送发送多少出错了怎么办 — 由OS的TCP协议自主决定 似曾相识 讲文件时我们提到 把自己的charBuf的数据调用write接口”写“到文件里 实际上write是把用户级缓冲区的数据拷贝到文件缓冲区每个文件都有自己的文件缓冲区刷新策略由OS控制把磁盘换成网卡是不是就理解了文件读写属于IO网络也一样在用户层做报头和有效载荷分离序列反序列把这些数据调用write接口拷贝到发送缓冲区之后就由OS来管理了 read读文件/接收缓冲区 阻塞 接收缓冲区没有数据 阻塞等待 将read进程挂起 当接收缓冲区有数据OS内某些条件就绪了 再调度。 一个文件可以同时读写 一个文件描述符配备两个缓冲区发送/接收 发送/接收缓冲区实际上是内存空间 OS为了管理内存 把他们划分为4kb内存块 哪些内存块被占用/被系统锁住不能换入换出/ 需要刷新管理–每一个内存块都有一个struct page{}这里的发送接收缓冲区实际上是很多个struct page管理的内存块。对内存的管理变成对结构体数组的增删查改打开网络–打开一个文件–文件描述符–struct file{}–本应指向磁盘 现在让他指向网络设备 再加上两个缓冲区–网络IO 传输控制协议的控制体现在哪里 数据从用户级缓冲区到发送缓冲区后 什么时候发到网络 发多少 出错怎么办 由TCP协议自主决定 – 控制。udp没有发送缓冲区 自然无法做到控制udp一直发 接收端收不下的多于内容就丢弃了 但是tcp有”控制“它可以让接收端尽快清空接收缓冲以便于接收新数据。
2.协议段格式 源/目的端口号: 表示数据是从哪个进程来, 到哪个进程去; 32位序号/32位确认号: 后面详细讲; 4位TCP报头长度: 表示该TCP头部有多少个32位bit(有多少个4字节); 所以TCP头部最大长度是15 * 4 60 16位校验和: 发送端填充, CRC校验. 接收端校验不通过, 则认为数据有问题. 此处的检验和不光包含TCP首部, 也包含TCP数据部分. 16位紧急指针: 标识哪部分数据是紧急数据 不同的名字 4位首部长度
计算时有基本单位 4B
[00001111] -- [015] — [060] 如果没有选项 只有标准报头 那么 4位首部长度应该存5 报头和有效载荷如何分离 固定长度标准报头长度20B 自定义字段4位首部长度x 收到一个报文 截取20B获取标准报头header 提取header的x x-20即为选项长度 再截取x-20即为选项 剩下的报文即为有效载荷
16位窗口大小 前面学了应用层 现在在学传输层 对于整个协议栈 只考虑应用层和传输层 我们要有以下的认识 客户端在应用层构建了一个http请求 交付给传输层 传输层会加一个tcp报头。服务端在传输层接收到会分离报头和有效载荷。client和server基于tcp协议进行通信互发消息的时候发送的是完整的tcp报文即一定携带完整的tcp报头! 理解http请求与响应发送数据等都是一个完整的报文即只要想通过网络通信那么就要封装和分离报头。一个tcp链接在应用层看 实际上就是一个fd配着两个缓冲区发送缓冲区/接收缓冲区。 讲可靠性 先了解什么是不可靠 数据重复/乱序/丢包 丢包接收端的接收缓冲区已经满了 发送方并不知道还在发 丢包怎么解决当接收缓冲区已经满想办法让发送方知道并发慢一点。—流量控制。 怎么做到流量控制 tcp可靠性中有丢包重传/超时重传。那么不做流量控制发送方就一直发接收方没收到发送方重传这样可以吗?可以但是不合理这样会消耗资源一个正常的数据发过来由于接收方缓冲区满而让发送方重传不合理消耗资源降低效率这种情况重传机制并不合理比较好的做法是让发送方发慢一点! TCP凭什么保证可靠性 一个基本特点应答机制接收方收到数据就会应答表示自己收到了上面已经提到 此处说的发送消息或者确认应答 只要经过网络 那么他就要带着报文 发送方发送速度的依据 由接收方接收缓冲区的剩余空间大小决定发送方怎么得知接收方的应答是一个带着tcp报头的报文报头中【16位窗口大小】的字段就是【接收方接收缓冲区的剩余空间大小】。 【16位窗口大小】是发送方自己的接收缓冲区剩余空间大小 CS双方通过携带这一字段 告知对方你给我发数据时要根据这个悠着点来
32位序号 世界上不存在百分百可靠的网络协议 发送方发了一条信息 收到了应答 可以确定我最近发送的信息对方收到了没有收到应答 不能保证对方收到了永远存在一条最新的消息 是没有应答的 局部上存不存在百分百可靠的网络协议 最新一条信息之前的信息都能保证是可靠的除了最新的消息 之前的每一条信息都有应答实际上没有必要对应答做应答 — 死循环 tcp最基本最原始的通信过程 发送方发了一条信息 接收方应答 就可以保证发送方发的消息被接收方成功收到了发送方有必要对应答做应答吗没必要发送方不必告知接收方我收到你的应答了发送方需要应答的目的是需要知道接收方到底收到没有接收方不需要应答是反正我已经收到了我不需要关心发送方知不知道我收到了即只要保证发送方发的消息接收方收到了就行 保证这两个方向上的可靠即我发送后知道你有没有收到你发送后知道我有没有收到。 关于应答 发送方发送数据后 如果一段时间没有收到应答 认为接收方没有收到数据 重传 接收方发的应答丢失了怎么办同上这也引来一个问题发送方发送的数据发送给网络后还要在发送缓冲区里待一段时间如果没有收到应答还得重传如果收到应答如果这段数据之后不用了就可以移出发送缓冲区 优化 – 捎带应答【应答要发的消息】 发送方一次发很多消息 发一条需要接收到应答才发下一条 … 这样是十分低效的一次发一批 发10条收10条应答 ---- 更真实的tcp tcp发的时候按顺序发 收的时候呢 先发的不一定先收经过网络受等多方面影响。---- 数据包乱序 – 乱序是不可靠的一种场景数据以乱序发给接收方这个是不可控的怎么办 32位序号的应用场景 发送方发送数据时 对各个报文编号 【32位序号】一个作用就是保证数据按序到达即接收方收到后排序接收 序号是什么 发送方发送的数据从用户层拷贝到发送缓冲区然后OS把发送缓冲区里的完整数据一个个发给网络。发送缓冲区实际上是一个char 字符数组buf – 面向字节流由于是数组每个字节天然都有一个编号即数组下标每一块数据在buf里占连续的空间每个数据块的最后一个字符的下标就是【序号】 一批发送一批响应 响应是对哪一个数据的响应 【确认序号】 收到的报文序号 1 。意义表示确认序号之前的数据我已经全部收到了下次发送请从确认序号指定的数字开始发送 10012001发送时丢失了但是发送方收到了3001说明接收方在3001之前的数据都接受到了 – 允许存在应答丢失情况、 如果接收方压根没有收到2000但是收到了10003000然后应答10013001发送方收到3001是不是仍然认为接收方接收到3001前的数据这种场景不是错的吗 这种情况接收方收到10003000没收到2000应答时不会应答3001只会应答1001【后面还会细讲此场景】 tcp协议段中有了32位序号后为什么还要有32位确认序号 接收方应答时可能同时发送数据那么就需要指明自己发送数据的序号。发送方在发送数据的同时可能也在接收数据双方地位对等。
思考三个问题【demo】
之前模拟浏览器服务端 我们只在应用层编码 至于数据怎么传的 底层实际上做了很多工作 在应用层我们不学 之后我们慢慢学16位窗口大小发送方自己的接收缓冲区剩余空间大小。但是历史上第一次发送方向接收方发信息他怎么知道接收方的窗口大小即他怎么知道他要发多少数据才合适多批量传输时 报文和应答丢失的情况。
标记位 6个标记位 建立链接三次握手 开始进行数据通信 断开连接四次挥手 。在tcp通信时这些行为都会发生tcp报文不同的行为引发不同的动作意味着tcp收到的报文是有各种”类型“的不同的类型决定了接收方要做不同的动作。接收方如何得知报头的类型通过6个标记位标记位的意义区分tcp报文的类型 简述 您已经列举了TCP协议中的六个重要标志位flags每个标志位都在TCP通信中扮演着不同的角色。以下是这些标志位的简要介绍
URG (Urgent): 作用表示TCP报文段的紧急指针Urgent Pointer是否有效。 解释当URG标志位被设置时TCP的紧急指针会指出紧急数据在报文段中的位置。这允许发送方标记一些数据为“紧急”这样接收方就可以优先处理这些数据而不是按照正常的顺序来处理。 ACK (Acknowledgment): 作用表示确认号Acknowledgment Number是否有效。 解释ACK标志位用于确认接收到的数据。当TCP发送一个报文段时它会期望对方返回一个包含ACK标志的报文段以确认数据的接收。ACK确认号表示接收方下一个期望接收的字节的序列号。 PSH (Push): 作用提示接收端的应用程序立刻从TCP缓冲区把数据读走。 解释PSH标志位用于通知接收端的应用程序尽快从TCP的接收缓冲区中读取数据。在某些情况下即使接收缓冲区中的数据量未达到应用程序的读取阈值PSH标志也可以确保数据被立即读取。 RST (Reset): 作用对方要求重新建立连接我们把携带RST标识的称为复位报文段。 解释RST标志位用于异常关闭连接。当TCP检测到严重错误如主机崩溃或者收到一个非法的报文段时它可能会发送一个RST报文段来关闭连接。RST报文段不携带数据并且会释放所有关联的资源。 SYN (Synchronize): 作用请求建立连接我们把携带SYN标识的称为同步报文段。 解释SYN标志位用于建立一个新的连接。在三次握手过程中第一个报文段SYN报文段会包含SYN标志位并设置初始的序列号。接收方会回复一个SYN-ACK报文段包含SYN和ACK标志位表示它同意建立连接并确认收到的序列号。 FIN (Finish): 作用通知对方本端要关闭了我们称携带FIN标识的为结束报文段。 解释FIN标志位用于正常关闭连接。当一方决定关闭连接时它会发送一个FIN报文段给另一方。接收方会回复一个ACK报文段来确认这个FIN报文段并在完成所有数据的发送后发送一个自己的FIN报文段来关闭连接。 这些标志位共同构成了TCP协议的核心部分确保了数据在网络中的可靠传输。 总结 ACK/SYN/FIN以非数据传送为目的 有一些控制传输的含义在其中。OS不会直接暴露这些标记位给用户 但是或多或少会给用户提供接口让用户设置 如connect–》synclose–》fin给对方发一个含有fin标记位的报文 详述 URG: 紧急指针是否有效提升某报文被处理优先级【0表示不设置1表示设置】
一般情况tcp数据报文一个大数据分成很多小数据发按123456顺序发接收时不一定是123456但是收到后他要根据32位序号排序成123456。在tcp协议下某些报文是不允许插队的即接收方只能按照特定顺序依次处理报文。但是如果接收方收到了带有urg的报文TCP协议段的16位紧急指针会指出紧急数据在报文段中的位置接收方收到后会优先处理该数据包。 紧急指针报文中有效载荷中的紧急数据的偏移量。 tcp中一个报文中一般只允许出现一个字节的紧急数据。 如何使用urg 在支持带外数据的套接字上发送带外数据(例如SOCKSTREAM类型);底层协议也必须支持带外数据。 此标志请求接收正常数据流中不会接收的带外数据。一些协议将加急数据放在正常数据队列的头部因此这个标志不能用于这样的协议。 什么场景用 c向s发起服务请求s响应很慢或者几乎不响应但是s并没坏他可能因为某种计算很复杂而一直计算此时c并不知道持续向s发送请求但是没有响应于是c向s发送了带外数据紧急数据询问s你到底在干嘛s中有例程专门处理紧急数据相应一个带有服务器状态的报文给c让c知道s在干嘛。s要支持读取紧急数据且s在软件设计上设计了某一状态用某一种编号代替
ACK: 确认号是否有效
三次握手成功后 几乎所有的应答报文的ack都是置为1的表示我是一个应答报文至于是不是捎带应答看看是否存在有效载荷。
PSH: 提示接收端应用程序立刻从TCP缓冲区把数据读走 情景 数据从网络里发到接收方 OS把网络数据存至接收缓冲区 用户层决定读不读接收缓冲区里的内容。如果用户一直不读 接收缓冲区里的空间就会越来越少。OS把网络数据放到接收缓冲区用户从接收缓冲区读》PCMode流量控制–》发送过程【发送者的发送缓冲区到接收者的接收缓冲区】的同步接收方接收缓冲区的数据一直不被取走发送方发送缓冲区的数据有一天会被拷贝满这时在发送方用户层就不能再向发送缓冲区写数据—》写阻塞发送方阻塞等待等到什么时候有没有判定依据1. 定期询问对方2. 当接收方接收缓冲区有空间了给发送方发通知。 接收方一直不读呢发送方就会发送一个带有psh标记位的报文接收方就会得知发送方已经着急了提示接收端应用程序立刻从TCP缓冲区把数据读走!同样一个合格的服务器也应该及时的读取数据宏观上提升网络通信效率也有可能一个捎带psh即带有数据psh标记位的报文让服务器尽快接收数据。
RST: 对方要求重新建立连接; 我们把携带RST标识的称为复位报文段
tcp协议保证可靠性正常通信下 tcp提供对于数据的很多种可靠策略 但是也有一些情况无法避免客户端不想通信了 也不挥手 直接拔了网线。所以tcp的可靠性的前提是不会出现一些不可抗拒的异常问题 即tcp不能保证三次握手每次都成功即便三次握手不成功但是三次握手每一步都做了 tcp也会开始通信。tcp允许链接建立失败服务器内部可能存在多个建立好的链接他在跟多个客户端通信。服务端存在很多链接管理–》先描述再组织链接—结构体属性—成员变量很多链接—链表 维护链接有成本 创建内核数据结构对象 初始化 填充字段》空间时间 链接太多 管理不过来 异常 客户端认为链接建立好了 服务端认为没建立好 服务端发送带有rst标记位的报文要求重新建立连接 画图线是斜的数据经过网络—有延迟 问题首先要知道三次握手重在三次至于是否建立好了连接不知道。 服务端接收回应接收三次后认为三次握手已完成。而客户端最后一次发送并没有响应他会认为只要他第三次发出去了就握手了–就建立链接了不考虑重传正常情况下客户端不知道服务端是否收到tcp在赌第三次的ack能被服务端收到既然第三次ack一经发出客户端就认为建立好了连接那么客户端此时就会创建连接的结构体对象并初始化填充属性准备通信。但是ack经过网络发到服务端需要时间在这个时间间隔内CS对于是否建立好连接认知不一致此时客户端认为建立好连接了就会开始给服务端发送数据。如果服务端没收到这个ack却突然收到了一个数据服务端就会意识到最后一个ack丢失了对方虽然建立好连接了但是我没有于是服务端就给客户端发送一个带有rst标记位的报文 rst标记位只有这一种场景吗 三次握手双方都建立成功了即第三次ack成功发送但是服务端断网重启了客户端不知道发送信息时服务端就会回应一个带有rst的报文。即rst应用于建立连接时正常通信中都会出现协议/网络问题导致要使用rst 第三种场景 服务器满载了即建立连接数已最大客户端就会给服务端发送带有rst的报文请求重新建立连接。 SYN: 请求建立连接; 我们把携带SYN标识的称为同步报文段
FIN: 通知对方, 本端要关闭了, 我们称携带FIN标识的为结束报文段
总结标记位
tcp报文有的用来进行数据通信 有的用来进行特殊功能–连接管理等 或者二者皆有之。
总结报头属性
tcp是可靠的协议 故协议中有很多属性就提高了可靠性有的属性为了提升传输效率。有很多为可靠性的设计的策略在tcp中也是体现不出来的比如流量控制重传。下一篇讲。