💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] # tcp(传输层) ****** TCP (Transmission Control Protocol 传输控制协议) 是一种面向连接的、可靠的、基于字节流的传输层通信协议,由 IETF 的 RFC 793 定义。在简化的计算机网络 OSI 模型中,它完成第四层传输层所指定的功能,用户数据报协议(UDP)是同一层内 另一个重要的传输协议。在因特网协议族(Internet protocol suite)中,TCP 层是位于 IP 层之上,应用层之下的中间层。不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是 IP 层不提供这样的流机制,而是提供不可靠的包交换。 应用层向 TCP 层发送用于网间传输的、用8位字节表示的数据流,然后 TCP 把数据流分区成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传输单元(MTU)的限制)。之后 TCP 把结果包传给 IP 层,由它来通过网络把包传送给接收端实体的 TCP 层。TCP 为了保证不发生丢包,就给每一个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。TCP 用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。 ## 三次握手 TCP 是因特网中的传输协议,使用三次握手协议建立连接。当主动方发出 SYN 连接请求后,等待对方回答 SYN+ACK ,并最终对对方的 SYN 执行 ACK 确认。这种建立连接的方法可以防止产生错误的连接,TCP 使用的流量控制协议是可变大小的滑动窗口协议。TCP 三次握手的过程如下: * 客户端发送 SYN (SEQ=x)报文给服务器端,进入 SYN_SEND 状态。 * 服务器端收到 SYN 报文,回应一个 SYN (SEQ=y) ACK(ACK=x+1)报文,进入 SYN_RECV 状态。 * 客户端收到服务器端的 SYN 报文,回应一个 ACK(ACK=y+1)报文,进入 Established 状态。 <br /> ## 连接成功 连接成功之后双方即可互相传输字节流,并随时可关闭连接,传输的数据有以下特性: * 传输的数据被 tcp 分割成了最适合发送的数据块 传递给 ip 协议,这个发送数据称为 报文段 或 段。 * tcp 作为可靠性连接,每次发送数据段,会启动一个定时器,每次接收数据段,会发送一次确认,如果定时器没有及时收到确认,则会重发数据。 * TCP 将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段(希望发端超时并重发)。 * 两个应用程序通过 TCP 连接交换 8bit 字节构成的字节流。TCP 不在字节流中插入记录标识符。我们将这称为字节流服务(bytestream service)。如果一方的应用程序先传 10 字节,又传 20 字节,再传 50 字节,连接的另一方将无法了解发方每次发送了多少字节。只要自己的接收缓存没有塞满,TCP 接收方将有多少就收多少。一端将字节流放到 TCP 连接上,同样的字节流将出现在 TCP 连接的另一端。 <br /> ## 四次挥手 建立一个连接需要三次握手,而终止一个连接要经过四次挥手,这是由于 TCP 的半关闭(half-close)造成的。具体过程如下所示。 * 某个应用进程首先调用 close,称该端执行“主动关闭”(active close)。该端的 TCP 于是发送一个 FIN 分节,表示数据发送完毕。 * 接收到这个 FIN 的对端执行“被动关闭”(passive close),这个 FIN 由 TCP 确认。 * 注意:FIN 的接收也作为一个文件结束符(end-of-file)传递给接收端应用进程,放在已排队等候应用进程接收的任何其他数据之后,因为,FIN 的接收意味着接收端应用进程在相应连接上再无额外数据可接收。 * 一段时间后,接收到这个文件结束符的应用进程将调用close关闭它的套接字。这导致它的 TCP 也发送一个 FIN。 * 接收这个最终 FIN 的原发送端 TCP (即执行主动关闭的那一端)确认这个FIN。既然每个方向都需要一个 FIN 和 一个 ACK,因此通常需要 4个字节。 > “通常”是指,某些情况下,步骤1的 FIN 随数据一起发送,另外,步骤2和步骤3发送的分节都出自执行被动关闭的那一端,有可能被合并成一个分节。在步骤2与步骤3之间,从执行被动关闭一端到执行主动关闭一端流动数据是可能的,这称为“半关闭”(half-close)。当一个Unix进程无论自愿地(调用 exit 或从 main 函数返回)还是非自愿地(收到一个终止本进程的信号)终止时,所有打开的描述符都被关闭,这也导致仍然打开的任何 TCP 连接上也发出一个 FIN。无论是客户端还是服务器端,任何一端都可以执行主动关闭。通常情况是,客户端执行主动关闭,但是某些协议,例如,HTTP/1.0 却由服务器端执行主动关闭。 <br /> ## php中的tcp php 可通过 socket 函数,swoole 扩展,stream 流函数进行创建 tcp 协议的 socket,绑定网卡端口,进行 tcp 服务端/客户端操作。在 php 中,我们并不需要了解 tcp 的握手/挥手,我们只需要知道 ip:port 能连接/创建 一个 tcp 服务端/客户端就行了,使用 php 的 socket,我们可以直接发送字符串,接收的也是字符串,其他一切都是语言、操作系统所需要做的事,我们只需要处理好字符串的完整性,例如我们使用 php 做 tcp 服务端。 * 客户端连接成功后,发送了一个“easyswoole是一个非常好的swoole框架”的字符串 * 而服务端每次只接收 9个字节,那第一次获取只会接收到“easyswoole”的残缺字符串,需要继续获取数据 <br /> ## 其他 > 可自行搜索详细理解