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三次握手
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 状态
连接成功

连接成功之后双方即可互相传输 字节流 并随时可 关闭连接 传输的数据有以下特性
传输的数据 被tcp 分割成了 最适合 发送的 数据块 传递给 ip协议 这个发送数据称为 报文段 或 段

tcp 作为可靠性连接 每次发送数据段 会启动一个 定时器 每次接收数据段 会发送一次确认 如果 定时器 没有及时收到确认 则会重发数据
TCP 将保持它首部和数据的检验和 这是一个 端到端的检验和 目的是检测数据在传输过程中的任何变化
如果收到段的检验和有差错 TCP将丢弃这个报文段和不确认收到此报文段(希望发端超时并重发)

两个 应用程序 通过TCP连接 交换8bit字节构成的 字节流
TCP 不在字节流中插入记录标识符
将这称为 字节流服务(bytestreamservice)
如果一方的 应用程序 先传10字节 又传20字节 再传50字节 连接的另一方将 无法了解发方 每次发送了多少字节
只要自己的接收缓存没有塞满 TCP 接收方将有多少 就收多少 一端 将字节流放到TCP连接上 同样的字节流将出现在TCP连接的另一端

四次挥手
建立一个连接需要 三次握手 而 终止一个连接 要经过 四次挥手 这是由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却由服务器执行主动关闭

php 的TCP
php 可通过 socket函数  swoole扩展 stream流函数 创建tcp协议的 socket 绑定网卡端口 进行tcp服务端/客户端操作
php 并不需要了解 tcp 握手/挥手  只需要知道 ip:port 能连接/创建  tcp服务端/客户端就行了
使用php socket  直接发送 字符串 接收的也是字符串 其他一切都是语言 操作系统所需要做的事
只需要处理好 字符串 的完整性

例如 使用php做tcp服务端
客户端 连接成功后 发送了一个 hello world 是一个非常好的swoole框架  的字符串
服务端 每次只接收 9 个字节 那第一次获取只会接收到 hello wor 的残缺字符串 需要继续获取数据