Socket-TCP

在TCP/ip协议中,用源IP、源端口号、目的IP、目的端口号、协议号这样一个五元组来标识一个通信!

端口号范围划分

  • 0 - 1023: 知名端口号,HTTP,FTP,SSH 等这些广为使用的应用层协议,他们的端口号都是固定的。
  • 1024 - 65535: 操作系统动态分配的端口号。客户端程序的端口号,就是由操作系统从这个范围分配的。

认识知名端口号 (Well-Know Port Number)

有些服务器是非常常用的,为了使用方便,人们约定一些常用的服务器,都是用以下这些固定的端口号:

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

执行下面的命令,可以看到知名端口号
cat /etc/services

一个进程可以绑定多个端口号一个用来收数据一个用来传数据;一个端口号不可以被多个进程绑定。

TCP(传输控制协议,Transmission Control Protocol )是一种位于传输层的通信协议。

应用场景

适用于对数据准确性、完整性、顺序性要求高的场景 ,如文件传输(FTP 基于 TCP ) 、网页浏览(HTTP 基于 TCP ) 、电子邮件(SMTP 基于 TCP ) 等。

TCP协议格式首部

  1. 源端口号(16 位):标识数据发送方应用程序端口,便于接收方后续回传数据能找到对应端口 。比如客户端浏览器发起 HTTP 请求,会用一个随机的源端口号。
  2. 目的端口号(16 位):指明数据要抵达的目标应用程序端口,像 HTTP 协议默认目的端口号 80 ,用于定位 Web 服务器应用 。
  3. 序号(32 位):给 TCP 传输的每个字节编号,在建立连接和数据传输时,保证字节按序传输 。例如发送一篇长文档,每个字节都有序号。
  4. 确认序号(32 位):接收方告知发送方下一个期望接收的字节序号,发送方依此判断哪些数据已成功接收,哪些需重传 。
  5. 首部长度(4 位):以 4 字节为单位指示首部长度,因首部中选项字段可变长,取值范围对应 0 - 60 字节 ,无选项时通常为 20 字节 。
  6. 保留(6 位):预留字段,当前未使用,默认置 0 。
  7. 标志位(6 位)

  1. 窗口大小(16 位):这个窗口大小其实代表的是缓冲区里面剩余空间把它放在报头里面目的是,想让接收方得知目前传送过去的数据,对方的接受速度是多少,来调整一下自己的发送速度(流量控制)。
  2. 检验和(16 位):对 TCP 首部、数据及伪首部计算校验和,检测传输过程中数据有无错误 。
  3. 紧急指针(16 位):当 URG 标志位为 1 时有效,指向紧急数据末尾,方便接收方优先处理紧急数据 。

选项与数据

  1. 选项:可选字段,长度可变,用于实现如最大段长度声明、窗口扩大等扩展功能 。
  2. 数据:即有效载荷,承载应用层传来的数据,TCP 负责可靠传输这部分数据 。

超时重传机制:

如果你的数据发送过去后没有得到应答,等到了一定时间就会重新补发,这个机制叫做超时重传机制,这个时间是动态的,会根据你的网络环境进行调整的,当你面临的情况是应答丢失的时候,此时它主机b会得到两个相同的数据,此时的主机b会进行去重操作,会根据你的报头里面的32位序号进行查重去重!当你面临的情况是始终重传不成功,系统会认为你的网络出现了异常,会自动断开两个主机的连接!

面对主机B收到重复的信息,此时操作系统可以根据报文里面的序号,进行去重操作!

TCP 连接管理机制详解

TCP 连接管理主要包括建立连接和断开连接两个过程,分别通过三次握手和四次挥手实现。

TCP的三次握手:刚开始客户端进行了connect在客户端状态没有变为ESTABLISHED之前一直处于阻塞状态,第一次握手是客户端给服务器发送的报文是SYN类型的(申请建立连接)此时的客户端状态为SYN_SENT,当你服务器收到发来的申请后状态变为SYN_RCVD,然后向客户端发送SYN+ACK(申请建立连接和确认收到了客户端发来的SYN)这是第二次握手,当客户端收到了来自服务器的应答后状态变为ESTABLISHED,随后向服务器发送ACK(确认自己收到了应答),收到信息后的服务器状态变为ESTABLISHED,此时的服务器会把刚刚完成三次握手后分配到的新的连接fd,交给accept,第三次握手的时候其实是已经可以携带数据了,做出捎带应答!

建立连接以后的通信:所用到的write和read其实都是面向发送缓冲区和接受缓冲区进行操作的!

TCP四次挥手:第一次挥手是客户端给服务器发FIN,客户端的状态变为FIN_WAIT_1,服务器接受到了以后状态变为CLOSE_WAIT,第二次挥手然后给客户端发送ACK应答,接收到信息的客户端状态变为FIN_WAIT_2,第三次挥手紧接着服务器会向客户端发送FIN,状态变为LAST_ACK,客户端收到断开连接请求以后状态变为TIME_WAIT,第四次挥手就是客户端给服务器的应答,状态变为CLOSED!

解决疑问:

至少三次握手是因为:1.客户端和服务端各自都要至少进行一次收报文和发报文,这样其实可靠验证了全双工通路是否通畅!!!2.奇数次握手,在一般情况,握手失败的连接成本嫁接给了客户端!

为什么两次不行是因为:当你服务器再发回给客户端的信息,你并不能知道客户端到底有没有收到!

为什么一次不行是因为:会发生SYN洪水,直到服务器内存不够分配的时候会导致服务中断!

插入知识点:SYN洪水:

SYN洪水不止一次握手会出现:SYN 洪水(SYN Flood)是一种常见的 DoS(Denial of Service,拒绝服务)攻击手段,它利用了 TCP 协议在建立连接时三次握手的漏洞来实施攻击,以下是关于 SYN 洪水攻击的详细介绍:

攻击原理

正常情况下,TCP 建立连接需要经过三次握手。客户端发送 SYN 包请求建立连接,服务器收到后回复 SYN + ACK 包并分配资源等待客户端的 ACK 包完成连接建立。而 SYN 洪水攻击中,攻击者会伪造大量源 IP 地址,向目标服务器发送大量的 SYN 包。服务器收到这些请求后,会为每个请求分配资源并发送 SYN + ACK 包进行响应,然后等待客户端的 ACK 包。由于攻击者使用的是伪造的 IP 地址,服务器无法收到这些伪造客户端的 ACK 确认,会不断重传 SYN + ACK 包,并长时间保留这些半连接状态的资源,直到超时。当服务器的半连接队列被填满后,就无法再处理正常用户的连接请求,导致正常用户无法与服务器建立连接,从而实现拒绝服务的目的。

防范措施

  • 防火墙配置:通过防火墙设置规则,限制来自同一 IP 地址的 SYN 请求速率,防止单个 IP 地址发送过多的 SYN 包。
  • TCP SYN Cookie 技术:服务器在收到 SYN 包时,不立即分配资源,而是根据 SYN 包的信息生成一个特殊的 Cookie(一种加密的序列号),并将其包含在 SYN + ACK 包中发送给客户端。当客户端返回 ACK 包时,服务器根据 ACK 包中的信息验证 Cookie 的有效性,如果验证通过,则建立连接。这样可以避免服务器为大量伪造的 SYN 请求分配资源。
  • 增加服务器资源:增加服务器的内存、CPU 等资源,提高服务器的处理能力和抗攻击能力。
  • 入侵检测系统(IDS)/ 入侵防御系统(IPS):部署 IDS/IPS 系统,实时监测网络流量,检测并阻止 SYN 洪水攻击。

从这个攻击原理其实可以明白:在三次握手中最怕的一次握手是第三次客户端给服务器的应答ACK,假如你是只有两次握手,那你的第二次握手丢失以后整个压力就会给到服务端,导致服务崩溃,但是如果你是三次握手,就不是这样,因为如果丢失了第三次握手,整个压力就会给到客户端上,这样就能保证服务器的稳定性!

四次挥手原因:

它不进行捎带应答是因为服务器与客户端进行关闭通信的时候存在着“协商”!

  • TCP 协议规定,主动关闭连接的一方要处于 TIME_WAIT 状态,等待两个 MSL (maximum segment lifetime) 的时间后才能回到 CLOSED 状态。
  • 我们使用 Ctrl - C 终止了 server,所以 server 是主动关闭连接的一方,在 TIME_WAIT 期间仍然不能再次监听同样的 server 端口;

为了避免这种情况,所以可以去用setsockopt。

  • MSL 在 RFC1122 中规定为两分钟,但是各操作系统的实现不同,在 Centos7 上默认配置的值是 60s;
  • 可以通过cat /proc/sys/net/ipv4/tcp_fin_timeout查看 msl 的值;
  • 规定 TIME_WAIT 的时间请读者参考 UNP 2.7 节;

MSL:一个报文它在网络中存活的时间是有限的!

当你第三次挥手结束,如果第四次挥手丢失,导致服务端收不到最后的一个ACK,此时Time_wait的时间可以让服务端端有足够的时间去补发一个FIN!等待时间一般为两个MSL(在传输过程中最大存在时长,这个一般是不确定的,因为如果遇到一个阻塞,那存在时长就大了)

流量控制:

接收端处理数据的速度是有限的。如果发送端发的太快,导致接收端的缓冲区被打满,这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等一系列连锁反应。
因此 TCP 支持根据接收端的处理能力,来决定发送端的发送速度。这个机制就叫做流量控制 (Flow Control):

  • 接收端将自己可以接收的缓冲区大小放入 TCP 首部中的 “窗口大小” 字段,通过 ACK 端通知发送端;
  • 窗口大小字段越大,说明网络的吞吐量越高;
  • 接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值通知给发送端;
  • 发送端接收到这个窗口之后,就会减慢自己的发送速度;
  • 如果接收端缓冲区满了,就会将窗口置为 0;这时发送方不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端。

流量控制属于可靠性还是效率?可靠性!

滑动窗口:

刚才我们讨论了确认应答策略,对每一个发送的数据段,都要给一个 ACK 确认应答。收到 ACK 后再发送下一个数据段。
这样做有一个比较大的缺点,就是性能较差,尤其是数据往返的时间较长的时候。

滑动窗口的大小,根据接受方缓冲区的剩余大小进行调整,这样可以保证滑动窗口里面的数据一次性传给接收方不会导致数据丢包!

关于缓冲区:

TCP 协议依靠发送缓冲区来保存已经发出但未收到应答的报文 。具体如下:

  • 缓冲区划分:发送缓冲区通常分为三部分。已发送已确认的数据,这部分数据传输已完成,可被后续数据覆盖;已发送未确认的数据,即暂时保存等待应答的报文所在区域,这部分区域也属于滑动窗口范畴,其最大范围由对方接收窗口大小决定 ;未发送未确认的数据,是等待发送且未得到接收方接收许可的数据。通过设置指针(如指向窗口开始和结束的指针)或数字下标来区分这些区域,随着数据发送和确认,指针移动实现窗口滑动 。
  • 保存作用:发送缓冲区保存已发送未确认报文,是为实现可靠传输。若发送方在一定时间(由超时重传时间 RTO 决定 )内未收到接收方对应答报文的确认,就会从发送缓冲区取出对应报文副本重传 。 比如网络拥塞导致报文丢失或延迟到达接收方,接收方无法及时返回确认,发送方超时后从缓冲区取出报文重发,保障数据最终能送达接收方。 同时,滑动窗口机制也基于发送缓冲区这些划分来控制数据发送速率,避免接收方处理不过来。

传输异常处理:

若窗口更新通知在传输途中丢失,发送主机 A 无法得知接收主机 B 窗口状态变化,会导致通信受阻。此时,发送主机 A 会定时发送窗口探测包,来主动获取窗口信息,以便恢复数据传输。

滑动窗口机制通过动态调整窗口大小,在保障数据可靠传输的同时,还能适应网络和接收端的不同状态,有效提升网络传输效率,避免网络拥塞和数据丢失。

注意:快重传并不是超时重传机制!超重传机制可以理解为是兜底的,而快重传是提高效率的!

快重传机制是 TCP 协议中用于快速检测并恢复丢失数据包的机制 。当接收方收到乱序数据包时,会立即向发送方发送重复确认 。当发送方累计收到三个相同的重复确认时,就会判定对应的数据包已丢失,不等重传超时,直接重传该数据包 。比如发送方发送数据包 1、2、3、4 ,若数据包 2 丢失,接收方收到 1、3、4 后发送重复确认,发送方收到三个重复确认,就快速重传数据包 2 。该机制减少了网络传输延迟,提升了 TCP 协议在网络传输中的效率和可靠性 。

延迟应答

如果接收数据的主机立刻返回 ACK 应答,这时候返回的窗口可能比较小。

  • 假设接收端缓冲区为 1M,一次收到了 500K 的数据;如果立刻应答,返回的窗口就是 500K;
  • 但实际上可能处理端处理的速度很快,10ms 之内就把 500K 数据从缓冲区消费掉了;
  • 在这种情况下,接收端处理还远没有达到自己的极限,即使窗口再放大一些,也能处理过来;
  • 如果接收端稍微等一会再应答,比如等待 200ms 再应答,那么这个时候返回的窗口大小就是 1M;

一定要记得,窗口越大,网络吞吐量就越大,传输效率就越高。我们的目标是在保证网络不拥塞的情况下尽量提高传输效率;

那么所有的包都可以延迟应答么?肯定也不是;

  • 数量限制:每隔 N 个包就应答一次;
  • 时间限制:超过最大延迟时间就应答一次;

拥塞控制

虽然 TCP 有了滑动窗口这个大杀器,能够高效可靠的发送大量的数据。但是如果在刚开始阶段就发送大量的数据,仍然可能引发问题。
因为网络上有很多的计算机,可能当前的网络状态就已经比较拥堵。在不清楚当前网络状态下,贸然发送大量的数据,是很有可能引起雪上加霜的。
TCP 引入慢启动机制,先发少量的数据,探探路,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据。

一个主机缓解不了网络拥塞,但是一群主机就可以缓解了!

看下图分析:

慢启动

TCP 启动时,拥塞窗口(cwnd)初始值通常为 1 ,慢启动阈值(ssthresh)等于窗口最大值(如初始值为 16 ) 。在慢开始阶段,cwnd 按指数规律增长。每收到一个确认应答,cwnd 就增加 1 。这使得发送方发送的数据量迅速增加,网络吞吐量逐渐上升。例如,从传输轮次 0 开始,cwnd 从 1 逐步增长,快速提升数据发送量。

拥塞避免

当 cwnd 增长到慢启动阈值(如达到 16 )后,进入拥塞避免阶段。此时,cwnd 不再按指数增长,而是采用 “加法增大” 策略,即每收到一个确认应答,cwnd 增加一个较小的固定值(如 1 ) 。这种方式让发送方数据发送量缓慢、平稳增加,防止网络因发送数据量增长过快而拥塞。

网络拥塞处理

若出现大量丢包,判定为网络拥塞。此时采取 “乘法减小” 策略,ssthresh 值变为原来的一半(如从 16 变为 12 ) ,同时 cwnd 置回 1 ,重新进入慢开始阶段。这能迅速降低发送方数据发送量,缓解网络拥塞。少量丢包时,仅触发超时重传,不调整 ssthresh 和 cwnd 。

TCP 拥塞控制机制在追求快速数据传输的同时,平衡网络负载,避免拥塞,就像热恋中把握节奏,既积极又不过度,保障网络通信顺畅。

TCP是面向字节流:

面向字节流:读和写不需要匹配。TCP是面向字节流,UDP面向数据报,udp写一次就得读一次!

粘包问题:说简单就是,不知道一段报文从哪开始到哪结束,从而导致读取报文错误!

TCP异常情况:

当你的进程终止的时候(无论是客户端还是服务端或者两个同时),此时我们应该知道linux下一切皆文件,包括通信。有因为文件的生命周期是随进程的,所以进程终止了,通信也要结束了,此时通信进行正常的四次挥手既可!

TCP/UDP的区别:

TCP 和 UDP 均为传输层协议。TCP 面向连接,靠三次握手建立连接,有确认应答、重传等机制保障可靠传输,开销大,适用于文件传输等对数据准确性要求高场景;UDP 无连接,不保证可靠交付,传输效率高,适合在线视频等实时性要求高、能容忍丢包场景。

TCP中可靠性和效率:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/904448.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据Spark(五十八):Spark Pi介绍

文章目录 Spark Pi介绍 Spark Pi介绍 Spark Pi是Apache Spark官方提供的一个示例程序,该案例使用 Spark 进行分布式计算,通过蒙特卡罗方法估算圆周率(π)的值,其估算π原理如下: 上图中,正方形…

Doris索引机制全解析,如何用高效索引加速数据分析

在当今大数据时代,企业对于实时数据分析的需求呈现爆发式增长。面对动辄PB级的数据量和秒级响应的业务诉求,传统数据库系统往往力不从心。Apache Doris作为新一代MPP分析型数据库,凭借其独特的索引机制,在京东、美团等企业的实时数…

基于SpringBoot + Vue 的作业管理系统

产品包含: 项目源码数据库文件论文ppt 技术栈 架构: B/S、MVC 系统环境:Windows/Mac 开发环境:IDEA、JDK1.8、Maven、Mysql 技术栈:Java、Mysql、SpringBoot、Mybatis、Vue 功能模块 用户模块:学生用户、管理员、…

HCL(HashiCorp Configuration Language)是一种结构化配置语言

HCL(HashiCorp Configuration Language)是一种结构化配置语言,语法简洁且可读性强,广泛用于 Docker Buildx Bake、Terraform、Nomad 等工具的配置。以下是其核心语法规则和示例: 1. 基础结构 HCL 使用 块(…

《AI大模型应知应会100篇》第50篇:大模型应用的持续集成与部署(CI/CD)实践

第50篇:大模型应用的持续集成与部署(CI/CD)实践 🧾 摘要 在AI大模型开发中,随着模型版本迭代频繁、依赖复杂、部署环境多样,构建一套高效可靠的持续集成与持续交付(CI/CD)流程显得尤…

【Linux深入浅出】之全连接队列及抓包介绍

【Linux深入浅出】之全连接队列及抓包介绍 理解listen系统调用函数的第二个参数简单实验实验目的实验设备实验代码实验现象 全连接队列简单理解什么是全连接队列全连接队列的大小 从Linux内核的角度理解虚拟文件、sock、网络三方的关系回顾虚拟文件部分的知识struct socket结构…

DB-GPT V0.7.1 版本更新:支持多模态模型、支持 Qwen3 系列,GLM4 系列模型 、支持Oracle数据库等

V0.7.1版本主要新增、增强了以下核心特性 🍀DB-GPT支持多模态模型。 🍀DB-GPT支持 Qwen3 系列,GLM4 系列模型。 🍀 MCP支持 SSE 权限认证和 SSL/TLS 安全通信。 🍀 支持Oracle数据库。 🍀 支持 Infini…

2025五一数学建模竞赛A题完整分析论文(共45页)(含模型、可运行代码、数据)

2025年五一数学建模竞赛A题完整分析论文 摘 要 一、问题分析 二、问题重述 三、模型假设 四、符号定义 五、 模型建立与求解 5.1问题1 5.1.1问题1思路分析 5.1.2问题1模型建立 5.1.3问题1参考代码 5.1.4问题1求解结果 5.2问题2 5.2.1问题2思路分析 …

[学习]RTKLib详解:pntpos.c与postpos.c

文章目录 RTKLib详解:pntpos.c与postpos.cPart A: pntpos.c一、概述二、整体工作流程三、主要函数说明1. pntpos()2. satposs()3. estpos()4. rescode()5. prange()6. ionocorr()7. tropcorr()8. valsol()9. raim_fde()10. estvel() 四、函数调用关系图(…

【科研绘图系列】R语言绘制世界地图(map plot)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载导入数据数据预处理画图输出图片系统信息介绍 【科研绘图系列】R语言绘制世界地图(map plot) 加载R包 library(ggmap) library(RColorBrewer) library(pals) …

在pycharm profession 2020.3上安装使用xlwings

之前写了一篇文章在win7和python3.8上安装xlwings-CSDN博客 今天安装了pycharm profession 2020.3,自带Terminal,所以试一下安装xlwings。 一、新建一个python项目 二、安装xlwings 三、输入安装命令 pip3.exe install -i https://pypi.tuna.tsinghu…

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】4.3 数据脱敏与安全(模糊处理/掩码技术)

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 PostgreSQL数据脱敏实战:从模糊处理到动态掩码的全流程解析4.3 数据脱敏与安全:模糊处理与掩码技术深度实践4.3.1 数据脱敏的核心技术体系4.3.1.1 技…

坚鹏:平安保险集团《保险行业发展趋势与AI应用方法及案例》培训

坚鹏:平安保险集团《保险行业发展趋势与AI应用方法及案例》培训圆满成功 中国平安保险(集团)股份有限公司是全球领先的综合金融生活服务集团,2024年位列《财富》世界500强第16位,连续多年蝉联全球保险品牌价值榜首。截…

NetSuite 2025.1 学习笔记

目录 领域、新功能统计表 值得注意功能摘要 最有价值功能详解 1. 领域、新功能统计表 2. 值得注意功能 3. 最有价值功能 3.1 Customer 360 目前的Customer 360在加入了几个新的控件后,变得完整了,相比较过去,真正有了实用感。 3.2 CSV Im…

Messenger.Default.Send 所有重载参数说明

Messenger.Default.Send 是 MVVM 框架中实现消息传递的核心方法,其重载参数主要用于控制消息的发送范围和接收条件。以下是其所有重载形式及参数说明: ‌1. 基本消息发送‌ Send<TMessage>(TMessage message) ‌参数说明‌: TMessage:消息类型(泛型参数),可以是任…

代码异味(Code Smell)识别与重构指南

1、引言:什么是“代码异味”? 在软件开发中,“代码异味(Code Smell)”是指那些虽然不会导致程序编译失败或运行错误,但暗示着潜在设计缺陷或可维护性问题的代码结构。它们是代码演进过程中的“信号灯”,提示我们某段代码可能需要优化。 1.1 ✅ 为什么关注代码异味? 预…

K8S有状态服务部署(MySQL、Redis、ES、RabbitMQ、Nacos、ZipKin、Sentinel)

K8S部署MySQL ①、创建配置 ②、创建存储卷 ③、创建服务 指定配置文件 指定存储卷 ④、同样的方式创建mysql-slaver服务&#xff08;配置文件和mysql-master不同&#xff09; ⑤、进行主从同步关联 进入master服务中 进入从库的终端 K8S部署Redis…

正则表达式与文本三剑客grep、sed、awk

目录 一、正则表达式 1.1、字符匹配 1.2、次数匹配 1.3、位置锚定 1.4、分组或其他 二、扩展正则表达式 三、grep 四、awk 4.1、常用命令选项 4.2、工作原理 4.3、基础用法 4.4、内置变量 4.5、模式 4.6、条件判断 4.7、awk中的循环语句 4.8、数组 4.9、脚本 …

Matlab/Simulink的一些功能用法笔记(4)

水一篇帖子 01--MATLAB工作区的保护眼睛颜色设置 默认的工作区颜色为白色 在网上可以搜索一些保护眼睛的RGB颜色参数设置 在MATLAB中按如下设置&#xff1a; ①点击预设 ②点击颜色&#xff0c;点击背景色的三角标符号 ③点击更多颜色&#xff0c;找到RGB选项 ④填写颜色参数…

Qt国际化实战--精通Qt Linguist工具链

概述 在全球化的今天,软件产品需要支持多种语言和地区,以满足来自世界各地用户的需求。Qt框架提供了一套完整的工具集来帮助开发者实现应用程序的国际化(i18n)和本地化(l10n),其中最核心的就是Qt Linguist工具链 关于国际化与本地化 国际化(i18n): 指的是设计和开发…