[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 />
## 其他
> 可自行搜索详细理解
- 引言
- Introduction
- 运行模式
- php-fpm
- php-cli
- 基础介绍
- 网络协议
- ip
- tcp
- tcp
- http
- webSocket
- udp
- port端口
- 会话管理
- cookie
- session
- api/token
- linux基础
- lnmp安装
- 命令
- 进程管理
- 扩展安装
- 端口监控
- 防火墙说明
- php7.0
- 部分新特性
- php回调/闭包
- 回调事件
- 闭包/匿名函数
- php多进程
- 多进程开启
- 进程通信
- 进程信号
- 僵尸进程
- 孤儿进程
- 守护进程
- 同步/异步
- 阻塞/非阻塞
- 协程
- Swoole
- 初始Swoole
- 运行机制
- 生命周期
- composer使用
- EasySwoole
- 设计理念
- 组件说明
- 运行过程
- demo
- 提问的艺术