當(dāng)前位置:首頁(yè) > 通信技術(shù) > 通信網(wǎng)絡(luò)
[導(dǎo)讀] 進(jìn)行程序開發(fā)的同學(xué),無(wú)論Web前端開發(fā)、Web后端開發(fā),還是搜索引擎和大數(shù)據(jù),幾乎所有的開發(fā)領(lǐng)域都會(huì)涉及到網(wǎng)絡(luò)編程。比如我們進(jìn)行Web服務(wù)端開發(fā),除了Web協(xié)議本身依賴網(wǎng)絡(luò)外,通常還需要連接數(shù)據(jù)

進(jìn)行程序開發(fā)的同學(xué),無(wú)論Web前端開發(fā)、Web后端開發(fā),還是搜索引擎和大數(shù)據(jù),幾乎所有的開發(fā)領(lǐng)域都會(huì)涉及到網(wǎng)絡(luò)編程。比如我們進(jìn)行Web服務(wù)端開發(fā),除了Web協(xié)議本身依賴網(wǎng)絡(luò)外,通常還需要連接數(shù)據(jù)庫(kù),而數(shù)據(jù)庫(kù)連接通常是通過網(wǎng)絡(luò)連接數(shù)據(jù)庫(kù)服務(wù)器,或者數(shù)據(jù)庫(kù)集群,如果負(fù)載太高還要搞個(gè)緩存集群。

我們?cè)谏蠈W(xué)的時(shí)候基本學(xué)了網(wǎng)絡(luò)編程和網(wǎng)絡(luò)協(xié)議。但兩者之間的具體關(guān)系可能有些摸不到頭腦。這里我們首先重點(diǎn)介紹2個(gè)概念,一個(gè)概念是網(wǎng)絡(luò)編程,另外一個(gè)是協(xié)議。

我們知道網(wǎng)絡(luò)協(xié)議是一個(gè)分層的協(xié)議族,也就是是有一組協(xié)議構(gòu)成,從下往上各自負(fù)責(zé)各自的功能。那什么是協(xié)議呢?協(xié)議的字面意思是共同計(jì)議,商議。簡(jiǎn)單的理解其實(shí)就是多方進(jìn)行溝通的規(guī)定。而網(wǎng)絡(luò)協(xié)議其實(shí)就是在網(wǎng)絡(luò)中多個(gè)計(jì)算節(jié)點(diǎn)進(jìn)行交互、溝通的規(guī)定。如果根我們?nèi)粘I顚?duì)比的話,協(xié)議可以理解為語(yǔ)言,比如漢語(yǔ)普通話。兩個(gè)人交流如果都用不通話,那么彼此都能理解對(duì)方表達(dá)的意圖。例如,一個(gè)人用四川話,而另外一個(gè)用浙江話,那溝通起來(lái)估計(jì)幾乎不太可能。網(wǎng)絡(luò)協(xié)議也是一樣的,通過對(duì)數(shù)據(jù)格式的規(guī)范化,從而使計(jì)算機(jī)之間能夠彼此明確對(duì)方的意圖。

下面本文介紹一下網(wǎng)絡(luò)編程,網(wǎng)絡(luò)編程也稱為socket編程,socket通常譯作“套接字”,但原意其實(shí)意譯應(yīng)該為”接口“。也就是操作系統(tǒng)提供給開發(fā)人員進(jìn)行網(wǎng)絡(luò)開發(fā)的API接口。這套接口通??梢詤?shù)的調(diào)整支持多種協(xié)議,包括TCP、UDP和IP等等。下面本文從套接字編程和協(xié)議兩方面分別詳細(xì)的進(jìn)行介紹。

網(wǎng)絡(luò)編程

為了便于理解,本文先從具體的內(nèi)容開始,也就是通過一個(gè)實(shí)例介紹一下網(wǎng)絡(luò)編程是怎么回事。

本文將以TCP協(xié)議為例介紹網(wǎng)絡(luò)編程和協(xié)議之前的關(guān)系。為了簡(jiǎn)單,便于理解,本文以Python為例進(jìn)行介紹,如果不了解Python編程語(yǔ)言關(guān)系也不大,下面代碼很容易理解。我們知道在網(wǎng)絡(luò)通信中無(wú)論是BS架構(gòu)還是CS架構(gòu),通常分為服務(wù)端和客戶端,只不過BS架構(gòu)中的瀏覽器就是客戶端。因此,本文的示例也包含服務(wù)端和客戶端2部分的代碼。代碼功能很簡(jiǎn)單,就是實(shí)現(xiàn)客戶端和服務(wù)端發(fā)送字符串。

客戶端服務(wù)端通信模型

這個(gè)代碼清單是服務(wù)端的代碼,這段代碼的作用就是在服務(wù)端的某個(gè)端口建立監(jiān)聽,并等待客戶端建立連接。完成連接建立后,等待客戶端發(fā)送數(shù)據(jù),并將數(shù)據(jù)回傳給客戶端。

#!/usr/bin/env python3#-*- coding:utf-8 -*-from socket import *from time import cTImehost = ‘’port = 12345buffsize = 2048ADDR = (host,port)# 創(chuàng)建一個(gè)基于TCP協(xié)議的套接字tcTIme = socket(AF_INET,SOCK_STREAM)tcTIme.bind(ADDR)# 在指定的地址和端口監(jiān)聽tcTIme.listen(3)while True:print(‘Wait for connection 。..’) tctimeClient,addr = tctime.accept()print(“Connection from :”,addr) while True: data = tctimeClient.recv(buffsize).decode() if not data: breaktctimeClient.send((‘[%s] %s’ % (ctime(),data)).encode())tctimeClient.close()tctimeClient.close()

閱讀服務(wù)端的代碼可以看出主要包括,socket、bind、listen、accept、recv和send幾個(gè)。其中值得關(guān)注的是listen和accept,兩者分別用于監(jiān)聽端口和接受客戶端的連接請(qǐng)求。

下面代碼清單是客戶端的實(shí)現(xiàn),這里特別的地方是有一個(gè)connect函數(shù),該函數(shù)實(shí)現(xiàn)與服務(wù)端建立連接。

#!/usr/bin/env python3#-*- coding:utf-8 -*-from socket import *HOST =‘localhost’PORT = 12345BUFFSIZE=2048ADDR = (HOST,PORT)tctimeClient = socket(AF_INET,SOCK_STREAM)tctimeClient.connect(ADDR)while True:data = input(“》”) if not data: breaktctimeClient.send(data.encode()) data = tctimeClient.recv(BUFFSIZE).decode() if not data: breakprint(data)tctimeClient.close()

通過上述示例代碼可以看出服務(wù)端通常是被動(dòng)的,而客戶端則要主動(dòng)一些。服務(wù)端程序建立對(duì)某個(gè)端口的監(jiān)聽,等待客戶端的連接請(qǐng)求??蛻舳讼蚍?wù)端發(fā)送連接請(qǐng)求,不出意外的情況下連接建立成功,這時(shí)客戶端和服務(wù)端之前就可以互發(fā)數(shù)據(jù)了。當(dāng)然,在實(shí)際生產(chǎn)環(huán)境中意外是經(jīng)常的,因此從協(xié)議和接口層面,需要處理各種意外,本文在協(xié)議部分將詳細(xì)介紹。

另外,本文實(shí)現(xiàn)了一個(gè)基本的客戶端和服務(wù)端通信的程序,這個(gè)模式的通信在實(shí)際生產(chǎn)中幾乎不再使用。在實(shí)際生產(chǎn)中為了提高數(shù)據(jù)傳輸和處理的效率,通常采用異步模式,這些內(nèi)容超出了本文的介紹范圍,后續(xù)文章會(huì)逐漸介紹。

TCP協(xié)議詳解

前文說了網(wǎng)絡(luò)協(xié)議是網(wǎng)絡(luò)中不同計(jì)算機(jī)信息通信的語(yǔ)言,為了實(shí)現(xiàn)交互,這個(gè)語(yǔ)言就需要有一定的格式。本文以TCP協(xié)議為例進(jìn)行介紹。

TCP協(xié)議是一個(gè)可靠的傳輸協(xié)議,其可靠性表現(xiàn)在2方面,一方面是保證數(shù)據(jù)包可以按照發(fā)送的順序到達(dá),另外一方面是保證數(shù)據(jù)包一定程度的正確性(后文詳解為什么是一定程度上的正確性)。其可靠性的實(shí)現(xiàn)則基于2點(diǎn)技術(shù),一點(diǎn)是具有一個(gè)CRC校驗(yàn),這樣如果數(shù)據(jù)包中的某些數(shù)據(jù)出現(xiàn)錯(cuò)誤可以通過該校驗(yàn)和發(fā)現(xiàn);另外一點(diǎn)是每個(gè)數(shù)據(jù)包都有一個(gè)序號(hào),這樣就能保證數(shù)據(jù)包的順序性,如果出現(xiàn)錯(cuò)位的數(shù)據(jù)包可以請(qǐng)求重發(fā)。

既然說到了格式,那我們先看一下TCP數(shù)據(jù)包的數(shù)據(jù)格式。如下圖是TCP數(shù)據(jù)包的格式,包括原端口、目的端口、序列號(hào)和標(biāo)識(shí)位等等內(nèi)容,內(nèi)容有些多,看著可能有點(diǎn)眼花。但從大的方面理解,這個(gè)數(shù)據(jù)包其實(shí)只包含2部分內(nèi)容,一個(gè)是包頭,另外一個(gè)則是具體需要傳輸?shù)臄?shù)據(jù)。在TCP協(xié)議的控制邏輯中,包頭起著最為關(guān)鍵的作用,它是TCP協(xié)議中諸如建立連接、斷開連接、重傳和錯(cuò)誤校驗(yàn)等各種特性的基礎(chǔ)。

包頭的其它信息的含義都比較明了,本文僅僅介紹幾個(gè)標(biāo)志位(URG、ACK、PSH、RST、SYN和FIN)的含義。具體含義如下:

ACK: 確認(rèn)序號(hào)有效。

RST:重置連接

SYN:發(fā)起一個(gè)新連接

FIN:釋放一個(gè)連接

連接的建立TCP在具體傳輸數(shù)據(jù)之前需要建立連接。這里的連接并不是物理連接,物理連接基于底層的協(xié)議已經(jīng)建立完成,而且TCP建立連接也是要假設(shè)底層連接已經(jīng)成功,TCP的連接其實(shí)是一個(gè)虛擬的,邏輯的連接。簡(jiǎn)單粗暴的理解,就是客戶端和服務(wù)端分別記錄了各自接受到的數(shù)據(jù)包的序號(hào),并且將自身設(shè)置為某種狀態(tài)。在TCP協(xié)議中,連接的建立通常成為3次握手,從字面的概念可以看出,連接的建立需要經(jīng)過3次確認(rèn)的過程。

TCP協(xié)議3次握手的過程如圖所示,初始狀態(tài)客戶端和服務(wù)端都處于關(guān)閉狀態(tài)。主要過程分為3步:

客戶端發(fā)送預(yù)連接數(shù)據(jù)包: TCP的連接是由客戶端主動(dòng)發(fā)起建立,客戶端會(huì)發(fā)送一個(gè)數(shù)據(jù)包(報(bào)文)給服務(wù)端,需要注意的是數(shù)據(jù)包中的SYN標(biāo)識(shí)位為1。我們前文已經(jīng)介紹,如果SYN為1,則說明為建立連接的數(shù)據(jù)包。同時(shí),在該數(shù)據(jù)包中包含一個(gè)請(qǐng)求序列號(hào),該序列號(hào)也是建立連接的依據(jù)。

服務(wù)端回復(fù)連接確認(rèn): 服務(wù)端確認(rèn)可以建立連接(服務(wù)端不一定可以建立連接,因?yàn)橄到y(tǒng)中套接字的數(shù)量是有限的)的情況下會(huì)向客戶端發(fā)送一個(gè)應(yīng)答數(shù)據(jù)包。在應(yīng)答數(shù)據(jù)包中會(huì)將ACK標(biāo)志位設(shè)置為1,表示為服務(wù)端應(yīng)答數(shù)據(jù)包。同時(shí),在應(yīng)答數(shù)據(jù)包中會(huì)設(shè)置請(qǐng)求序列號(hào)和應(yīng)答序列號(hào)的值,具體參考圖3.

客戶端回復(fù)連接確認(rèn): 最后,客戶端再次發(fā)送一個(gè)連接確認(rèn)數(shù)據(jù)包,告訴服務(wù)端連接建立成功。

從上面流程可以看出,連接的建立需要經(jīng)過多次交互,這就是我們?nèi)粘V兴f的建立連接是高成本的操作。在實(shí)際生產(chǎn)環(huán)境中,為了應(yīng)對(duì)這個(gè)問題,會(huì)減少連接建立的頻度,通常的做法是建立連接池,傳輸數(shù)據(jù)時(shí)直接從連接池中獲取連接,而不是新建連接。

有人可能覺得可以對(duì)建立連接的過程進(jìn)行優(yōu)化,比如將客戶端最后一次的確認(rèn)取消掉,覺得這個(gè)沒有卵用。對(duì)于正常情況確實(shí)沒有多大的作用,這里主要是應(yīng)對(duì)異常情況。因?yàn)榫W(wǎng)絡(luò)拓?fù)涫欠浅?fù)雜的,特別是在廣域網(wǎng)中,有著數(shù)不清的網(wǎng)絡(luò)節(jié)點(diǎn),因此會(huì)出現(xiàn)各種異常情況。因此,TCP協(xié)議在設(shè)計(jì)的時(shí)候必須要保證異常情況下的可靠性。

我們這里舉一個(gè)例子,就是連接請(qǐng)求超時(shí)的情況。假設(shè)客戶端向服務(wù)端發(fā)送一個(gè)連接請(qǐng)求,由于各種原因,請(qǐng)求一直沒有到達(dá)服務(wù)端,因此服務(wù)端也就沒有回復(fù)連接確認(rèn)消息??蛻舳诉B接超時(shí),因此客戶端重新發(fā)送一個(gè)連接請(qǐng)求到服務(wù)端,這次比較順利,很快到達(dá)了,并且順利建立了連接。之后,前一個(gè)數(shù)據(jù)包經(jīng)過長(zhǎng)途跋涉最終還是到了服務(wù)端,服務(wù)端也向客戶端發(fā)送了回復(fù)數(shù)據(jù)包,服務(wù)端認(rèn)為連接是建立成功的,并且會(huì)維持連接。但客戶端層面認(rèn)為連接是超時(shí)的,因此將永遠(yuǎn)不會(huì)關(guān)閉該連接。這樣就會(huì)造成服務(wù)端有殘留的資源,從而造成服務(wù)端資源浪費(fèi),久而久之可能會(huì)導(dǎo)致服務(wù)端無(wú)新連接資源可用。

另外一個(gè)需要說明的是客戶端和服務(wù)端的套接字都有相應(yīng)的狀態(tài),而且狀態(tài)會(huì)隨著連接的不同階段變化。初始狀態(tài)都是CLOSE,最終連接建立成功后都是ESTABLISHED,具體變化過程如圖3所示。后面本文會(huì)詳細(xì)介紹狀態(tài)變化情況。

傳輸數(shù)據(jù)完成連接建立之后,客戶端和服務(wù)端就可以進(jìn)行數(shù)據(jù)傳輸了。我們知道TCP是可靠的傳輸,那么傳輸?shù)目煽啃允峭ㄟ^什么來(lái)保證的呢?主要就是通過包頭中的校驗(yàn)和、請(qǐng)求序列號(hào)和應(yīng)答序列號(hào)(參考圖2)。

TCP數(shù)據(jù)內(nèi)容的可靠性是通過校驗(yàn)和保證的。TCP在發(fā)送數(shù)據(jù)時(shí)都會(huì)計(jì)算整個(gè)數(shù)據(jù)包的校驗(yàn)和,并存儲(chǔ)在包頭的校驗(yàn)和字段中。接收方會(huì)按照規(guī)則進(jìn)行計(jì)算,從而確認(rèn)接收到的數(shù)據(jù)是否是正確的。發(fā)送發(fā)計(jì)算校驗(yàn)和的流程大概如下:

把偽首部、TCP包頭和TCP數(shù)據(jù)分為16為的字,并把TCP包頭中的校驗(yàn)和字段置0

用反碼加法累加所有16位數(shù)字

對(duì)計(jì)算結(jié)果去反,將其填充到TCP包頭的校驗(yàn)和字段

接收方將所有原碼相加,高位疊加,如果全為1則表示數(shù)據(jù)正確,否則說明數(shù)據(jù)有錯(cuò)誤。

TCP數(shù)據(jù)包順序的可靠性是通過請(qǐng)求序列號(hào)和應(yīng)答序列號(hào)保證的。在數(shù)據(jù)傳輸中的每個(gè)請(qǐng)求都會(huì)有一個(gè)請(qǐng)求序列號(hào),而在接收方接收到數(shù)據(jù)后會(huì)發(fā)送一個(gè)應(yīng)答序列號(hào),這樣發(fā)送方就能知道數(shù)據(jù)是否被正確接收,而接收方也能知道數(shù)據(jù)是否出現(xiàn)亂序,從而保證數(shù)據(jù)包的順序性。

斷開連接TCP關(guān)閉連接分為4步,稱為4次揮手。連接的關(guān)閉不一定是在客戶端發(fā)起,服務(wù)端也可以發(fā)起關(guān)閉連接。關(guān)閉連接的過程如下:

發(fā)起方發(fā)送一個(gè)FIN置位的數(shù)據(jù)包,用來(lái)請(qǐng)求關(guān)閉發(fā)送方到接收方的連接

接收方發(fā)送一個(gè)應(yīng)答,ACK標(biāo)志位為1,確認(rèn)關(guān)閉。此時(shí)完成了發(fā)起方到接收方的連接,也即發(fā)送方無(wú)法再向接收方發(fā)送數(shù)據(jù),但接收方還可以向發(fā)送方發(fā)送數(shù)據(jù)。

接收方數(shù)據(jù)傳輸完成后向發(fā)起方發(fā)送一個(gè)FIN為1的包,表示請(qǐng)求斷開連接

發(fā)起方回復(fù)一個(gè)ACK包,確認(rèn)關(guān)閉成功

關(guān)閉連接流程示意圖

TCP是全雙工通信,因此關(guān)閉連接時(shí)需要雙向關(guān)閉連接。首先是關(guān)閉發(fā)起方關(guān)閉本端的連接,然后是關(guān)閉接收方在收到發(fā)起方的關(guān)閉請(qǐng)求后,除了回復(fù)關(guān)閉應(yīng)答外,還要確保數(shù)據(jù)傳輸完成后發(fā)起一個(gè)關(guān)閉連接的請(qǐng)求,保證雙向同時(shí)關(guān)閉。

截止到這里,本文介紹了基于TCP協(xié)議進(jìn)行網(wǎng)絡(luò)編程的主要內(nèi)容。當(dāng)然這個(gè)只是入門級(jí)的,如果需要真正理解TCP協(xié)議和網(wǎng)絡(luò)編程還需要學(xué)習(xí)很多內(nèi)容。后續(xù)本號(hào)將陸續(xù)介紹給大家。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉