歡迎關(guān)注博主 Mindtechnist 或加入【Linux C/C++/Python社區(qū)】一起學(xué)習(xí)和分享Linux、C、C++、Python、Matlab,機(jī)器人運(yùn)動(dòng)控制、多機(jī)器人協(xié)作,智能優(yōu)化算法,濾波估計(jì)、多傳感器信息融合,機(jī)器學(xué)習(xí),人工智能等相關(guān)領(lǐng)域的知識(shí)和技術(shù)。
專欄:《網(wǎng)絡(luò)編程》
計(jì)算機(jī)通訊過程
兩臺(tái)計(jì)算機(jī)通過TCP/IP協(xié)議通訊的過程如下所示:
上圖對應(yīng)兩臺(tái)計(jì)算機(jī)在同一網(wǎng)段中的情況,如果兩臺(tái)計(jì)算機(jī)在不同的網(wǎng)段中,那么數(shù)據(jù)從一臺(tái)計(jì)算機(jī)到另一臺(tái)計(jì)算機(jī)傳輸過程中要經(jīng)過一個(gè)或多個(gè)路由器,如下圖所示:
鏈路層有以太網(wǎng)、令牌環(huán)網(wǎng)等標(biāo)準(zhǔn),鏈路層負(fù)責(zé)網(wǎng)卡設(shè)備的驅(qū)動(dòng)、幀同步(即從網(wǎng)線上檢測到什么信號(hào)算作新幀的開始)、沖突檢測(如果檢測到?jīng)_突就自動(dòng)重發(fā))、數(shù)據(jù)差錯(cuò)校驗(yàn)等工作。交換機(jī)是工作在鏈路層的網(wǎng)絡(luò)設(shè)備,可以在不同的鏈路層網(wǎng)絡(luò)之間轉(zhuǎn)發(fā)數(shù)據(jù)幀(比如十兆以太網(wǎng)和百兆以太網(wǎng)之間、以太網(wǎng)和令牌環(huán)網(wǎng)之間),由于不同鏈路層的幀格式不同,交換機(jī)要將進(jìn)來的數(shù)據(jù)包拆掉鏈路層首部重新封裝之后再轉(zhuǎn)發(fā)。
網(wǎng)絡(luò)層的IP協(xié)議是構(gòu)成Internet的基礎(chǔ)。Internet上的主機(jī)通過IP地址來標(biāo)識(shí),Inter-net上有大量路由器負(fù)責(zé)根據(jù)IP地址選擇合適的路徑轉(zhuǎn)發(fā)數(shù)據(jù)包,數(shù)據(jù)包從Internet上的源主機(jī)到目的主機(jī)往往要經(jīng)過十多個(gè)路由器。路由器是工作在第三層的網(wǎng)絡(luò)設(shè)備,同時(shí)兼有交換機(jī)的功能,可以在不同的鏈路層接口之間轉(zhuǎn)發(fā)數(shù)據(jù)包,因此路由器需要將進(jìn)來的數(shù)據(jù)包拆掉網(wǎng)絡(luò)層和鏈路層兩層首部并重新封裝。IP協(xié)議不保證傳輸?shù)目煽啃?,?shù)據(jù)包在傳輸過程中可能丟失,可靠性可以在上層協(xié)議或應(yīng)用程序中提供支持。
網(wǎng)絡(luò)層負(fù)責(zé)點(diǎn)到點(diǎn)(ptop,point-to-point)的傳輸(這里的“點(diǎn)”指主機(jī)或路由器),而傳輸層負(fù)責(zé)端到端(etoe,end-to-end)的傳輸(這里的“端”指源主機(jī)和目的主機(jī))。傳輸層可選擇TCP或UDP協(xié)議。
TCP是一種面向連接的、可靠的協(xié)議,有點(diǎn)像打電話,雙方拿起電話互通身份之后就建立了連接,然后說話就行了,這邊說的話那邊保證聽得到,并且是按說話的順序聽到的,說完話掛機(jī)斷開連接。也就是說TCP傳輸?shù)碾p方需要首先建立連接,之后由TCP協(xié)議保證數(shù)據(jù)收發(fā)的可靠性,丟失的數(shù)據(jù)包自動(dòng)重發(fā),上層應(yīng)用程序收到的總是可靠的數(shù)據(jù)流,通訊之后關(guān)閉連接。
UDP是無連接的傳輸協(xié)議,不保證可靠性,有點(diǎn)像寄信,信寫好放到郵筒里,既不能保證信件在郵遞過程中不會(huì)丟失,也不能保證信件寄送順序。使用UDP協(xié)議的應(yīng)用程序需要自己完成丟包重發(fā)、消息排序等工作。
目的主機(jī)收到數(shù)據(jù)包后,如何經(jīng)過各層協(xié)議棧最后到達(dá)應(yīng)用程序呢?其過程如下圖所示:
以太網(wǎng)驅(qū)動(dòng)程序首先根據(jù)以太網(wǎng)首部中的“上層協(xié)議”字段確定該數(shù)據(jù)幀的有效載荷(payload,指除去協(xié)議首部之外實(shí)際傳輸?shù)臄?shù)據(jù))是IP、ARP還是RARP協(xié)議的數(shù)據(jù)報(bào),然后交給相應(yīng)的協(xié)議處理。假如是IP數(shù)據(jù)報(bào),IP協(xié)議再根據(jù)IP首部中的“上層協(xié)議”字段確定該數(shù)據(jù)報(bào)的有效載荷是TCP、UDP、ICMP還是IGMP,然后交給相應(yīng)的協(xié)議處理。假如是TCP段或UDP段,TCP或UDP協(xié)議再根據(jù)TCP首部或UDP首部的“端口號(hào)”字段確定應(yīng)該將應(yīng)用層數(shù)據(jù)交給哪個(gè)用戶進(jìn)程。IP地址是標(biāo)識(shí)網(wǎng)絡(luò)中不同主機(jī)的地址,而端口號(hào)就是同一臺(tái)主機(jī)上標(biāo)識(shí)不同進(jìn)程的地址,IP地址和端口號(hào)合起來標(biāo)識(shí)網(wǎng)絡(luò)中唯一的進(jìn)程。
雖然IP、ARP和RARP數(shù)據(jù)報(bào)都需要以太網(wǎng)驅(qū)動(dòng)程序來封裝成幀,但是從功能上劃分,ARP和RARP屬于鏈路層,IP屬于網(wǎng)絡(luò)層。雖然ICMP、IGMP、TCP、UDP的數(shù)據(jù)都需要IP協(xié)議來封裝成數(shù)據(jù)報(bào),但是從功能上劃分,ICMP、IGMP與IP同屬于網(wǎng)絡(luò)層,TCP和UDP屬于傳輸層。
網(wǎng)絡(luò)編程基礎(chǔ)
什么是socket?
- socket可以看成是用戶進(jìn)程與內(nèi)核網(wǎng)絡(luò)協(xié)議棧的編程接口。
- socket不僅可以用于本機(jī)的進(jìn)程間通信,還可以用于網(wǎng)絡(luò)上不同主機(jī)的進(jìn)程間通信。
IPv4套接口地址結(jié)構(gòu)通常也稱為“網(wǎng)際套接字地址結(jié)構(gòu)”,它以“sockaddr_in”命名,定義在頭文件<netinet/in.h>中
struct sockaddr_in {
uint8_t sin_len; //4
sa_family_t sin_family; //4
in_port_t sin_port; //2
struct in_addr sin_addr; //4
char sin_zero[8]; //8
};
- sin_len:整個(gè)sockaddr_in結(jié)構(gòu)體的長度,在4.3BSD-Reno版本之前的第一個(gè)成員是sin_family.
- sin_family:指定該地址家族,在這里必須設(shè)為AF_INET
- sin_port:端口
- sin_addr:IPv4的地址;
- sin_zero:暫不使用,一般將其設(shè)置為0
通用地址結(jié)構(gòu)用來指定與套接字關(guān)聯(lián)的地址。
struct sockaddr {
uint8_t sin_len;
sa_family_t sin_family;
char sa_data[14]; //14
};
- sin_len:整個(gè)sockaddr結(jié)構(gòu)體的長度
- sin_family:指定該地址家族
- sa_data:由sin_family決定它的形式。
網(wǎng)絡(luò)字節(jié)序
- 大端字節(jié)序(Big Endian)
最高有效位(MSB:Most Significant Bit)存儲(chǔ)于最低內(nèi)存地址處,最低有效位(LSB:Lowest Significant Bit)存儲(chǔ)于最高內(nèi)存地址處。 - 小端字節(jié)序(Little Endian)
最高有效位(MSB:Most Significant Bit)存儲(chǔ)于最高內(nèi)存地址 處,最低有效位(LSB:Lowest Significant Bit)存儲(chǔ)于最低內(nèi)存地址處。 - 主機(jī)字節(jié)序
不同的主機(jī)有不同的字節(jié)序,如x86為小端字節(jié)序,Motorola 6800為大端字節(jié)序,ARM字節(jié)序是可配置的。 - 網(wǎng)絡(luò)字節(jié)序
網(wǎng)絡(luò)字節(jié)序規(guī)定為大端字節(jié)序。
字節(jié)序轉(zhuǎn)換函數(shù)
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
說明:在上述的函數(shù)中,h代表host;n代表network s代表short;l代表long。
地址轉(zhuǎn)換函數(shù)
#include <netinet/in.h>
#include <arpa/inet.h>
int inet_aton(const char *cp, struct in_addr *inp);
in_addr_t inet_addr(const char *cp);
char *inet_ntoa(struct in_addr in);
套接字類型
- 流式套接字(SOCK_STREAM)
提供面向連接的、可靠的數(shù)據(jù)傳輸服務(wù),數(shù)據(jù)無差錯(cuò),無重復(fù)的發(fā)送,且按發(fā)送順序接收。 - 數(shù)據(jù)報(bào)式套接字(SOCK_DGRAM)
提供無連接服務(wù)。不提供無錯(cuò)保證,數(shù)據(jù)可能丟失或重復(fù),并且接收順序混亂。 - 原始套接字(SOCK_RAW)
圖書推薦
??從大師視角詮釋計(jì)算常識(shí)
做一個(gè)穿行于數(shù)字世界與現(xiàn)實(shí)世界的智者
計(jì)算機(jī)和通信系統(tǒng),以及由它們所實(shí)現(xiàn)的許多事物遍布我們周圍。其中一些在日常生活中隨處可見,比如筆記本電腦、手機(jī)和互聯(lián)網(wǎng)。今天,在任何公共場所,都會(huì)看到許多人在使用手機(jī)查詢交通路線、購物以及和朋友聊天。與此同時(shí),大部分計(jì)算機(jī)世界卻是隱形的,比如電子設(shè)備、汽車、火車、飛機(jī)、電力系統(tǒng)和醫(yī)療設(shè)備中的計(jì)算機(jī)。這種幾乎不可見的基礎(chǔ)設(shè)施對我們產(chǎn)生了巨大的影響,如果沒有這些在后臺(tái)運(yùn)行的系統(tǒng),我們所處的現(xiàn)代社會(huì)將會(huì)坍塌。大多數(shù)情況下,它們確實(shí)在正確地執(zhí)行任務(wù),一切運(yùn)轉(zhuǎn)正常。但我們會(huì)不時(shí)得到令人不安的警示,這發(fā)生在當(dāng)這些系統(tǒng)出現(xiàn)問題時(shí),或當(dāng)我們聽到各種系統(tǒng)正在悄悄收集、共享,甚至濫用這些數(shù)據(jù)時(shí)。
下面推薦一本書,該書對計(jì)算機(jī)和通信系統(tǒng)如何工作進(jìn)行了詳細(xì)和透徹的解釋。本書展示了當(dāng)今的計(jì)算和通信世界是如何運(yùn)作的,從硬件到軟件,再到互聯(lián)網(wǎng)和Web。
書名:《普林斯頓計(jì)算機(jī)公開課》
作者:布萊恩·W. 柯尼漢(Brian W. Kernighan)
譯者:戴開宇
出版社:機(jī)械工業(yè)出版社
內(nèi)容簡介:從1999年開始,每年秋天,普林斯頓大學(xué)都有一門大受歡迎的計(jì)算機(jī)課程。Kernighan教授正是這門課程的主講,他從科學(xué)家視角詮釋的計(jì)算常識(shí),使來自各個(gè)專業(yè)的學(xué)生都深深受益。
基于課程講義,Kernighan教授撰寫了D is for Digital(2011)和本書第1版(2017),而今,這本書再度全面升級。書中沿用簡潔易懂的風(fēng)格來講解硬件、軟件、通信和數(shù)據(jù)知識(shí),并更新了大量時(shí)事案例來討論隨著疫情的變化和在線工作的增加而帶來的隱私和安全問題。這使得本書不僅成為每個(gè)人暢游數(shù)字世界的科普指南,更折射出作者的人文關(guān)懷和思想鋒芒。文章來源:http://www.zghlxwxcb.cn/news/detail-484822.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-484822.html
到了這里,關(guān)于計(jì)算機(jī)網(wǎng)絡(luò)通信過程的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!