[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
- 提問的藝術