報文段
報文段是指TCP/IP協議網絡傳輸過程中,起著路由導航作用
用以查詢各個網絡路由網段,ip地址,交換協議等ip數據包
報文段充當整個tcp/ip協議數據包的導航路由功能
報文在傳輸過程中會不斷的封裝成組、包、幀來傳輸的
傳輸協議
協議顧名思義,一種規定,約束
約定大于配置,在網絡傳輸中依然適用;網絡的傳輸流程是健壯的穩定的,得益于基礎的協議構成
簡單來說:A->B的傳輸數據,B能識別,繁殖B->A的傳輸數據A也能識別,這就是協議
IP地址
"1.1.1.1": 為直接廣播地址,會向全網廣播UDP消息,但是一般會被路由器防火墻攔截
"255.255.255.255": 為受限廣播地址,會在局域網絡內發送UDP消息
UDP
用戶數據報協議,基于報文的協議,而不是基于連接的協議
應用場景:DNS TFTP SNMP
UDP包的最大長度
16位-> 2字節 存儲長度信息;2^16-1=65535;自身協議占用:32+32位=64位=8字節
所以最大數據長度:65535-8=65507 byte字節
UDP單播,廣播,多播
單播:點對點
廣播:給所有設備發送數據(例如:受限廣播地址,255.255.255.255)
- C網廣播地址一般為:xxx.xxx.xxx.255(192.168.1.255)
多播(組播):給一組發送數據
- D類IP地址為多播預留
廣播地址運算
IP;192.168.124.7
子網掩碼: 255.255.255.0
網絡地址: 192.168.124.0
廣播地址: 192.168.124.255
但是運算結果不是絕對的,如下:
如果子網掩碼是:255.255.255.192-> 11111111.11111111.11111111.11000000
則可劃分網段就是最后的一個字節的1數據,即2*2=4個
四個網段為:0-63 64-127 128-191 n 192-255
IP:192.168.124.7歸屬于第一個網段,所以廣播地址就是該網段的
最后一個即192.168.124.63 ,網絡地址(是該網段第一個地址)
仍是192.168.124.0
廣播通信問題
如上圖,主機一位于第一個網段,主機二位于第二個網段,所以二者無法通信
協議
什么是協議
從應?的?度出發,協議可理解為“規則”,是數據傳輸和數據的解釋的規則。
假設,A、B雙?欲傳輸?件。規定:
- 第?次,傳輸?件名,接收?接收到?件名,應答OK給傳輸?;
- 第?次,發送?件的尺?,接收?接收到該數據再次應答?個OK;
- 第三次,傳輸?件內容。同樣,接收?接收數據完成后應答OK表示?件內容接收成功
由此,?論A、B之間傳遞何種?件,都是通過三次數據傳輸來完成。A、B之間形成了?個最簡單的數據傳輸規則。雙?都按此規則發送、接收數據。A、B之間達成的這個相互遵守的規則即為協議。
這種僅在A、B之間被遵守的協議稱之為原始協議。當此協議被更多的?采?,不斷的增加、改進、維護、完善。最終形成?個穩定的、完整的?件傳輸協議,被?泛應?于各種?件傳輸過程中。該協議就成為?個標準協議。最早的ftp協議就是由此衍??來。
TCP協議注重數據的傳輸。http協議著重于數據的解釋。
典型協議
傳輸層 常?協議有TCP/UDP協議。
應?層 常?的協議有HTTP協議,FTP協議。
?絡層 常?協議有IP協議、ICMP協議、IGMP協議。
?絡接?層 常?協議有ARP協議、RARP協議。
TCP傳輸控制協議(Transmission Control Protocol)是?種?向連接的、可靠的、基于字節流的
傳輸層通信協議。
UDP?戶數據報協議(User Datagram Protocol)是OSI參考模型中?種?連接的傳輸層協議,
提供?向事務的簡單不可靠信息傳送服務。
HTTP超?本傳輸協議(Hyper Text Transfer Protocol)是互聯?上應?最為?泛的?種?絡協
議。
FTP?件傳輸協議(File Transfer Protocol)
IP協議是因特?互聯協議(Internet Protocol)
ICMP協議是Internet控制報?協議(Internet Control Message Protocol)它是TCP/IP協議族的?個?協議,?于在IP主機、路由器之間傳遞控制消息。
IGMP協議是 Internet 組管理協議(Internet Group Management Protocol),是因特?協議家
族中的?個組播協議。該協議運?在主機和組播路由器之間。
ARP協議是正向地址解析協議(Address Resolution Protocol),通過已知的IP,尋找對應主機
的MAC地址。
RARP是反向地址轉換協議,通過MAC地址確定IP地址。
分層模型
- 物理層:
主要定義物理設備標準,如?線的接?類型、光纖的接?類型、各種傳輸介質的傳輸速率等。它的主要作?是傳輸?特流(就是由1、0轉化為電流強弱來進?傳輸,到達?的地后再轉化為1、0,也就是我們常說的數模轉換與模數轉換)。這?層的數據叫做?特。
- 數據鏈路層:
定義了如何讓格式化數據以幀為單位進?傳輸,以及如何讓控制對物理介質的訪問。這?層通常還提供錯誤檢測和糾正,以確保數據的可靠傳輸。如:串?通信中使?到的115200、 8、N、1
- ?絡層:
在位于不同地理位置的?絡中的兩個主機系統之間提供連接和路徑選擇。Internet的發展使得從世界各站點訪問信息的?戶數??增加,??絡層正是管理這種連接的層。
- 傳輸層:
定義了?些傳輸數據的協議和端?號(WWW端?80等),如:TCP(傳輸控制協議,傳輸效率低,可靠性強,?于傳輸可靠性要求?,數據量?的數據),UDP(?戶數據報協議,與TCP特性恰恰相反,?于傳輸可靠性要求不?,數據量?的數據,如QQ聊天數據就是通過這種?式傳輸的)。主要是將從下層接收的數據進?分段和傳輸,到達?的地址后再進?重組。常常把這?層數據叫做段。
- 會話層:
通過傳輸層(端?號:傳輸端?與接收端?)建?數據傳輸的通路。主要在你的系統之間發起會話或者接受會話請求(設備之間需要互相認識可以是IP也可以是MAC或者是主機名)。
- 表示層:
可確保?個系統的應?層所發送的信息可以被另?個系統的應?層讀取。例如,PC程序與另?臺計算機進?通信,其中?臺計算機使?擴展???進制交換碼(EBCDIC),?另?臺則使?美國信息交換標準碼(ASCII)來表示相同的字符。如有必要,表示層會通過使??種通格式來實現多種數據格式之間的轉換。
- 應?層
是最靠近?戶的OSI層。這?層為?戶的應?程序(例如電?郵件、?件傳輸和終端仿真)提供?絡服務。
下圖模擬一個數據發送到接收一層層封包和解包的過程
通信過程
TCP/IP通信過程
上圖對應兩臺計算機在同??段中的情況,如果兩臺計算機在不同的?段中,那么數據從?臺計算機到另?臺計算機傳輸過程中要經過?個或多個路由器,如下圖所示:
跨路由通信
鏈路層有以太?、令牌環?等標準,鏈路層負責?卡設備的驅動、幀同步(即從?線上檢測到什么信號算作新幀的開始)、沖突檢測(如果檢測到沖突就?動重發)、數據差錯校驗等?作。交換機是?作在鏈路層的?絡設備,可以在不同的鏈路層?絡之間轉發數據幀(?如?兆以太?和百兆以太?之間、以太?和令牌環?之間),由于不同鏈路層的幀格式不同,交換機要將進來的數據包拆掉鏈路層?部重新封裝之后再轉發。
?絡層的IP協議是構成Internet的基礎。Internet上的主機通過IP地址來標識,Inter-net上有?量路由器負責根據IP地址選擇合適的路徑轉發數據包,數據包從Internet上的源主機到?的主機往往要經過?多個路由器。路由器是?作在第三層的?絡設備,同時兼有交換機的功能,可以在不同的鏈路層接?之間轉發數據包,因此路由器需要將進來的數據包拆掉?絡層和鏈路層兩層?部并重新封裝。IP協議不保證傳輸的可靠性,數據包在傳輸過程中可能丟失,可靠性可以在上層協議或應?程序中提供?持。
?絡層負責點到點(ptop,point-to-point)的傳輸(這?的“點”指主機或路由器),?傳輸層負責端到端(etoe,end-to-end)的傳輸(這?的“端”指源主機和?的主機)。傳輸層可選擇TCP或UDP協議。
TCP是?種?向連接的、可靠的協議,有點像打電話,雙?拿起電話互通身份之后就建?了連接,然后說話就?了,這邊說的話那邊保證聽得到,并且是按說話的順序聽到的,說完話掛機斷開連接。也就是說TCP傳輸的雙?需要?先建?連接,之后由TCP協議保證數據收發的可靠性,丟失的數據包?動重發,上層應?程序收到的總是可靠的數據流,通訊之后關閉連接。UDP是?連接的傳輸協議,不保證可靠性,有點像寄信,信寫好放到郵筒?,既不能保證信件在郵遞過程中不會丟失,也不能保證信件寄送順序。使?UDP協議的應?程序需要??完成丟包重發、消息排序等?作。
?的主機收到數據包后,如何經過各層協議棧最后到達應?程序呢?其過程如下圖所示:
以太?驅動程序?先根據以太??部中的“上層協議”字段確定該數據幀的有效載荷(payload,指除去協議?部之外實際傳輸的數據)是IP、ARP還是RARP協議的數據報,然后交給相應的協議處理。假如是IP數據報,IP協議再根據IP?部中的“上層協議”字段確定該數據報的有效載荷是TCP、
UDP、ICMP還是IGMP,然后交給相應的協議處理。假如是TCP段或UDP段,TCP或UDP協議再根據TCP?部或UDP?部的“端?號”字段確定應該將應?層數據交給哪個?戶進程。IP地址是標識?絡中不同主機的地址,?端?號就是同?臺主機上標識不同進程的地址,IP地址和端?號合起來標識?絡中唯?的進程。
雖然IP、ARP和RARP數據報都需要以太?驅動程序來封裝成幀,但是從功能上劃分,ARP和RARP屬于鏈路層,IP屬于?絡層。雖然ICMP、IGMP、TCP、UDP的數據都需要IP協議來封裝成數據報,但是從功能上劃分,ICMP、IGMP與IP同屬于?絡層,TCP和UDP屬于傳輸層。
協議格式
數據包封裝
傳輸層及其以下的機制由內核提供,應?層由?戶進程提供(后?將介紹如何使?socket API編寫應?程序),應?程序對通訊數據的含義進?解釋,?傳輸層及其以下處理通訊的細節,將數據從?臺計算機通過?定的路徑發送到另?臺計算機。應?層數據通過協議棧發到?絡上時,每層協議都要加上?個數據?部(header),稱為封裝(Encapsulation),如下圖所示:
TCP/IP數據包封裝
不同的協議層對數據包有不同的稱謂,在傳輸層叫做段(segment),在?絡層叫做數據報(datagram),在鏈路層叫做幀(frame)。數據封裝成幀后發到傳輸介質上,到達?的主機后每層協議再剝掉相應的?部,最后將應?層數據交給應?程序處理。
以太網幀格式
以太?幀格式
其中的源地址和?的地址是指?卡的硬件地址(也叫MAC地址),?度是48位,是在?卡出?時固化的。可在shell中使?ifconfig命令查看,“HWaddr 00:15:F2:14:9E:3F”部分就是硬件地址。協議字段有三種值,分別對應IP、ARP、RARP。幀尾是CRC校驗碼。以太?幀中的數據?度規定最?46字節,最?1500字節,ARP和RARP數據包的?度不夠46字節,要在后?補填充位。最?值1500稱為以太?的最?傳輸單元(MTU),不同的?絡類型有不同的MTU,如果?個數據包從以太?路由到撥號鏈路上,數據包?度?于撥號鏈路的MTU,則需要對數據包進?分?(fragmentation)。ifconfig命令輸出中也有“MTU:1500”。注意,MTU這個概念指數據幀中有效載荷的最??度,不包括幀頭長度。
ARP數據報格式
在?絡通訊時,源主機的應?程序知道?的主機的IP地址和端?號,卻不知道?的主機的硬件地址,?數據包?先是被?卡接收到再去處理上層協議的,如果接收到的數據包的硬件地址與本機不符,則直接丟棄。因此在通訊前必須獲得?的主機的硬件地址。ARP協議就起到這個作?。源主機發出ARP請求,詢問“IP地址是192.168.0.1的主機的硬件地址是多少”,并將這個請求?播到本地?段(以太?幀?部的硬件地址填FF:FF:FF:FF:FF:FF表示?播),?的主機接收到?播的ARP請求,發現其中的IP地址與本機相符,則發送?個ARP應答數據包給源主機,將??的硬件地址填寫在應答包中。
每臺主機都維護?個ARP緩存表,可以?arp-a命令查看。緩存表中的表項有過期時間(?般為20分鐘),如果20分鐘內沒有再次使?某個表項,則該表項失效,下次還要發ARP請求來獲得?的主機的硬件地址。想?想,為什么表項要有過期時間?不是?直有效?
ARP數據報格式
源MAC地址、?的MAC地址在以太??部和ARP請求中各出現?次,對于鏈路層為以太?的情況是多余的,但如果鏈路層是其它類型的?絡則有可能是必要的。硬件類型指鏈路層?絡類型,1為以太?,協議類型指要轉換的地址類型,0x0800為IP地址,后?兩個地址?度對于以太?地址和IP地址分別為6和4(字節),op字段為1表示ARP請求,op字段為2表示ARP應答。
看?個具體的例?。
請求幀如下(為了清晰在每?的前?加了字節計數,每?16個字節):以太??部(14字節)
0000: ff ff ff ff ff ff 00 05 5d 61 58 a8 08 06
ARP幀(28字節)
0000: 00 01
0010: 08 00 06 04 00 01 00 05 5d 61 58 a8 c0 a8 00 37
0020: 00 00 00 00 00 00 c0 a8 00 02
填充位(18字節)
0020: 00 77 31 d2 50 10
0030: fd 78 41 d3 00 00 00 00 00 00 00 00
以太??部:?的主機采??播地址,源主機的MAC地址是00:05:5d:61:58:a8,上層協議類型0x0806表示ARP。
ARP幀:硬件類型0x0001表示以太?,協議類型0x0800表示IP協議,硬件地址(MAC地址)?度為6,協議地址(IP地址)?度為4,op為0x0001表示請求?的主機的MAC地址,源主機MAC地址為00:05:5d:61:58:a8,源主機IP地址為c0 a8 00 37(192.168.0.55),?的主機MAC地址全0待填寫,?的主機IP地址為c0 a8 00 02(192.168.0.2)。
由于以太?規定最?數據?度為46字節,ARP幀?度只有28字節,因此有18字節填充位,填充位的內容沒有定義,與具體實現相關。
應答幀如下:
以太??部
0000: 00 05 5d 61 58 a8 00 05 5d a1 b8 40 08 06
ARP幀
0000: 00 01
0010: 08 00 06 04 00 02 00 05 5d a1 b8 40 c0 a8 00 02
0020: 00 05 5d 61 58 a8 c0 a8 00 37
填充位
0020: 00 77 31 d2 50 10
0030: fd 78 41 d3 00 00 00 00 00 00 00 00
以太??部:?的主機的MAC地址是00:05:5d:61:58:a8,源主機的MAC地址是
00:05:5d:a1:b8:40,上層協議類型0x0806表示ARP。
ARP幀:硬件類型0x0001表示以太?,協議類型0x0800表示IP協議,硬件地址(MAC地址)?度為6,協議地址(IP地址)?度為4,op為0x0002表示應答,源主機MAC地址為00:05:5d:a1:b8:40,源主機IP地址為c0 a8 00 02(192.168.0.2),?的主機MAC地址為00:05:5d:61:58:a8,?的主機IP地址為c0 a8 00 37(192.168.0.55)
IP段格式
IP數據報格式
IP數據報的?部?度和數據?度都是可變?的,但總是4字節的整數倍。
對于IPv4,4位版本字段是4。4位?部?度的數值是以4字節為單位的,最?值為5,也就是說?部?度最?是4x5=20字節,也就是不帶任何選項的IP?部,4位能表示的最?值是15,也就是說?部?度最?是60字節。
8位TOS字段有3個位?來指定IP數據報的優先級(?前已經廢棄不?),還有4個位表示可選的服務類型(最?延遲、最?吐量、最?可靠性、最?成本),還有?個位總是0。總?度是整個數據報(包括IP?部和IP層payload)的字節數。每傳?個IP數據報,16位的標識加1,可?于分?和重新組裝數據報。3位標志和13位?偏移?于分?。
TTL(Time to live)是這樣?的:源主機為數據包設定?個?存時間,?如64,每過?個路由器就把該值減1,如果減到0就表示路由已經太?了仍然找不到?的主機的?絡,就丟棄該包,因此這個?存時間的單位不是秒,?是跳(hop)。
協議字段指示上層協議是TCP、UDP、ICMP還是IGMP。然后是校驗和,只校驗IP?部,數據的校驗由更?層協議負責。IPv4的IP地址?度為32位。
UDP數據報格式
UDP數據段
下?分析?幀基于UDP的TFTP協議幀。
以太??部
0000: 00 05 5d 67 d0 b1 00 05 5d 61 58 a8 08 00
IP?部
0000: 45 00
0010: 00 53 93 25 00 00 80 11 25 ec c0 a8 00 37 c0 a8
0020: 00 01
UDP?部
0020: 05 d4 00 45 00 3f ac 40
TFTP協議
0020: 00 01 'c'':''\''q'
0030: 'w''e''r''q''.''q''w''e'00 'n''e''t''a''s''c''i'
0040: 'i'00 'b''l''k''s''i''z''e'00 '5''1''2'00 't''i'
0050: 'm''e''o''u''t'00 '1''0'00 't''s''i''z''e'00 '0'
以太??部
:源MAC地址是00:05:5d:61:58:a8,?的MAC地址是00:05:5d:67:d0:b1,上層協議類型0x0800表示IP。
IP?部
:每?個字節0x45包含4位版本號和4位?部?度,版本號為4,即IPv4,?部?度為5,說明IP?部不帶有選項字段。服務類型為0,沒有使?服務。16位總?度字段(包括IP?部和IP層payload的?度)為0x0053,即83字節,加上以太??部14字節可知整個幀?度是97字節。IP報標識是0x9325,標志字段和?偏移字段設置為0x0000,就是DF=0允許分?,MF=0此數據報沒有更多分?,沒有分?偏移。TTL是0x80,也就是128。上層協議0x11表示UDP協議。IP?部校驗和為0x25ec,源主機IP是c0 a8 00 37(192.168.0.55),?的主機IP是c0 a8 00
01(192.168.0.1)。
UDP?部
:源端?號0x05d4(1492)是客戶端的端?號,?的端?號0x0045(69)是TFTP服務的well-known端?號。UDP報?度為0x003f,即63字節,包括UDP?部和UDP層pay-load的?度。UDP?部和UDP層payload的校驗和為0xac40。
TFTP
是基于?本的協議,各字段之間?字節0分隔,開頭的00 01表示請求讀取?個?件,接下來的各字段是:
c:\qwerq.qwe
netascii
blksize 512
timeout 10
tsize 0
?般的?絡通信都是像TFTP協議這樣,通信的雙?分別是客戶端和服務器,客戶端主動發起請求(上?的例?就是客戶端發起的請求幀),?服務器被動地等待、接收和應答請求。客戶端的IP地址和端?號唯?標識了該主機上的TFTP客戶端進程,服務器的IP地址和端?號唯?標識了該主機上的TFTP服務進程,由于客戶端是主動發起請求的??,它必須知道服務器的IP地址和TFTP服務進程的端?號,所以,?些常?的?絡協議有默認的服務器端?,例如HTTP服務默認TCP協議的80端?,FTP服務默認TCP協議的21端?,TFTP服務默認UDP協議的69端?(如上例所示)。
在使?客戶端程序時,必須指定服務器的主機名或IP地址,如果不明確指定端?號則采?默認端?,請讀者查閱ftp、tftp等程序的manpage了解如何指定端?號。/etc/services中列出了所有well-known的服務端?和對應的傳輸層協議,這是由IANA(Internet Assigned NumbersAuthority)規定的,其中有些服務既可以?TCP也可以?UDP,為了清晰,IANA規定這樣的服務采?相同的TCP或UDP默認端?號,?另外?些TCP和UDP的相同端?號卻對應不同的服務。很多服務有well-known的端?號,然?客戶端程序的端?號卻不必是well-known的,往往是每次運?客戶端程序時由系統?動分配?個空閑的端?號,?完就釋放掉,稱為ephemeral的端?號,想想這是為什么?
前?提過,UDP協議不?向連接,也不保證傳輸的可靠性,例如:
發送端的UDP協議層只管把應?層傳來的數據封裝成段交給IP協議層就算完成任務了,如果因為?絡故障該段?法發到對?,UDP協議層也不會給應?層返回任何錯誤信息。
接收端的UDP協議層只管把收到的數據根據端?號交給相應的應?程序就算完成任務了,如果發送端發來多個數據包并且在?絡上經過不同的路由,到達接收端時順序已經錯亂了,UDP協議層也不保證按發送時的順序交給應?層。
通常接收端的UDP協議層將收到的數據放在?個固定??的緩沖區中等待應?程序來提取和處理,如果應?程序提取和處理的速度很慢,?發送端發送的速度很快,就會丟失數據包,UDP協議層并不報告這種錯誤。
因此,使?UDP協議的應?程序必須考慮到這些可能的問題并實現適當的解決?案,例如等待應答、超時重發、為數據包編號、流量控制等。?般使?UDP協議的應?程序實現都?較簡單,只是發送?些對可靠性要求不?的消息,?不發送?量的數據。例如,基于UDP的TFTP協議?般只?于傳送??件(所以才叫trivial的ftp),?基于TCP的FTP協議適?于 各種?件的傳輸。TCP協議?是如何??向連接的服務來代替應?程序解決傳輸的可靠性問題呢。
TCP數據報格式
TCP數據段
與UDP協議?樣也有源端?號和?的端?號,通訊的雙?由IP地址和端?號標識。32位序號、32位確認序號、窗???稍后詳細解釋。4位?部?度和IP協議頭類似,表示TCP協議頭的?度,以4字節為單位,因此TCP協議頭最?可以是4x15=60字節,如果沒有選項字段,TCP協議頭最短20字節。URG、ACK、PSH、RST、SYN、FIN是六個控制位,本節稍后將解釋SYN、ACK、FIN、RST四個位,其它位的解釋從略。16位檢驗和將TCP協議頭和數據都計算在內。緊急指針和各種選項的解釋從略。
TCP協議
TCP通信時序
下圖是?次TCP通訊的時序圖。TCP連接建?斷開。包含三次握?和四次握?。
TCP通訊時序
在這個例?中,?先客戶端主動發起連接、發送請求,然后服務器端響應請求,然后客戶端主動關閉連接。兩條豎線表示通訊的兩端,從上到下表示時間的先后順序,注意,數據從?端傳到?絡的另?端也需要時間,所以圖中的箭頭都是斜的。雙?發送的段按時間順序編號為1-10,各段中的主要信息在箭頭上標出,例如段2的箭頭上標著SYN, 8000(0), ACK1001, ,表示該段中的SYN位置1,32位序號是8000,該段不攜帶有效載荷(數據字節數為0),ACK位置1,32位確認序號是1001,帶有?個mss(Maximum Segment Size,最?報??度)選項值為1024。
建?連接(三次握?)的過程:
- 客戶端發送?個帶SYN標志的TCP報?到服務器。這是三次握?過程中的段1
客戶端發出段1,SYN位表示連接請求。序號是1000,這個序號在?絡通訊中?作臨時的地址,每發?個數據字節,這個序號要加1,這樣在接收端可以根據序號排出數據包的正確順序,也可以發現丟包的情況,另外,規定SYN位和FIN位也要占?個序號,這次雖然沒發數據,但是由于發了SYN位,因此下次再發送應該?序號1001。mss表示最?段尺?,如果?個段太?,封裝成幀后超過了鏈路層的最?幀?度,就必須在IP層分?,為了避免這種情況,客戶端聲明??的最?段尺?,建議服務器端發來的段不要超過這個?度。
- 服務器端回應客戶端,是三次握?中的第2個報?段,同時帶ACK標志和SYN標志。它表示對剛才客戶端SYN的回應;同時?發送SYN給客戶端,詢問客戶端是否準備好進?數據通訊。
服務器發出段2,也帶有SYN位,同時置ACK位表示確認,確認序號是1001,表示“我接收到序號1000及其以前所有的段,請你下次發送序號為1001的段”,也就是應答了客戶端的連接請求,同時也給客戶端發出?個連接請求,同時聲明最?尺?為1024。
- 客戶必須再次回應服務器端?個ACK報?,這是報?段3。
客戶端發出段3,對服務器的連接請求進?應答,確認序號是8001。在這個過程中,客戶端和服務器分別給對?發了連接請求,也應答了對?的連接請求,其中服務器的請求和應答在?個段中
發出,因此?共有三個段?于建?連接,稱為“三?握?(three-way-handshake)”。在建?連接的同時,雙?協商了?些信息,例如雙?發送序號的初始值、最?段尺?等。
在TCP通訊中,如果??收到另??發來的段,讀出其中的?的端?號,發現本機并沒有任何進程使?這個端?,就會應答?個包含RST位的段給另??。例如,服務器并沒有任何進程使?8080端?,我們卻?telnet客戶端去連接它,服務器收到客戶端發來的SYN段就會應答?個RST段,客戶端的telnet程序收到RST段后報告錯誤Connection refused:
$ telnet 192.168.0.200 8080
Trying 192.168.0.200...
telnet: Unable to connect to remote host: Connection refused
數據傳輸的過程:
- 客戶端發出段4,包含從序號1001開始的20個字節數據。
- 服務器發出段5,確認序號為1021,對序號為1001-1020的數據表示確認收到,同時請求發送序號1021開始的數據,服務器在應答的同時也向客戶端發送從序號8001開始的10個字節數據,這稱為piggyback。
- 客戶端發出段6,對服務器發來的序號為8001-8010的數據表示確認收到,請求發送序號8011開始的數據。
在數據傳輸過程中,ACK和確認序號是?常重要的,應?程序交給TCP協議發送的數據會暫存在TCP層的發送緩沖區中,發出數據包給對?之后,只有收到對?應答的ACK段才知道該數據包確實發到了對?,可以從發送緩沖區中釋放掉了,如果因為?絡故障丟失了數據包或者丟失了對?發回的ACK段,經過等待超時后TCP協議?動將發送緩沖區中的數據包重發。
關閉連接(四次握?)的過程:
由于TCP連接是全雙?的,因此每個?向都必須單獨進?關閉。這原則是當??完成它的數據發送任務后就能發送?個FIN來終?這個?向的連接。收到?個FIN只意味著這??向上沒有數據流動,?個TCP連接在收到?個FIN后仍能發送數據。?先進?關閉的??將執?主動關閉,?另??執?被動關閉。
- 客戶端發出段7,FIN位表示關閉連接的請求。
- 服務器發出段8,應答客戶端的關閉連接請求。
- 服務器發出段9,其中也包含FIN位,向客戶端發送關閉連接請求。
- 客戶端發出段10,應答服務器的關閉連接請求.
建?連接的過程是三?握?,?關閉連接通常需要4個段,服務器的應答和關閉連接請求通常不合并在?個段中,因為有連接半關閉的情況,這種情況下客戶端關閉連接之后就不能再發送數據給服務器了,但是服務器還可以發送數據給客戶端,直到服務器也關閉連接為?。
滑動窗? (TCP流量控制)
介紹UDP時描述了這樣的問題:如果發送端發送的速度較快,接收端接收到數據后處理的速度較慢,?接收緩沖區的??是固定的,就會丟失數據。TCP協議通過“滑動窗?(SlidingWindow)”機制解決這?問題。看下圖的通訊過程
滑動窗?
- 發送端發起連接,聲明最?段尺?是1460,初始序號是0,窗???是4K,表示“我的接收緩沖區還有4K字節空閑,你發的數據不要超過4K”。接收端應答連接請求,聲明最?段尺?是1024,初始序號是8000,窗???是6K。發送端應答,三?握?結束。
- 發送端發出段4-9,每個段帶1K的數據,發送端根據窗???知道接收端的緩沖區滿了,因此停?發送數據。
- 接收端的應?程序提?2K數據,接收緩沖區?有了2K空閑,接收端發出段10,在應答已收到6K數據的同時聲明窗???為2K。
- 接收端的應?程序?提?2K數據,接收緩沖區有4K空閑,接收端發出段11,重新聲明窗???為4K。
- 發送端發出段12-13,每個段帶2K數據,段13同時還包含FIN位。
- 接收端應答接收到的2K數據(6145-8192),再加上FIN位占?個序號8193,因此應答序號是8194,連接處于半關閉狀態,接收端同時聲明窗???為2K。
- 接收端的應?程序提?2K數據,接收端重新聲明窗???為4K。
- 接收端的應?程序提?剩下的2K數據,接收緩沖區全空,接收端重新聲明窗???為6K。
- 接收端的應?程序在提?全部數據后,決定關閉連接,發出段17包含FIN位,發送端應答,連接完全關閉。
上圖在接收端???塊表示1K數據,實?的??塊表示已接收到的數據,虛線框表示接收緩沖區,因此套在虛線框中的空???塊表示窗???,從圖中可以看出,隨著應?程序提?數據,虛線框是向右滑動的,因此稱為滑動窗?。
從這個例?還可以看出,發送端是?K?K地發送數據,?接收端的應?程序可以兩K兩K地提?數據,當然也有可能?次提?3K或6K數據,或者?次只提??個字節的數據。也就是說,應?程序所看到的數據是?個整體,或說是?個流(stream),在底層通訊中這些數據可能被拆成很多數據包來發送,但是?個數據包有多少字節對應?程序是不可?的,因此TCP協議是?向流的協議。?UDP是?向消息的協議,每個UDP段都是?條消息,應?程序必須以消息為單位提取數據,不能?次提取任意字節的數據,這?點和TCP是很不同的。
TCP狀態轉換
這個圖N多?都知道,它排除和定位?絡或系統故障時?有幫助,但是怎樣牢牢地將這張圖刻在腦中呢?那么你就?定要對這張圖的每?個狀態,及轉換的過程有深刻的認識,不能只停留在?知半解之中。下?對這張圖的11種狀態詳細解析?下,以便加強記憶!不過在這之前,先回顧?下TCP建?連接的三次握?過程,以及 關閉連接的四次握?過程。
CLOSED
:表示初始狀態。
LISTEN
:該狀態表示服務器端的某個SOCKET處于監聽狀態,可以接受連接。
SYN_SENT
:這個狀態與SYN_RCVD遙相呼應,當客戶端SOCKET執?CONNECT連接時,它?先發送SYN報?,隨即進?到了SYN_SENT狀態,并等待服務端的發送三次握?中的第2個報?。SYN_SENT狀態表示客戶端已發送SYN報?。
SYN_RCVD
: 該狀態表示接收到SYN報?,在正常情況下,這個狀態是服務器端的SOCKET在建?TCP連接時的三次握?會話過程中的?個中間狀態,很短暫。此種狀態時,當收到客戶端的ACK報?后,會進?到ESTABLISHED狀態。
ESTABLISHED
:表示連接已經建?。
FIN_WAIT_1
: FIN_WAIT_1和FIN_WAIT_2狀態的真正含義都是表示等待對?的FIN報?。區別是:FIN_WAIT_1狀態是當socket在ESTABLISHED狀態時,想主動關閉連接,向對?發送了FIN報?,此時該socket進?到FIN_WAIT_1狀態。
FIN_WAIT_2狀態是當對?回應ACK后,該socket進?到FIN_WAIT_2狀態,正常情況下,對?應?上回應ACK報?,所以FIN_WAIT_1狀態?般較難?到,?FIN_WAIT_2狀態可?netstat看到。
FIN_WAIT_2
:主動關閉鏈接的??,發出FIN收到ACK以后進?該狀態。稱之為半連接或半關閉狀態。該狀態下的socket只能接收數據,不能發。
TIME_WAIT
: 表示收到了對?的FIN報?,并發送出了ACK報?,等2MSL后即可回到CLOSED可?狀態。如果FIN_WAIT_1狀態下,收到對?同時帶FIN標志和ACK標志的報?時,可以直接進?到TIME_WAIT狀態,??須經過FIN_WAIT_2狀態。
CLOSING
: 這種狀態較特殊,屬于?種較罕?的狀態。正常情況下,當你發送FIN報?后,按理來說是應該先收到(或同時收到)對?的ACK報?,再收到對?的FIN報?。但是CLOSING狀態表示你發送FIN報?后,并沒有收到對?的ACK報?,反?卻也收到了對?的FIN報?。什么情況下會出現此種情況呢?如果雙??乎在同時close?個SOCKET的話,那么就出現了雙?同時發送FIN報?的情況,也即會出現CLOSING狀態,表示雙?都正在關閉SOCKET連接。
CLOSE_WAIT
: 此種狀態表示在等待關閉。當對?關閉?個SOCKET后發送FIN報?給??,系統會回應?個ACK報?給對?,此時則進?到CLOSE_WAIT狀態。接下來呢,察看是否還有數據發送給對?,如果沒有可以close這個SOCKET,發送FIN報?給對?,即關閉連接。所以在CLOSE_WAIT狀態下,需要關閉連接。
LAST_ACK
: 該狀態是被動關閉??在發送FIN報?后,最后等待對?的ACK報?。當收到ACK報?后,即可以進?到CLOSED可?狀態。
半關閉
當TCP鏈接中A發送FIN請求關閉,B端回應ACK后(A端進?FIN_WAIT_2狀態),B沒有?即發送FIN給A時,A?處在半鏈接狀態,此時A可以接收B發送的數據,但是A已不能再向B發送數據。
2MSL
2MSL (Maximum Segment Lifetime) TIME_WAIT狀態的存在有兩個理由:
- 讓4次握?關閉流程更加可靠;4次握?的最后?個ACK是是由主動關閉?發送出去的,若這個ACK丟失,被動關閉?會再次發?個FIN過來。若主動關閉?能夠保持?個2MSL的TIME_WAIT狀態,則有更?的機會讓丟失的ACK被再次發送出去。
- 防?lost duplicate對后續新建正常鏈接的傳輸造成破壞。lost uplicate在實際的?絡中?常常?,經常是由于路由器產?故障,路徑?法收斂,導致?個packet在路由器A,B,C之間做類似死循環的跳轉。IP頭部有個TTL,限制了?個包在?絡中的最?跳數,因此這個包有兩種命運,要么最后TTL變為0,在?絡中消失;要么TTL在變為0之前路由器路徑收斂,它憑借剩余的TTL跳數終于到達?的地。但?常可惜的是TCP通過超時重傳機制在早些時候發送了?個跟它?模?樣的
包,并先于它達到了?的地,因此它的命運也就注定被TCP協議棧拋棄。
另外?個概念叫做incarnation connection,指跟上次的socket pair?摸?樣的新連接,叫做incarnation of previous connection。lost uplicate加上incarnation connection,則會對我們的
傳輸造成致命的錯誤。
TCP是流式的,所有包到達的順序是不?致的,依靠序列號由TCP協議棧做順序的拼接;假設?個incarnation connection這時收到的seq=1000, 來了?個lost duplicate為seq=1000,len=1000,則TCP認為這個lost duplicate合法,并存放?了receive buffer,導致傳輸出現錯誤。通過?個
2MSL TIME_WAIT狀態,確保所有的lost duplicate都會消失掉,避免對新連接造成錯誤。
該狀態為什么設計在主動關閉這??:
(1)發最后ACK的是主動關閉??。
(2)只要有??保持TIME_WAIT狀態,就能起到避免incarnation connection在2MSL內的重新建?,不需要兩?都有。
如何正確對待2MSL TIME_WAIT?RFC要求socket pair在處于TIME_WAIT時,不能再起?個incarnation connection。但絕?部分
TCP實現,強加了更為嚴格的限制。在2MSL等待期間,socket中使?的本地端?在默認情況下不能再被使?。
若A 10.234.5.5 : 1234和B 10.55.55.60 : 6666建?了連接,A主動關閉,那么在A端只要port為
1234,?論對?的port和ip是什么,都不允許再起服務。這甚??RFC限制更為嚴格,RFC僅僅是要求socket pair不?致,?實現當中只要這個port處于TIME_WAIT,就不允許起連接。這個限制
對主動打開?來說是?所謂的,因為?般?的是臨時端?;但對于被動打開?,?般是server,就悲劇了,因為server?般是熟知端?。?如http,?般端?是80,不可能允許這個服務在2MSL內不能起來。
解決?案是給服務器的socket設置SO_REUSEADDR選項,這樣的話就算熟知端?處于TIME_WAIT狀態,在這個端?上依舊可以將服務啟動。當然,雖然有了SO_REUSEADDR選項,但sockt pair這個限制依舊存在。?如上?的例?,A通過SO_REUSEADDR選項依舊在1234端?上起了監聽,但這時我們若是從B通過6666端?去連它,TCP協議會告訴我們連接失敗,原因為Address already in use.
RFC 793中規定MSL為2分鐘,實際應?中常?的是30秒,1分鐘和2分鐘等。
RFC (Request For Comments),是?系列以編號排定的?件。收集了有關因特?相關資訊,以及UNIX和因特?社群的軟件?件。
粘包拆包發生的原因
產生原因主要有這3種:滑動窗口、MSS/MTU限制、Nagle算法
- 滑動窗口
TCP流量控制主要使用滑動窗口協議,滑動窗口是接受數據端使用的窗口大小,用來告訴發送端接收端的緩存大小,以此可以控制發送端發送數據的大小,從而達到流量
控制的目的。這個窗口大小就是我們一次傳輸幾個數據。對所有數據幀按順序賦予編號,發送方在發送過程中始終保持著一個發送窗口,只有落在發送窗口內的幀才允許被發送;
同時接收方也維持著一個接收窗口,只有落在接收窗口內的幀才允許接收。這樣通過調整發送方窗口和接收方窗口的大小可以實現流量控制。
現在來看一下滑動窗口是如何造成粘包、拆包的?
粘包:假設發送方的每256 bytes表示一個完整的報文,接收方由于數據處理不及時,這256個字節的數據都會被緩存到SO_RCVBUF(接收緩存區)中。如果接收方的SO_RCVBUF中緩存了多個報文,那么對于接收方而言,這就是粘包。
拆包:考慮另外一種情況,假設接收方的窗口只剩了128,意味著發送方最多還可以發送128字節,而由于發送方的數據大小是256字節,因此只能發送前128字節,等到接收方ack后,才能發送剩余字節。這就造成了拆包。
- MSS和MTU分片
MSS: 是Maximum Segement Size縮寫,表示TCP報文中data部分的最大長度,是TCP協議在OSI五層網絡模型中傳輸層對一次可以發送的最大數據的限制。
MTU: 最大傳輸單元是Maxitum Transmission Unit的簡寫,是OSI五層網絡模型中鏈路層(datalink layer)對一次可以發送的最大數據的限制。
當需要傳輸的數據大于MSS或者MTU時,數據會被拆分成多個包進行傳輸。由于MSS是根據MTU計算出來的,因此當發送的數據滿足MSS時,必然滿足MTU。
MTU是以太網傳輸數據方面的限制,每個以太網幀都有最小的大小64bytes最大不能超過1518bytes。刨去以太網幀的幀頭 (DMAC目的MAC地址48bit=6Bytes+SMAC源MAC地址48bit=6Bytes+Type域2bytes)14Bytes和幀尾 CRC校驗部分4Bytes(這個部分有時候大家也把它叫做FCS),那么剩下承載上層協議的地方也就是Data域最大就只能有1500Bytes這個值 我們就把它稱之為MTU。
由于MTU限制了一次最多可以發送1500個字節,而TCP協議在發送DATA時,還會加上額外的TCP Header和Ip Header,因此刨去這兩個部分,就是TCP協議一次可以發送的實際應用數據的最大大小,也就是MSS。
MSS長度=MTU長度-IP Header-TCP Header
TCP Header的長度是20字節,IPv4中IP Header長度是20字節,IPV6中IP Header長度是40字節,因此:在IPV4中,以太網MSS可以達到1460byte;在IPV6中,以太網MSS可以達到1440byte。
需要注意的是MSS表示的一次可以發送的DATA的最大長度,而不是DATA的真實長度。發送方發送數據時,當SO_SNDBUF中的數據量大于MSS時,操作系統會將數據進行拆分,使得每一部分都小于MSS,這就是拆包,然后每一部分都加上TCP Header,構成多個完整的TCP報文進行發送,當然經過網絡層和數據鏈路層的時候,還會分別加上相應的內容。
需要注意: 默認情況下,與外部通信的網卡的MTU大小是1500個字節。而本地回環地址的MTU大小為65535,這是因為本地測試時數據不需要走網卡,所以不受到1500的限制。
3、 Nagle算法
TCP/IP協議中,無論發送多少數據,總是要在數據(DATA)前面加上協議頭(TCP Header+IP Header),同時,對方接收到數據,也需要發送ACK表示確認。
即使從鍵盤輸入的一個字符,占用一個字節,可能在傳輸上造成41字節的包,其中包括1字節的有用信息和40字節的首部數據。這種情況轉變成了4000%的消耗,這樣的情況對于重負載的網絡來是無法接受的。
為了盡可能的利用網絡帶寬,TCP總是希望盡可能的發送足夠大的數據。(一個連接會設置MSS參數,因此,TCP/IP希望每次都能夠以MSS尺寸的數據塊來發送數據)。
Nagle算法就是為了盡可能發送大塊數據,避免網絡中充斥著許多小數據塊。
Nagle算法的基本定義是任意時刻,最多只能有一個未被確認的小段。 所謂“小段”,指的是小于MSS尺寸的數據塊,所謂“未被確認”,是指一個數據塊發送出去后,沒有收到對方發送的ACK確認該數據已收到。
Nagle算法的規則:
1)如果SO_SNDBUF(發送緩沖區)中的數據長度達到MSS,則允許發送;
2)如果該SO_SNDBUF中含有FIN,表示請求關閉連接,則先將SO_SNDBUF中的剩余數據發送,再關閉;
3)設置了TCP_NODELAY=true選項,則允許發送。TCP_NODELAY是取消TCP的確認延遲機制,相當于禁用了Nagle 算法。
4)未設置TCP_CORK選項時,若所有發出去的小數據包(包長度小于MSS)均被確認,則允許發送;
5)上述條件都未滿足,但發生了超時(一般為200ms),則立即發送。
總結:UDP無粘包拆遷現象,最多會出現丟包問題,因為是不可靠通信方式; Nagle的算法通常會在TCP程序里添加兩行代碼,在未確認數據發送的時候讓發送器把數據送到緩存里。任何數據隨后繼續直到得到明顯的數據確認或者直到攢到了一定數量的數據了再發包。降低網絡負載