计算机网络系列--TCP 篇

2023-11-15

TCP 是因特网协议栈中运输层(传输层)常用的协议,该协议的全称为 Transmission Control Protocol(传输控制协议),它提供了一种可靠的数据传输,而因特网协议栈中运输层的另一种常用的协议则不提供可靠的数据传输,它在网络层提供的服务基础上不提供不必要的服务。本篇我们将从 TCP 的可靠数据传输、流量控制和拥塞控制几个方面简单介绍作为运输层的 TCP 协议提供的服务,顺便简单介绍一下 TCP 的连接管理。

0. TCP 报文段(Segment)结构

在这里插入图片描述
源端口:发送方应用程序所在的端口;
目的端口:接收方应用程序所在的端口(可能不存在);
序号:报文段中的数据部分首个字节的编号;
确认号:标识接收方期望接收的下一个数组分组的最小编号;
检验和:用于差错检验;
接收窗口:用于流量控制,接收方允许发送方发送的数据的最大长度。

1. 可靠数据传输

在了解 TCP 的可靠数据传输的具体实现之前,我们先了解一下什么样的数据传输可以称为是可靠数据传输。简单来说就是接收端收到的数据要和发送端发送的原始数据是完全相同的,这就需要保证接收端收到的数据没有差错,没有丢包,没有冗余同时还是有序的。因为 TCP 协议作为运输层的协议,它所提供的数据服务是建立在尽力而为的网络层协议——IP 协议之上的,因此可靠数据传输的保证需要在 TCP 协议中去实现。

TCP 使用这些主要技术来实现可靠数据传输:滑动窗口,超时重传,快速重传,累积确认,超时间隔加倍

发送端主要通过维护这几个变量来实现滑动窗口协议,表示最早的未被确认分组序号 send_base,下一个要发送的数据分组的序号 nextseqnum(TCP 会隐式的为应用层到达的数据的每一个字节进行编号,每个传输层报文段中数据字段的首个字节的序号被用来作为该报文段的序号,假如一个分组中数据字段的首个字节的序号为 100,即该分组被发送前的 nextseqnum 值为 100,假设该分组中数据字段的长度为 500 字节,则该数据被发送之后,nextseqnum 就是 600),以及表示窗口长度的变量 N,N 的大小由流量控制中的接收窗口以及拥塞控制中的拥塞窗口决定。
初始状态时,发送端可以一次连续发送 N 个数据分组而不必等待接收端的确认。当发送端收到确认报文段,且报文段中的 ACK 的值 y,则表示接收端已经收到了序号 y 之前的所有报文段,这种确认方式就叫做累积确认。假如 y > send_base,发送端会将 send_base 的值置为 y(这里注意,就算序号小于 y 的多个报文段都在等待确认,也会认为这些都被正确接收,这时基于累积确认得到的结果),可以发送的数据分组的序号必须落在 [send_base, send_base + N] 之间,因此可发送报文段序号区间可以被看作长度为 N,且随着确认的接收而不断向前滑动的窗口。当新的数据分组从应用层到达运输层时,发送端会判断数据分组的序号是否在发送窗口中,在的话会将分组发送,同时更新 nextseqnum 的值。
当某一批数据分组被发送时,该批分组中最早的分组被发送后会启动一个定时器(超时时间通过公式计算得到),加入在定时器超时(可能由于分组或者 ACK 丢包导致)之前未收到该分组的确认,发送端会重传该分组(超时重传)并重启定时器,并将超时时间设置为之前的两倍(这种方式被称为超时时间加倍,),当再次收到正常的确认报文段后,会将超时时间恢复为通过公式计算的值,但是实际中有可能在超时之前发送端会收到来自接收端发送的冗余 ACK 来进行快速重传(当接收端收到来自发送端的失序的分组时,会发送 3 个冗余的 ACK 来通知发送端进行快速重传),假设接收端在等待序号为 x 的报文段的到达,但是却收到了序号小于 x 的报文段失序报文段,这时接收端会假定 x 序号的报文段丢失(实际可能由于在数据链路中的排队导致了乱序,或者真的发生了丢包),并发送三个冗余的 ACK 报文段,报文段中确认号为 x,以此来通知发送端重发,快速重传机制可以有效的降低超时重传带来的长时间等待,但同时也可能引起不必要的重传(针对不必要的重传,接收端会忽略冗余的报文段)。只有当乱序报文段中的间隙被填充时,接收端才会将多个连续的报文段交给上层去处理,这样保证了报文段的有序性。

上面描述的这些机制,保证了接收端收到的数据没有丢包、没有冗余并且有序,那么没有差错是如何保证的呢?TCP 协议主要使用报文段首部字段中的检验和字段来进行差错检验,具体检验过程与 UDP 协议的基本一样,将报文段中所有 16 比特字进行求和,求和过程中遇到溢出就会回卷,最后将得到的和进行反码运算得到的就是检验和的值,接收端收到报文段之后会将报文段中所有 16 比特字进行求和,求和过程中遇到溢出就会回卷,将得到的和同检验和字段相加,得到的结果必须为 1111 1111 1111 1111,否则说明报文端出现差错,需要发送端重传。

2. 流量控制

接收方接收到的数据会先放在接收缓存中,接收缓存是在连接建立期间创建的,接收窗口的最大值不能超过缓存的大小,RcvBuffer 表示接收缓存的大小,rwnd 表示接收窗口的大小,rwnd = RcvBuffer - 缓存中未处理的数据大小。缓存中未处理的数据大小 = 接收的总字节数 - 已处理的总字节数。由此可知窗口的大小是在不断变化的,当接收方读取数据的速度快时,窗口的尺寸就大,发送方可以连续发送的数据包的数量就相对较多,否则就少。在发送端要保证已发送的数据大小 - 已确认的数据大小 <= rwnd,以此来实现流量的控制,使得发送方的数据发送速率和接收方的处理速度相匹配。

3. 拥塞控制

流量控制主要是为了达到发送方的数据发送速率和接收方的处理速度相匹配。而发送方也可能因为网络拥塞而被遏制,发送方对这种情况的处理称为拥塞控制。

在了解拥塞控制之前,我们先了解一下发送放是如何推断网络拥塞控制的,对于 TCP 协议而言,主要是通过两种方式,一种是客户端通过超时判断,另一种是根据来自接收端的冗余 ACK 来判断。接收端会在每批发送的数据发送时启动一个定时器,在定时器超时之前如果没有收到应答,则预测链路发生了拥塞(可能是数据分组或应答发生丢包或长时间排队)。接收端每次收到一个来自发送端的分组时,也会启动一个定时器,在定时器超时之前没有收到预期的数据分组,会发送 3 个冗余的 ACK 提示客户端出现网络拥塞。

TCP 的拥塞控制算法主要包括三部分:慢启动,避免拥塞和快速恢复。
TCP 的发送方除了维护接收窗口外,还会维护一个拥塞窗口 cwnd,在任意时刻发送方向接收方连续发送的数据不能超过 min(rwnd, cwnd),在拥塞控制中还有一个重要变量叫慢启动阈值(ssthresh,初始大小为 64kB),当 cwnd 到达这个阈值时,发送发就由慢启动进入避免拥塞状态。
慢启动:当一条 TCP 连接开始时,cwnd 被设置成 1 个 MSS 的大小(Maximum Segment Size,最大报文段尺寸),即一个 RTT(Round-Trip Time,往返时间,从发送端发送报文段到收到接收端的确认之间经历的时间)中只发送一个报文段,每当接收到一个应答,就将 cwnd 增加一个 MSS,因此慢启动阶段发送速率是指数增长的。
避免拥塞:当 cwnd 的值增加到慢启动阈值后,就进入避免拥塞状态,该状态下,每经过一个 RTT,cwnd 的大小只会增加一个 MSS,因此这个阶段 cwnd 是线性增长的。
快速恢复:慢启动或者是避免拥塞阶段如果根据冗余 ACK 推断出拥塞,会进入快速恢复阶段,快速恢复阶段会等待新的 ACK 的到达,如果在超时之前收到新的 ACK,则切换到避免拥塞阶段,否则切换到慢启动阶段,切换到慢启动状态时会将慢启动阈值降低至拥塞窗口的一半。
TCP 的拥塞控制 FSM 描述如下图:
在这里插入图片描述
TCP 的这种拥塞控制算法被称为加性增乘性减的拥塞控制方式,这种方式在实现了拥塞控制的同时,也给网络带宽中的 TCP 连接提供了相对的公平性,同时也提升了在空闲带宽的利用率,当大家发现网络拥塞时,会试图降低其发送速率来降低拥塞,发现网络畅通时就适当增加发送速率。

通过对拥塞控制的了解,我们不难发现,当发送端需要向一个距离较远的主机发送一个数据量较大的应用报文时,可能需要等待若干个 RTT 的时间在能收到响应。TCP 分岔可以很好的解决这个问题。简单来说,TCP 分岔就是服务提供方将请求通过 CDN 定向到距离用户比较近的一台前端服务器,这台服务器与远程的数据中心保持有一条带宽比较大的连接,客户与该服务器建立 TCP 连接,并发送数据到该服务器。前端服务器将请求转发给数据中心处理(只需要一个 RTT 的时间),然后再将响应转发给用户。我们用如下参数表示请求过程中的时间:
R T T C S − 表 示 客 户 端 到 数 据 中 心 的 数 据 往 返 时 间 ; R T T C F − 表 示 客 户 端 到 前 端 服 务 器 的 数 据 往 返 时 间 ; R T T F S − 表 示 前 端 服 务 器 到 数 据 中 心 的 数 据 往 返 时 间 ; 当 客 户 端 发 送 一 个 请 求 到 远 程 的 数 据 中 心 时 , 慢 启 动 阶 段 通 常 要 经 历 4 个 R T T C S 的 时 延 ( 不 考 虑 远 程 服 务 器 处 理 时 间 ) 才 能 得 到 请 求 的 结 果 ( 一 个 用 于 T C P 连 接 的 建 立 , 三 个 用 于 应 用 层 数 据 传 输 ) , 如 果 通 过 前 端 服 务 器 进 行 转 发 , 只 需 要 4 ∗ R T T C F + R T T F S , 而 R T T C F 相 比 R T T F S 及 R T T C S 很 小 , 因 此 可 以 忽 略 , 进 而 得 到 4 ∗ R T T C F + R T T F S ≈ R T T C S 。 因 此 , 使 用 T C P 分 岔 将 用 户 感 受 到 的 时 延 由 4 ∗ R T T C S 降 到 了 R T T C S 。 RTT_{CS}-表示客户端到数据中心的数据往返时间;\\ RTT_{CF}-表示客户端到前端服务器的数据往返时间;\\ RTT_{FS}-表示前端服务器到数据中心的数据往返时间;\\ 当客户端发送一个请求到远程的数据中心时,慢启动阶段\\ 通常要经历 4 个 RTT_{CS} 的时延(不考虑远程服务器处理时间)\\ 才能得到请求的结果(一个用于 TCP 连接的建立,三个用于应用\\ 层数据传输),如果通过前端服务器进行转发,\\ 只需要 4 * RTT_{CF} + RTT_{FS},而 RTT_{CF} 相比 RTT_{FS} \\ 及 RTT_{CS} 很小,因此可以忽略,进而得到 \\ 4 * RTT_{CF} + RTT_{FS} \approx RTT_{CS}。因此,使用 TCP 分岔将\\ 用户感受到的时延由 4*RTT_{CS} 降到了 RTT_{CS}。 RTTCSRTTCFRTTFS4RTTCSTCP4RTTCF+RTTFSRTTCFRTTFSRTTCS4RTTCF+RTTFSRTTCS使TCP4RTTCSRTTCS

4. 连接管理

4.1 连接创建

连接建立之前需要服务端在某个端口运行一个进程来监听来自客户的请求。
第一步,客户端的 TCP 首先向服务端的 TCP 发送一个特殊的报文段,报文段中不包含应用层数据。报文段的首部中 SYN 被置为 1,并且会选择一个随机的序号作为初始序号,记为 seq = client_isn。
第二步,当服务端收到来自客户端的报文段后,提取出 TCP SYN 标识,为该连接分配变量和缓存后,向客户端返回允许连接的报文段,报文段中也不包含应用层数据,报文段中的 SYN 也被置为 1,确认号 ack = client_isn + 1,同时服务端也会生成一个自己的初始序号,记为 seq = server_isn。
第三步,客户端收到来自服务端的确认后,也要为服务端分配变量和缓存,并向服务方发送应答报文段,这个报文段中可以捎带应用层数据,这时 SYN 被置为 0,因为是对服务端报文段的确认,因此确认号 ack = server_isn + 1,报文段的序号为 seq = client_isn + 1。

4.2 连接关闭

连接的关闭可以由客户端发起,也可以由服务端发起,我们假设是由客户端发起的关闭连接。
第一步,客户端发送关闭连接的特殊报文段,报文段中的首部 FIN 位被置为 1。
第二步,服务端收到报文段后,会返回一个确认报文段,服务端准备好之后才会进入下一步。
第三步,服务端发送关闭连接的特殊报文段,报文段中的首部 FIN 位被置为 1,服务端收到该报文段的确认之后会关闭连接。
第四步,客户端收到报文段后,会返回一个确认报文,发送确认之后会等待 2MSL(最大段生命周期)的时间来等待由于丢包或差错导致的服务端的重发,之后客户端关闭连接。

4.3 连接的生命周期

在这里插入图片描述

4.4 SYN 洪范攻击

前面在介绍 TCP 连接的建立时,当服务端收到客户端的 SYN 报文段后,会为连接分配变量和接收缓存,处于此种状态的连接我们称为半连接,如果某台恶意的机器虚拟大量的 IP 地址作为源地址,向某台服务器发送 SYN 报文,这时就会导致服务端由于资源被大量半连接占用二导致正常的请求无法建立,这种 DoS 攻击被称为 SYN 洪范攻击。
针对这种类型的攻击,SYN cookie 是一种很好的防御措施。
SYN cookie 的工作过程如下:
当服务端收到来自客户端的 SYN 报文段后,并不建立半开的连接(不分配变量和缓存)。同时,在确认报文段中使用的初始序号经特殊的算法生成,该算法使用源地址和端口号以及目的地址和端口号作为入参(得到的值被称为 cookie),而且服务端并不保存该值得状态。当服务端收到客户端 ACK 后,会根据源地址和端口号以及目的地址和端口号,生成序列号,将该序列号加一得到的结果与 ACK 中的确认号比较,如果相等再为连接分配变量和缓存。

参考资料:《计算机网络——自顶向下方法(原书第7版)》

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

计算机网络系列--TCP 篇 的相关文章

  • PHP 致命错误:未找到“MongoClient”类

    我有一个使用 Apache 的网站 代码如下 当我尝试访问它时 我在 error log 中收到错误 PHP Fatal Error Class MongoClient not found 以下是可能错误的设置 但我认为没有错误 php i
  • .NET Core 中的跨平台文件名处理

    如何处理文件名System IO以跨平台方式运行类以使其在 Windows 和 Linux 上运行 例如 我编写的代码在 Windows 上完美运行 但它不会在 Ubuntu Linux 上创建文件 var tempFilename Dat
  • 如何更改 Ubuntu 14.04 上的 php-cli 版本?

    我是 Linux 新手 在篡改时破坏了一些 php 设置 如果我执行一个包含以下内容的 php 脚本 phpinfo 它显示 php 版本为 5 6 但通过命令行 如果我运行php v它返回 7 0 版本 我想让两个版本匹配 我怎样才能修复
  • QFileDialog::getSaveFileName 和默认的 selectedFilter

    我有 getSaveFileName 和一些过滤器 我希望当用户打开 保存 对话框时选择其中之一 Qt 文档说明如下 可以通过将 selectedFilter 设置为所需的值来选择默认过滤器 我尝试以下变体 QString selFilte
  • 为什么我收到的数据包数据大小大于mss?

    我在两台 PC 上使用 ifconfig ethX mtu 300 修改了 MTU 并使用 netperf 测试网络 我用 WireShark 嗅探了 SYN 数据包中的 MSS 260 但我得到了一些大于 260 的数据包 为什么 嗅探器
  • Linux 中的无缓冲 I/O

    我正在写入大量的数据 这些数据数周内都不会再次读取 由于我的程序运行 机器上的可用内存量 显示为 空闲 或 顶部 很快下降 我的内存量应用程序使用量不会增加 其他进程使用的内存量也不会增加 这让我相信内存正在被文件系统缓存消耗 因为我不打算
  • 如何通过替换为空页映射来取消映射 mmap 文件

    Linux 用户空间有没有办法用空页面 映射自 dev null 或者可能是一个空页面 重复映射到从文件映射的页面的顶部 对于上下文 我想找到这个 JDK bug 的修复 https bugs openjdk java net browse
  • 从 csv 文件中删除特定列,保持输出上的相同结构[重复]

    这个问题在这里已经有答案了 我想删除第 3 列并在输出文件中保留相同的结构 输入文件 12 10 10 10 10 1 12 23 1 45 6 7 11 2 33 45 1 2 1 2 34 5 6 I tried awk F 3 fil
  • 应用程序无缘无故地被杀死。怀疑 BSS 高。如何调试呢?

    我已经在CentOs6 6中成功运行我的应用程序 最近 硬件 主板和内存 更新了 我的应用程序现在毫无理由地被杀死 root localhost PktBlaster PktBlaster Killed 文件和 ldd 输出 root lo
  • 如何在 Linux 中编写文本模式 GUI? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 当我编写脚本 程序时 我经常想弹出一个简单的文本 gui 来提示输入 我该怎么做 例如 来自 Shel
  • 如何根据 HTTP 请求使用 Python 和 Flask 执行 shell 命令并流输出?

    下列的这个帖子 https stackoverflow com questions 15092961 how to continuously display python output in a webpage 我能够tail f网页的日志
  • Linux TUN/TAP:无法从 TAP 设备读回数据

    问题是关于如何正确配置想要使用 Tun Tap 模块的 Linux 主机 My Goal 利用现有的路由软件 以下为APP1和APP2 但拦截并修改其发送和接收的所有消息 由Mediator完成 我的场景 Ubuntu 10 04 Mach
  • 为什么内核需要虚拟寻址?

    在Linux中 每个进程都有其虚拟地址空间 例如 32位系统为4GB 其中3GB为进程保留 1GB为内核保留 这种虚拟寻址机制有助于隔离每个进程的地址空间 对于流程来说这是可以理解的 因为有很多流程 但既然我们只有 1 个内核 那么为什么我
  • 大多数 Linux 系统头文件与 C++ 兼容吗?

    大多数 Linux 系统头文件 API C 兼容吗 今天我试图做这样的事情 include
  • 我可以从命令行打印 html 文件(带有图像、css)吗?

    我想从脚本中打印带有图像的样式化 html 页面 谁能建议一个开源解决方案 我使用的是 Linux Ubuntu 8 04 但也对其他操作系统的解决方案感兴趣 你可以给html2ps http user it uu se jan html2
  • 域套接字“sendto”遇到“errno 111,连接被拒绝”

    我正在使用域套接字从另一个进程获取值 就像 A 从 B 获取值一样 它可以运行几个月 但最近 A 向 B 发送消息时偶尔会失败 出现 errno 111 连接被拒绝 我检查了B域套接字绑定文件 它是存在的 我也在另一台机器上做了一些测试 效
  • Android 时钟滴答数 [赫兹]

    关于 proc pid stat 中应用程序的总 CPU 使用率 https stackoverflow com questions 16726779 total cpu usage of an application from proc
  • 添加要在给定命令中运行的 .env 变量

    我有一个 env 文件 其中包含如下变量 HELLO world SOMETHING nothing 前几天我发现了这个很棒的脚本 它将这些变量放入当前会话中 所以当我运行这样的东西时 cat env grep v xargs node t
  • arm64和armhf有什么区别?

    Raspberry Pi Type 3 具有 64 位 CPU 但其架构不是arm64 but armhf 有什么区别arm64 and armhf armhf代表 arm hard float 是给定的名称Debian 端口 https
  • 如何在 Linux shell 中将十六进制转换为 ASCII 字符?

    假设我有一个字符串5a 这是 ASCII 字母的十六进制表示Z 我需要找到一个 Linux shell 命令 它将接受一个十六进制字符串并输出该十六进制字符串代表的 ASCII 字符 所以如果我这样做 echo 5a command im

随机推荐

  • WPF Virtualization

    WPF虚拟化技术分为UI 虚拟化和数据虚拟化 第一种方法被称为 UI 虚拟化 支持虚拟化用户界面的控件是足够聪明来创建只显示的是实际在屏幕上可见的数据项目所需的 UI 元素 例如 假设我们有一个滚动的列表框是绑定到 1 000 000 项目
  • 微信小程序上线流程

    1 打开微信公众平台扫码登录 2 点击成员管理 我是接的别人开发的版本 首先要管理员给我权限 让我成为小程序的开发者 按下图就可以添加成员了 你要是开发者直接要他给你全勾上 最后点击确认添加就行 3 点击微信开发者工具里的上传按钮或者hbu
  • C++项目实战-实际应用

    目录 典型IO的两个阶段 网络IO Linux上的五种IO模型 1 阻塞 blocking 2 非阻塞 3 IO复用 4 信号驱动 5 异步 Web Server HTTP协议 应用层的协议 简介 概述 工作原理 HTTP 请求报文格式 H
  • 秒传的原理

    在本文中 我们将介绍网盘秒传的基本原理和实现方法 以及秒传的优缺点和应用场景 网盘秒传的基本原理 网盘秒传的基本原理是利用哈希算法 如MD5或SHA 1 对文件进行特征值提取 然后与服务器上已有的文件特征值进行比对 如果发现相同的特征值 就
  • C语言实现贪吃蛇小游戏

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 前言 一 贪吃蛇实现的结构和方式 2 对窗口进行设置 3 对蛇进行初始化 一 源代码 利用学会的知识做点小游戏 前言 控制台的欢乐就是这么简单 提示 以下是本篇文章
  • Vue3 Table 性能优化,减少 85% 渲染耗时

    大厂技术 高级前端 Node进阶 点击上方 程序员成长指北 关注公众号 回复1 加入高级Node交流群 原文链接 https juejin cn post 7194516447932973112 作者 dev zuo 前段时间公司有一个比较
  • 一个新的开始(非技术贴)

    谈谈一个新的开始 说实话 从来没想过自己会有一刻坐在这里写博客 因为一直以来都觉得自己会像父母所期望的那样考上公务员 结婚生子 过平凡的一生 从大一以来 自己都一直坚信这样对我来说是最最好的 但今年大三 用了短短一个月我就改变了想法 可以说
  • 38.驱动调试——printk

    printk的用法 mz linux ChinaUnix博客 printk函数的用法 wwwlyj123321的博客 CSDN博客 printk 34 Linux printk分析 使用 FILE FUNCTION LINE 调试 诺谦 博
  • freemarker---数字小数点格式化问题

    保留小数的问题问题 http blog sina com cn s blog 7db125620101codn html http blog 163 com sir 876 blog static 117052232012102854524
  • SIM800C模块AT指令编程指南

    SIM800C是一款四频GSM GPRS模块 为城堡孔封装 其性能稳定 外观小巧 能满足客户的多种需求 SIM80C工作频率为GSM GPRS850 900 180 190OMHz 可以低功耗实现语音 SMS和数据信息的传输 SIM800C
  • Java 线程池的submit的使用与分析.md

    在Java5以后 通过Executor来启动线程比用Thread的start 更好 在新特征中 可以很容易控制线程的启动 执行和关闭过程 还能使用线程池的特性 上一篇我们介绍了线程池的基本用法和特性 我们用的最多的是ExecutorServ
  • Springboot的创建步骤

    1 创建Springboot模块 ider gt file gt new gt project gt Spring lnitializr gt 不选择default 默认 gt 选择custom定制网址 http start springb
  • Matlab实现无标度网络生成及其分析

    文章目录 引言 社会网络分类 Barab si Albert无标度网络生成算法 MATLAB代码实现 无向的无标度网络生成代码BAgraph undir 有向的无标度网络生成代码BAgraph dir 无标度网络的节点度统计分析 无向的无标
  • 机器学习常识 3: 分类、回归、聚类

    摘要 本贴描述分类 回归 聚类问题的基本概念 1 基本概念 机器学习常识 2 数据类型从输入数据的角度来进行讨论 这里从输出数据 或者目标的角度来讨论 分类是指将一个样本预测为给定类别之一 也称为该样本打标签 例 1 如果我去向那个女生表白
  • API接口原理实现及应用

    API Application Programming Interface 接口是现代软件开发中不可或缺的一部分 它们提供了一种机制 使得不同的应用程序和服务可以相互通信 共享数据和功能 在这篇文章中 我们将探讨API接口的原理 实现及应用
  • stable diffusion ——img2img Api参数数据格式参考,插件包含ControlNet和roop换脸

    init images resize mode 0 denoising strength 1 0 image cfg scale 1 5 mask mask blur 4 inpainting fill 2 inpaint full res
  • 【SQL】19 SQL函数

    SQL 拥有很多可用于计数和计算的内建函数 SQL Aggregate 函数 SQL Aggregate 函数计算从列中取得的值 返回一个单一的值 有用的 Aggregate 函数 AVG 返回平均值 COUNT 返回行数 FIRST 返回
  • DataX下载安装使用

    文章目录 01 Clickhouse到HBase Phoenix 数据导入 DataX 介绍 下载 执行同步的组件 配置数据同步 查看官方读写配置样例 创建Hbase和Phoenix表 创建ClickHouse表 写入ClickHouse测
  • 测试经验分享:做一个靠谱的软件测试人员

    何为靠谱 在带新人过程中 交待测试新人测试任务时 都不会忘记交待这样的一句话 这个开发如何如何 比如这个开发代码质量很好 少bug 修改bug也快 比如这个开发编码有点慢 跟任务时多催一下 比如这个开发编码质量不怎么样 bug多 你测试的时
  • 计算机网络系列--TCP 篇

    TCP 是因特网协议栈中运输层 传输层 常用的协议 该协议的全称为 Transmission Control Protocol 传输控制协议 它提供了一种可靠的数据传输 而因特网协议栈中运输层的另一种常用的协议则不提供可靠的数据传输 它在网