前言
本文不會去介紹tcp的具體協議,因為這個tcp 應該不能說是單純的連線和傳輸資料這麼簡單,裡面還有很多機制。
正文
首先介紹一下什麼是協議族(protocal Family),舉個例子PF_INET 為ipv4 協議族了。
為什麼有一個族的概念呢?因為吧,ipv4 有很多協議,地址解析協議ARP(Address Resolution Protocol)、逆地址解析協議RARP(Reverse Address Resolution Protocol)、網際網路控制報文協議ICMP(Internet Control Message Protocol)、傳輸控制協議TCP(Transmission Contronl Protocol)和使用者資料包協議UDP(User Datagram Protocol)。
所以要理解ip 協議還不是這麼簡單的,然後還有一個叫做地址族的。
地址族和協議族其實是一樣的,值也一樣,都是用來識別不同協議的,為什麼要搞兩套東西呢?這是因為之前UNIX有兩種風格系統:BSD系統和POSIX系統,對於BSD系統,一直用的是AF,對於POSIX系統,一直用的是PF。Linux作為後起之秀,為了相容,所以兩種都支援,這樣兩種風格的UNIX下的軟體就可以在Linux上執行了。
然後有了ipv4協議族,那麼還有一個是資料傳輸方式,叫做socketType。
理論上我們已經知道了是ipv4的協議族了,那麼為什麼有一個socketType呢?
為什麼有這樣一個東西呢? ipv4 協議族我們知道了,有這麼多協議。
但是吧,這裡並沒有指明,用什麼傳輸協議。
比如說面向連線的套接字(socket_stream):
有以下特點:
- 傳輸過程中資料不會消失
- 按序傳輸資料
- 傳輸的資料不存在邊界
傳輸的資料不存在邊界,這個怎麼說呢?
就是說我可以把一個G的資料,我分為很多包來傳輸,雖然每次傳輸的都比較小,但是隻要保證資料連線正常,我還是可以傳輸完成的。
按序傳輸的,比如我要傳輸一篇文章,被分成了10個包,這些包是按照順序傳輸的,也就是第一個包沒有收到,第二個包就不會傳輸。
傳輸過程資料不會消失,主要是講究的其的可靠性。
比如說包沒收到會重發,包如果收到重複了會丟棄。
一般兩邊都有快取, 如果接收方無法快取了,也會有相應的對策,讓服務方能夠重發收到。總之就是有一些措施能夠讓其資料穩定收到。
另外還有一種比較出名的socketType是Sock_DGRAM。
傳輸特點:
- 強調快速傳輸而非傳輸順序
- 傳輸的資料可能丟失可能損毀
- 傳輸的資料有資料邊界
- 限制每次傳輸的資料大小
首先說一下資料邊界,前面我們提及到Sock_Steam 說沒有資料邊界。
這個我們說過,就是說其實就是每次傳輸的都很小,但是組裝理論上可以無限大。
而這個Sock_DGRAM 每次傳輸就是這麼大,也就是資料只能這麼多。
Sock_DGRAM 也不會說等上一個傳輸完成,下一個才開始傳輸,其是無序的。
除了socketType,那麼還有一個叫做ProtocolType的。
這是怎麼回事呢?我們指定了協議族,指點了傳輸型別,為什麼要指定ProtocolType呢?
這是因為同一協議族中,可能存在多個傳輸型別相同的協議。
不過再ipv4 中傳輸方式是Sock_Steam也就只要tcp了。
而Sock_DGRAM 也就只有UDP了。
這些大概就是設定一個socket的值了。
接下來說一下ip,ip 地址有下面幾類:
A類:(1.0.0.0-126.0.0.0)(預設子網掩碼:255.0.0.0或 0xFF000000)第一個位元組為網路號,後三個位元組為主機號。該類IP地址的最前面為“0”,所以地址的網路號取值於1~126之間。一般用於大型網路。
首位0開頭的
B類:(128.0.0.0-191.255.0.0)(預設子網掩碼:255.255.0.0或0xFFFF0000)前兩個位元組為網路號,後兩個位元組為主機號。該類IP地址的最前面為“10”,所以地址的網路號取值於128~191之間。一般用於中等規模網路。
首位10開頭的
C類:(192.0.0.0-223.255.255.0)(子網掩碼:255.255.255.0或 0xFFFFFF00)前三個位元組為網路號,最後一個位元組為主機號。該類IP地址的最前面為“110”,所以地址的網路號取值於192~223之間。一般用於小型網路。
首位110開頭的
D類:是多播地址。該類IP地址的最前面為“1110”,所以地址的網路號取值於224~239之間。一般用於多路廣播使用者[1] 。
E類:是保留地址。該類IP地址的最前面為“1111”,所以地址的網路號取值於240~255之間。
再說資料傳輸過程中,因為cpu的儲存記憶體有大端序和小端序,這個可以自行去百度,那麼網路傳輸中規定傳輸的都是大端序,這個需要注意。
實際上,這個大端序和小端序的問題不用考慮我們傳送的訊息,一般send會做自動轉換。
但是隻有bind的時候和connect的時候需要注意,因為這個是寫入到作業系統中,不會做轉換,就需要注意一下。
上面這個不絕對哈,看語言的,有些會幫忙轉的。
結
下一結編寫一個完整的tcp服務端和客戶端,後面就是一直根據編寫的程式碼,介紹會有什麼問題,然後做改造。