linux网络编程(一)网络基础传输知识
linux網(wǎng)絡(luò)編程(一)網(wǎng)絡(luò)傳輸基礎(chǔ)知識(shí)
- 一、什么是協(xié)議?
- 二、使用步驟
- 典型協(xié)議
- 2.網(wǎng)絡(luò)應(yīng)用程序設(shè)計(jì)模式
- C/S模式
- B/S模式
- 優(yōu)缺點(diǎn)
- 3.分層模型
- 4.TCP/IP四層模型
- 通信過(guò)程
- 5.協(xié)議格式
- 數(shù)據(jù)包封裝
- 以太網(wǎng)幀格式
- ARP數(shù)據(jù)報(bào)格式
- IP段格式
- UDP數(shù)據(jù)報(bào)格式
- TCP數(shù)據(jù)報(bào)格式
- 6.TCP協(xié)議
- 三次握手
- 四次握手
- 服務(wù)器
- 客戶端
一、什么是協(xié)議?
示例:pandas 是基于NumPy 的一種工具,該工具是為了解決數(shù)據(jù)分析任務(wù)而創(chuàng)建的。
二、使用步驟
從應(yīng)用的角度出發(fā),協(xié)議可理解為“規(guī)則”,是數(shù)據(jù)傳輸和數(shù)據(jù)的解釋的規(guī)則.
假設(shè),A、B雙方欲傳輸文件。規(guī)定:
第一次,傳輸文件名,接收方接收到文件名,應(yīng)答OK給傳輸方;
第二次,發(fā)送文件的尺寸,接收方接收到該數(shù)據(jù)再次應(yīng)答一個(gè)OK;
第三次,傳輸文件內(nèi)容。同樣,接收方接收數(shù)據(jù)完成后應(yīng)答OK表示文件內(nèi)容接收成功。
由此,無(wú)論A、B之間傳遞何種文件,都是通過(guò)三次數(shù)據(jù)傳輸來(lái)完成。A、B之間形成了一個(gè)最簡(jiǎn)單的數(shù)據(jù)傳輸規(guī)則。雙方都按此規(guī)則發(fā)送、接收數(shù)據(jù)。A、B之間達(dá)成的這個(gè)相互遵守的規(guī)則即為協(xié)議。
這種僅在A、B之間被遵守的協(xié)議稱之為原始協(xié)議。當(dāng)此協(xié)議被更多的人采用,不斷的增加、改進(jìn)、維護(hù)、完善。最終形成一個(gè)穩(wěn)定的、完整的文件傳輸協(xié)議,被廣泛應(yīng)用于各種文件傳輸過(guò)程中。該協(xié)議就成為一個(gè)標(biāo)準(zhǔn)協(xié)議。最早的ftp協(xié)議就是由此衍生而來(lái)。
典型協(xié)議
傳輸層 常見(jiàn)協(xié)議有TCP/UDP協(xié)議。
應(yīng)用層 常見(jiàn)的協(xié)議有HTTP協(xié)議,FTP協(xié)議。
網(wǎng)絡(luò)層 常見(jiàn)協(xié)議有IP協(xié)議、ICMP協(xié)議、IGMP協(xié)議。
網(wǎng)絡(luò)接口層 常見(jiàn)協(xié)議有ARP協(xié)議、RARP協(xié)議。
TCP傳輸控制協(xié)議(Transmission Control Protocol)是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議。
UDP用戶數(shù)據(jù)報(bào)協(xié)議(User Datagram Protocol)是OSI參考模型中一種無(wú)連接的傳輸層協(xié)議,提供面向事務(wù)的簡(jiǎn)單不可靠信息傳送服務(wù)。
HTTP超文本傳輸協(xié)議(Hyper Text Transfer Protocol)是互聯(lián)網(wǎng)上應(yīng)用最為廣泛的一種網(wǎng)絡(luò)協(xié)議。
FTP文件傳輸協(xié)議(File Transfer Protocol)
IP協(xié)議是因特網(wǎng)互聯(lián)協(xié)議(Internet Protocol)
ICMP協(xié)議是Internet控制報(bào)文協(xié)議(Internet Control Message Protocol)它是TCP/IP協(xié)議族的一個(gè)子協(xié)議,用于在IP主機(jī)、路由器之間傳遞控制消息。
IGMP協(xié)議是 Internet 組管理協(xié)議(Internet Group Management Protocol),是因特網(wǎng)協(xié)議家族中的一個(gè)組播協(xié)議。該協(xié)議運(yùn)行在主機(jī)和組播路由器之間。
ARP協(xié)議是正向地址解析協(xié)議(Address Resolution Protocol),通過(guò)已知的IP,尋找對(duì)應(yīng)主機(jī)的MAC地址。
RARP是反向地址轉(zhuǎn)換協(xié)議,通過(guò)MAC地址確定IP地址。
2.網(wǎng)絡(luò)應(yīng)用程序設(shè)計(jì)模式
C/S模式
傳統(tǒng)的網(wǎng)絡(luò)應(yīng)用設(shè)計(jì)模式,客戶機(jī)(client)/服務(wù)器(server)模式。需要在通訊兩端各自部署客戶機(jī)和服務(wù)器來(lái)完成數(shù)據(jù)通信
B/S模式
瀏覽器/服務(wù)器(server)模式。只需在一端部署服務(wù)器,而另外一端使用每臺(tái)PC都默認(rèn)配置的瀏覽器即可完成數(shù)據(jù)的傳輸。
優(yōu)缺點(diǎn)
C/S 優(yōu)點(diǎn):1.協(xié)議靈活可自定義 2.緩存數(shù)據(jù)
缺點(diǎn):1.對(duì)用戶的安全構(gòu)成威脅 2.開(kāi)發(fā)工作量較大,調(diào)試?yán)щy
B/S 優(yōu)點(diǎn):1.跨平臺(tái) 2.無(wú)需緩存數(shù)據(jù)3.開(kāi)發(fā)量小
缺點(diǎn):1.只能采用http協(xié)議
代碼如下(示例):
3.分層模型
4.TCP/IP四層模型
通信過(guò)程
兩臺(tái)計(jì)算機(jī)通過(guò)TCP/IP協(xié)議通訊的過(guò)程如下所示:
上圖對(duì)應(yīng)兩臺(tái)計(jì)算機(jī)在同一網(wǎng)段中的情況,如果兩臺(tái)計(jì)算機(jī)在不同的網(wǎng)段中,那么數(shù)據(jù)從一臺(tái)計(jì)算機(jī)到另一臺(tái)計(jì)算機(jī)傳輸過(guò)程中要經(jīng)過(guò)一個(gè)或多個(gè)路由器,如下圖所示:
5.協(xié)議格式
數(shù)據(jù)包封裝
傳輸層及其以下的機(jī)制由內(nèi)核提供,應(yīng)用層由用戶進(jìn)程提供(后面將介紹如何使用socket API編寫應(yīng)用程序),應(yīng)用程序?qū)νㄓ崝?shù)據(jù)的含義進(jìn)行解釋,而傳輸層及其以下處理通訊的細(xì)節(jié),將數(shù)據(jù)從一臺(tái)計(jì)算機(jī)通過(guò)一定的路徑發(fā)送到另一臺(tái)計(jì)算機(jī)。應(yīng)用層數(shù)據(jù)通過(guò)協(xié)議棧發(fā)到網(wǎng)絡(luò)上時(shí),每層協(xié)議都要加上一個(gè)數(shù)據(jù)首部(header),稱為封裝(Encapsulation),如下圖所示:
不同的協(xié)議層對(duì)數(shù)據(jù)包有不同的稱謂,在傳輸層叫做段(segment),在網(wǎng)絡(luò)層叫做數(shù)據(jù)報(bào)(datagram),在鏈路層叫做幀(frame)。數(shù)據(jù)封裝成幀后發(fā)到傳輸介質(zhì)上,到達(dá)目的主機(jī)后每層協(xié)議再剝掉相應(yīng)的首部,最后將應(yīng)用層數(shù)據(jù)交給應(yīng)用程序處理
以太網(wǎng)幀格式
其中的源地址和目的地址是指網(wǎng)卡的硬件地址(也叫MAC地址),長(zhǎng)度是48位,是在網(wǎng)卡出廠時(shí)固化的。可在shell中使用ifconfig命令查看,“HWaddr 00:15:F2:14:9E:3F”部分就是硬件地址。協(xié)議字段有三種值,分別對(duì)應(yīng)IP、ARP、RARP。幀尾是CRC校驗(yàn)碼。
以太網(wǎng)幀中的數(shù)據(jù)長(zhǎng)度規(guī)定最小46字節(jié),最大1500字節(jié),ARP和RARP數(shù)據(jù)包的長(zhǎng)度不夠46字節(jié),要在后面補(bǔ)填充位。最大值1500稱為以太網(wǎng)的最大傳輸單元(MTU),不同的網(wǎng)絡(luò)類型有不同的MTU,如果一個(gè)數(shù)據(jù)包從以太網(wǎng)路由到撥號(hào)鏈路上,數(shù)據(jù)包長(zhǎng)度大于撥號(hào)鏈路的MTU,則需要對(duì)數(shù)據(jù)包進(jìn)行分片(fragmentation)。ifconfig命令輸出中也有“MTU:1500”。注意,MTU這個(gè)概念指數(shù)據(jù)幀中有效載荷的最大長(zhǎng)度,不包括幀頭長(zhǎng)度。
ARP數(shù)據(jù)報(bào)格式
在網(wǎng)絡(luò)通訊時(shí),源主機(jī)的應(yīng)用程序知道目的主機(jī)的IP地址和端口號(hào),卻不知道目的主機(jī)的硬件地址,而數(shù)據(jù)包首先是被網(wǎng)卡接收到再去處理上層協(xié)議的,如果接收到的數(shù)據(jù)包的硬件地址與本機(jī)不符,則直接丟棄。因此在通訊前必須獲得目的主機(jī)的硬件地址。ARP協(xié)議就起到這個(gè)作用。源主機(jī)發(fā)出ARP請(qǐng)求,詢問(wèn)“IP地址是192.168.0.1的主機(jī)的硬件地址是多少”,并將這個(gè)請(qǐng)求廣播到本地網(wǎng)段(以太網(wǎng)幀首部的硬件地址填FF:FF:FF:FF:FF:FF表示廣播),目的主機(jī)接收到廣播的ARP請(qǐng)求,發(fā)現(xiàn)其中的IP地址與本機(jī)相符,則發(fā)送一個(gè)ARP應(yīng)答數(shù)據(jù)包給源主機(jī),將自己的硬件地址填寫在應(yīng)答包中。
源MAC地址、目的MAC地址在以太網(wǎng)首部和ARP請(qǐng)求中各出現(xiàn)一次,對(duì)于鏈路層為以太網(wǎng)的情況是多余的,但如果鏈路層是其它類型的網(wǎng)絡(luò)則有可能是必要的。硬件類型指鏈路層網(wǎng)絡(luò)類型,1為以太網(wǎng),協(xié)議類型指要轉(zhuǎn)換的地址類型,0x0800為IP地址,后面兩個(gè)地址長(zhǎng)度對(duì)于以太網(wǎng)地址和IP地址分別為6和4(字節(jié)),op字段為1表示ARP請(qǐng)求,op字段為2表示ARP應(yīng)答
看一個(gè)具體的例子。
請(qǐng)求幀如下(為了清晰在每行的前面加了字節(jié)計(jì)數(shù),每行16個(gè)字節(jié)):
以太網(wǎng)首部(14字節(jié))
0000: ff ff ff ff ff ff 00 05 5d 61 58 a8 08 06
ARP幀(28字節(jié))
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字節(jié))
0020: 00 77 31 d2 50 10
0030: fd 78 41 d3 00 00 00 00 00 00 00 00
以太網(wǎng)首部:目的主機(jī)采用廣播地址,源主機(jī)的MAC地址是00:05:5d:61:58:a8,上層協(xié)議類型0x0806表示ARP。
ARP幀:硬件類型0x0001表示以太網(wǎng),協(xié)議類型0x0800表示IP協(xié)議,硬件地址(MAC地址)長(zhǎng)度為6,協(xié)議地址(IP地址)長(zhǎng)度為4,op為0x0001表示請(qǐng)求目的主機(jī)的MAC地址,源主機(jī)MAC地址為00:05:5d:61:58:a8,源主機(jī)IP地址為c0 a8 00 37(192.168.0.55),目的主機(jī)MAC地址全0待填寫,目的主機(jī)IP地址為c0 a8 00 02(192.168.0.2)。
由于以太網(wǎng)規(guī)定最小數(shù)據(jù)長(zhǎng)度為46字節(jié),ARP幀長(zhǎng)度只有28字節(jié),因此有18字節(jié)填充位,填充位的內(nèi)容沒(méi)有定義,與具體實(shí)現(xiàn)相關(guān)。
應(yīng)答幀如下:
以太網(wǎng)首部
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
以太網(wǎng)首部:目的主機(jī)的MAC地址是00:05:5d:61:58:a8,源主機(jī)的MAC地址是00:05:5d:a1:b8:40,上層協(xié)議類型0x0806表示ARP。
ARP幀:硬件類型0x0001表示以太網(wǎng),協(xié)議類型0x0800表示IP協(xié)議,硬件地址(MAC地址)長(zhǎng)度為6,協(xié)議地址(IP地址)長(zhǎng)度為4,op為0x0002表示應(yīng)答,源主機(jī)MAC地址為00:05:5d:a1:b8:40,源主機(jī)IP地址為c0 a8 00 02(192.168.0.2),目的主機(jī)MAC地址為00:05:5d:61:58:a8,目的主機(jī)IP地址為c0 a8 00 37(192.168.0.55)。
IP段格式
IP數(shù)據(jù)報(bào)的首部長(zhǎng)度和數(shù)據(jù)長(zhǎng)度都是可變長(zhǎng)的,但總是4字節(jié)的整數(shù)倍。對(duì)于IPv4,4位版本字段是4。4位首部長(zhǎng)度的數(shù)值是以4字節(jié)為單位的,最小值為5,也就是說(shuō)首部長(zhǎng)度最小是4x5=20字節(jié),也就是不帶任何選項(xiàng)的IP首部,4位能表示的最大值是15,也就是說(shuō)首部長(zhǎng)度最大是60字節(jié)。8位TOS字段有3個(gè)位用來(lái)指定IP數(shù)據(jù)報(bào)的優(yōu)先級(jí)(目前已經(jīng)廢棄不用),還有4個(gè)位表示可選的服務(wù)類型(最小延遲、最大?吐量、最大可靠性、最小成本),還有一個(gè)位總是0。總長(zhǎng)度是整個(gè)數(shù)據(jù)報(bào)(包括IP首部和IP層payload)的字節(jié)數(shù)。每傳一個(gè)IP數(shù)據(jù)報(bào),16位的標(biāo)識(shí)加1,可用于分片和重新組裝數(shù)據(jù)報(bào)。3位標(biāo)志和13位片偏移用于分片。TTL(Time to live)是這樣用的:源主機(jī)為數(shù)據(jù)包設(shè)定一個(gè)生存時(shí)間,比如64,每過(guò)一個(gè)路由器就把該值減1,如果減到0就表示路由已經(jīng)太長(zhǎng)了仍然找不到目的主機(jī)的網(wǎng)絡(luò),就丟棄該包,因此這個(gè)生存時(shí)間的單位不是秒,而是跳(hop)。協(xié)議字段指示上層協(xié)議是TCP、UDP、ICMP還是IGMP。然后是校驗(yàn)和,只校驗(yàn)IP首部,數(shù)據(jù)的校驗(yàn)由更高層協(xié)議負(fù)責(zé)。IPv4的IP地址長(zhǎng)度為32位。
UDP數(shù)據(jù)報(bào)格式
TCP數(shù)據(jù)報(bào)格式
與UDP協(xié)議一樣也有源端口號(hào)和目的端口號(hào),通訊的雙方由IP地址和端口號(hào)標(biāo)識(shí)。32位序號(hào)、32位確認(rèn)序號(hào)、窗口大小稍后詳細(xì)解釋。4位首部長(zhǎng)度和IP協(xié)議頭類似,表示TCP協(xié)議頭的長(zhǎng)度,以4字節(jié)為單位,因此TCP協(xié)議頭最長(zhǎng)可以是4x15=60字節(jié),如果沒(méi)有選項(xiàng)字段,TCP協(xié)議頭最短20字節(jié)。URG、ACK、PSH、RST、SYN、FIN是六個(gè)控制位,本節(jié)稍后將解釋SYN、ACK、FIN、RST四個(gè)位,其它位的解釋從略。16位檢驗(yàn)和將TCP協(xié)議頭和數(shù)據(jù)都計(jì)算在內(nèi)。緊急指針和各種選項(xiàng)的解釋從略。
6.TCP協(xié)議
三次握手
建立連接(三次握手)的過(guò)程:
客戶端發(fā)出段1,SYN位表示連接請(qǐng)求。序號(hào)是1000,這個(gè)序號(hào)在網(wǎng)絡(luò)通訊中用作臨時(shí)的地址,每發(fā)一個(gè)數(shù)據(jù)字節(jié),這個(gè)序號(hào)要加1,這樣在接收端可以根據(jù)序號(hào)排出數(shù)據(jù)包的正確順序,也可以發(fā)現(xiàn)丟包的情況,另外,規(guī)定SYN位和FIN位也要占一個(gè)序號(hào),這次雖然沒(méi)發(fā)數(shù)據(jù),但是由于發(fā)了SYN位,因此下次再發(fā)送應(yīng)該用序號(hào)1001。mss表示最大段尺寸,如果一個(gè)段太大,封裝成幀后超過(guò)了鏈路層的最大幀長(zhǎng)度,就必須在IP層分片,為了避免這種情況,客戶端聲明自己的最大段尺寸,建議服務(wù)器端發(fā)來(lái)的段不要超過(guò)這個(gè)長(zhǎng)度。
服務(wù)器發(fā)出段2,也帶有SYN位,同時(shí)置ACK位表示確認(rèn),確認(rèn)序號(hào)是1001,表示“我接收到序號(hào)1000及其以前所有的段,請(qǐng)你下次發(fā)送序號(hào)為1001的段”,也就是應(yīng)答了客戶端的連接請(qǐng)求,同時(shí)也給客戶端發(fā)出一個(gè)連接請(qǐng)求,同時(shí)聲明最大尺寸為1024。
客戶端發(fā)出段3,對(duì)服務(wù)器的連接請(qǐng)求進(jìn)行應(yīng)答,確認(rèn)序號(hào)是8001。在這個(gè)過(guò)程中,客戶端和服務(wù)器分別給對(duì)方發(fā)了連接請(qǐng)求,也應(yīng)答了對(duì)方的連接請(qǐng)求,其中服務(wù)器的請(qǐng)求和應(yīng)答在一個(gè)段中發(fā)出,因此一共有三個(gè)段用于建立連接,稱為“三方握手(three-way-handshake)”。在建立連接的同時(shí),雙方協(xié)商了一些信息,例如雙方發(fā)送序號(hào)的初始值、最大段尺寸等。
四次握手
由于TCP連接是全雙工的,因此每個(gè)方向都必須單獨(dú)進(jìn)行關(guān)閉。這原則是當(dāng)一方完成它的數(shù)據(jù)發(fā)送任務(wù)后就能發(fā)送一個(gè)FIN來(lái)終止這個(gè)方向的連接。收到一個(gè) FIN只意味著這一方向上沒(méi)有數(shù)據(jù)流動(dòng),一個(gè)TCP連接在收到一個(gè)FIN后仍能發(fā)送數(shù)據(jù)。首先進(jìn)行關(guān)閉的一方將執(zhí)行主動(dòng)關(guān)閉,而另一方執(zhí)行被動(dòng)關(guān)閉。
服務(wù)器
#include <sys/types.h> #include <sys/socket.h> #include <stdlib.h> #include <unistd.h> #include <sys/stat.h> #include <netinet/in.h> #include <arpa/inet.h> #include <ctype.h> #include <stdio.h> #include <memory.h>#define SERV_PORT 6666 #define SERV_IP "127.0.0.1"int main() {int sid,ret,cid,len;struct sockaddr_in addr,clie_addr;char buf[BUFSIZ] = {0};char clie_IP[BUFSIZ];socklen_t clie_len,clie_ip_len;//服務(wù)器創(chuàng)建套接字sid=socket(AF_INET, SOCK_STREAM,0);if (sid == -1){perror("server error:");exit(1);}bzero(&addr,sizeof(addr));addr.sin_family = AF_INET;addr.sin_port = htons(SERV_PORT);addr.sin_addr.s_addr =htonl( INADDR_ANY);//綁定ret=bind(sid,(struct sockaddr*)&addr,sizeof(addr));if (ret == -1){perror("bind error:");exit(1);}ret=listen(sid,30);if (ret == -1){perror("listen error:");exit(1);}clie_len = sizeof(clie_addr);cid=accept(sid, (struct sockaddr*)&clie_addr, &clie_printf("client IP:%s,client port:%d\n",inet_ntop(AF_INET,&clie_addr.sin_addr.s_addr,cli, ntohs(clie_addr.sin_port));while (1){//讀取客戶端信息len = read(cid, buf, sizeof(buf));if (len < 0){perror("read error");exit(1);}write(STDOUT_FILENO, buf, sizeof(buf));for (int i = 0; i < len; i++){buf[i] = toupper(buf[i]);}write(cid, buf, sizeof(buf));memset(buf,0,sizeof(buf));}close(sid);close(cid);return 0; }客戶端
#include <sys/types.h> #include <sys/socket.h> #include <stdlib.h> #include <unistd.h> #include <sys/stat.h> #include <netinet/in.h> #include <arpa/inet.h> #include <ctype.h> #include <stdio.h> #include <memory.h>#define CLIE_PORT 6666 #define CLIE_IP "118.178.192.222"int main() {char buf[BUFSIZ] = {0};struct in_addr s; // IPv4地址結(jié)構(gòu)體int cfd,ret,n;struct sockaddr_in addr;//客服端創(chuàng)建套接字cfd = socket(AF_INET,SOCK_STREAM,0);if (cfd == -1){perror("client error:");exit(1);}memset(&addr, 0, sizeof(addr));addr.sin_family = AF_INET;addr.sin_port = htons(CLIE_PORT);inet_pton(AF_INET, CLIE_IP,&addr.sin_addr.s_addr);ret =connect(cfd,(struct sockaddr *)&addr,sizeof(addr));if (ret <0){perror("connect error:");exit(1);}while (1){//從終端寫入fgets(buf,sizeof(buf),stdin);write(cfd,buf,strlen(buf));n=read(cfd, buf, sizeof(buf));write(STDOUT_FILENO, buf, n);memset(buf, 0, sizeof(buf));}close(cfd);return 0; }總結(jié)
以上是生活随笔為你收集整理的linux网络编程(一)网络基础传输知识的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Java这个地方list添加temp为什
- 下一篇: linux网络编程(二)高并发服务器