Python核心編程與應(yīng)用 課件 【ch08】網(wǎng)絡(luò)編程_第1頁
Python核心編程與應(yīng)用 課件 【ch08】網(wǎng)絡(luò)編程_第2頁
Python核心編程與應(yīng)用 課件 【ch08】網(wǎng)絡(luò)編程_第3頁
Python核心編程與應(yīng)用 課件 【ch08】網(wǎng)絡(luò)編程_第4頁
Python核心編程與應(yīng)用 課件 【ch08】網(wǎng)絡(luò)編程_第5頁
已閱讀5頁,還剩37頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

Python核心編程與應(yīng)用網(wǎng)絡(luò)編程第八章新工科·數(shù)據(jù)科學(xué)與大數(shù)據(jù)系列01網(wǎng)絡(luò)編程TCP網(wǎng)絡(luò)編程TCP01TCP/IPTCP/IP即傳輸控制和網(wǎng)絡(luò)協(xié)議,是網(wǎng)絡(luò)使用中最基本和最重要的通信協(xié)議,對互聯(lián)網(wǎng)中通信各方進行標準和方法的規(guī)定,保證網(wǎng)絡(luò)及時、完整地傳輸數(shù)據(jù)信息。TCP/IP是一個四層的體系結(jié)構(gòu):應(yīng)用層、傳輸層、網(wǎng)絡(luò)層和數(shù)據(jù)鏈路層,如圖8-1所示其中,最關(guān)鍵的是傳輸控制協(xié)議TCP和網(wǎng)際協(xié)議P。TCP位于傳輸層,負責(zé)保證端到端的可靠通信,P位于網(wǎng)絡(luò)層,負責(zé)數(shù)據(jù)分組的發(fā)送和接收,包括挑選合適的傳輸路徑。網(wǎng)絡(luò)編程TCP01Socket抽象層為了方便開發(fā)網(wǎng)絡(luò)應(yīng)用程序,在應(yīng)用層與TCP/IP協(xié)議族中間加入了軟件抽象層:Socket(套接字),如圖8-2所示。Socket是一組接口,用于隱藏復(fù)雜的TCP/IP協(xié)議族,程序員通過一組簡單的接口就可以方便地訪問TCP/IP協(xié)議族,進而組織數(shù)據(jù)并開發(fā)各種網(wǎng)絡(luò)應(yīng)用程序。套接字可以看作不同主機間的進程進行雙方通信的端點,構(gòu)成了單個主機及整個網(wǎng)絡(luò)的編程界面。打個比方,用一條數(shù)據(jù)線把移動硬盤與計算機連接時,數(shù)據(jù)線的一端連接移動硬盤,另一端連接計算機,就可以在移動硬盤與計算機之間直接傳輸數(shù)據(jù)了。數(shù)據(jù)線與設(shè)備相連接的USB接口相當于套接字,而這條數(shù)據(jù)線就是連接。套接字的表示方法為:Socket=(IP地址:端口號)即點分十進制的IP地址后寫上端口號,中間用“:”或“,”隔開。每個傳輸層的連接被通信兩端的兩個端點唯一地確定,如果IP地址是,端口號是23,那么套接字是(:23)。網(wǎng)絡(luò)編程TCP01Socket抽象層網(wǎng)絡(luò)編程TCP01套字節(jié)類型(1)流套接字流套接字(Sock_Stream)使用TCP進行數(shù)據(jù)的傳輸,用于提供面向連接、可靠的數(shù)據(jù)傳輸服務(wù),將保證數(shù)據(jù)能夠?qū)崿F(xiàn)無差錯、無重復(fù)發(fā)送,并按順序接收。(2)數(shù)據(jù)報套接字數(shù)據(jù)報套接字(Sock_Dgram)使用UDP進行數(shù)據(jù)的傳輸,提供一種無連接的服務(wù),并不能保證數(shù)據(jù)傳輸?shù)目煽啃?,?shù)據(jù)有可能在傳輸過程中丟失或出現(xiàn)數(shù)據(jù)重復(fù),且無法保證順序地收到數(shù)據(jù)。網(wǎng)絡(luò)編程TCP01Socket工作步驟通信時,網(wǎng)絡(luò)應(yīng)用程序?qū)⑿枰獋鬏數(shù)男畔懭胨谥鳈C的Socket中,該Socket通過傳輸介質(zhì)將這段信息傳送到另一臺主機的Socket中。服務(wù)器端和客戶端的工作步驟如圖8-3所示。網(wǎng)絡(luò)編程TCP01Socket工作步驟通信時,網(wǎng)絡(luò)應(yīng)用程序?qū)⑿枰獋鬏數(shù)男畔懭胨谥鳈C的Socket中,該Socket通過傳輸介質(zhì)將這段信息傳送到另一臺主機的Socket中。服務(wù)器端和客戶端的工作步驟如圖8-3所示。02網(wǎng)絡(luò)編程UDP網(wǎng)絡(luò)編程UDP02服務(wù)器端①創(chuàng)建地址:P地址和端口。②創(chuàng)建Socket對象。udpsock=socket.socket(socket.AF_INET,socket.SOCKDGRAM,0)其中,socket.AF_INET表示IPv4地址socket.SOCK_DGRAM表示數(shù)據(jù)報套接字,protocol表示協(xié)議,默認為0。上述三個參數(shù)在UDP編程中不能省略。③綁定地址:bind()④收發(fā)數(shù)據(jù)。接收數(shù)據(jù):data,addr=recvfrom(BUFSIZE)網(wǎng)絡(luò)編程UDP02服務(wù)器端發(fā)送數(shù)據(jù):sendto(data,addr)⑤同關(guān)閉Socket:close()與TCP編程相比,UDP編程少了listen(監(jiān)聽)和Accept(接收)兩個步驟,更簡單,效率更高,但是降低了可靠性。網(wǎng)絡(luò)編程UDP02客戶端①創(chuàng)建地址:服務(wù)器的I地址和端口。②創(chuàng)建Socket對象:udpsock=socket.socket(socket,AF_INET,socket.SOCK_DGRAM,0)③收發(fā)數(shù)據(jù):sendto(data,addr)data,addr=recvfrom(BUFSIZE)④關(guān)閉Socket:close()03網(wǎng)絡(luò)編程SocketServer網(wǎng)絡(luò)編程SocketServer03在前面使用Socket的過程中先設(shè)置了socket類型,再依次調(diào)用bind()、listen()、accept(),最后用while循環(huán)讓服務(wù)器不斷接受請求。這些可以通過SocketServer包來簡化。socketserver模塊是在socket模塊基礎(chǔ)上的一層封裝,簡化了網(wǎng)絡(luò)服務(wù)程序的編寫,可以實現(xiàn)并發(fā),也是Pvthon標準庫中很多服務(wù)器框架的基礎(chǔ)。SocketServer包提供了4個基本服務(wù)類,如圖8-10所示。網(wǎng)絡(luò)編程SocketServer03ThreadingTCPServer是一個繼承自BaseServer和ThredingMixIn的子類,具備處理TCP(Socket模塊)和多線程的能力。本節(jié)學(xué)習(xí)的SocketServer模塊來自ThreadingTCPServer類。先自定義一個類,取名MyServer,是一個繼承自socketserverBaseRequestHandler的類重寫其handle方法并將這個類和服務(wù)器的P地址端口作為參數(shù)傳遞給ThreadingTCPServer類,然后手動啟動ThreadingTCPServer。ThreadingTCPServer類就是一個連接客戶端和服務(wù)器的管道,封裝了Socket中的監(jiān)聽和請求這兩個步驟。再編寫一個用SocketServer實現(xiàn)多線程會話的程序。利用SocketServer,在內(nèi)部使用IO多路復(fù)用和多線程/進程機制,實現(xiàn)并發(fā)處理多個客戶端請求Socket服務(wù)器端會話的功能。每個客戶端請求連接到服務(wù)器時,SocketServer服務(wù)器端都會創(chuàng)建一個線程或者進程,專門負責(zé)處理當前客戶端的所有請求04多線程多線程04進程進程是程序的一個執(zhí)行實例,每個運行中的程序可以同時創(chuàng)建多個進程,但至少一個每個進程提供執(zhí)行程序所需的所有資源:虛擬的地址空間,可執(zhí)行的代碼,操作系統(tǒng)的接口,安全的上下文(記錄啟動該進程的用戶和權(quán)限等),唯一的進程ID,環(huán)境變量,優(yōu)先級類最小和最大的工作空間(內(nèi)存空間)。進程可以包含線程,并且每個進程必須有至少一個線程。每個進程啟動時先產(chǎn)生一個線程,即主線程,主線程會再創(chuàng)建其他子線程。多線程04線程線程,有時被稱為輕量級進程,是程序執(zhí)行流的最小單元。標準的線程包含線程ID、當前指令的地址(PC)、寄存器集合和堆棧組成。線程是進程中的一個實體,是被系統(tǒng)獨立調(diào)度和分派的基本單位。線程不獨立擁有系統(tǒng)資源,但可與同屬一個進程的其他線程共享該進程所擁有的全部資源。每個應(yīng)用程序都至少有一個進程和一個線程,單個程序通過同時運行多個線程,完成不同的工作。多線程04進程與線程的區(qū)別①同一個進程內(nèi)的線程共享內(nèi)存空間,不同進程的內(nèi)存空間相互獨立②同一個進程內(nèi)的所有線程共享數(shù)據(jù),不同進程的數(shù)據(jù)相互獨立。③對主線程的修改會影響其他線程的行為,但是父進程的修改(除了刪除不會影響其他子進程。④線程是一個上下文的執(zhí)行指令,進程是與運算相關(guān)的一簇資源。違約同一個進程的線程之間可以直接通信,進程之間的交流需要借助中間代理來實現(xiàn)。⑥創(chuàng)建新的線程很容易,但是創(chuàng)建新的進程需要對父進程做一次復(fù)制。⑦一個線程可以操作同一進程內(nèi)的其他線程,進程只能操作其子進程。⑧線程啟動速度快,進程啟動速度慢。多線程04Threading模塊常用方法Threading模塊是Python中專門處理線程的內(nèi)建模塊,封裝了相關(guān)屬性和方法,常用方法如下。currentthread:返回當前線程activecount:返回當前活躍的線程數(shù),一個主線程和多個子線程。get_ident:返回當前線程ID。enumerater:返回當前活動線程對象列表。mainthread:返回主線程對象。多線程04創(chuàng)建線程創(chuàng)建自定義線程類有兩種方法:通過繼承父類threadingThread創(chuàng)建,這時需要重寫thread類中的init和rn方法,或者直接使用Threading模塊創(chuàng)建,更加簡便。用Threading模塊創(chuàng)建線程【例8-11】用threading.Thread方法直接創(chuàng)建子類。importthreadingimporttimeimportrandomdef

jogging():time.sleep(random.random())print(threading.current_thread().name,"isrunning...")多線程04創(chuàng)建線程if__name__=’__main__’:foriinrange(5):t=threading.Thread(target=jogging) #直接創(chuàng)建子類t.start()運行結(jié)果:Thread-4isrunning..Thread-1isrunning..Thread-2isrunning..Thread-3isrunning...Thread-0isrunning..這樣寫程序更加簡潔明了。多線程04守護線程在多線程執(zhí)行過程中,各線程獨立執(zhí)行任務(wù),不等待其他線程。若把所有子線程都變成主線程的守護線程,當主線程結(jié)束后,守護線程也會隨之結(jié)束,整個程序隨之退出。設(shè)置守護線程的方法如下:setDaemon(True)05線程鎖線程鎖05線程鎖的基本含義線程鎖用于鎖定資源,當需要獨占某一資源時就用該鎖鎖定。系統(tǒng)中存在多個線程鎖,任何一個鎖都可以用于鎖定某個資源,好比用不同的鎖都可以把相同的一個箱子鎖住一樣?!纠?-15】不加鎖產(chǎn)生的臟數(shù)據(jù)。importthreadingimporttimenumber=0defplus():globalnumberfor_inrange(1000000):number+=1print(f'{threading.current_thread().name}:(number}')線程鎖05線程鎖的基本含義if__name__==’__main__’:threading.Thread(target=plus).start()

#開啟線程,通用plus函數(shù)threading.Thread(target=plus)start()

#開啟線程,通用plus函數(shù)time.sleep(1)

#主線程等待1秒print(f'{threading.mainthread().name}:number})運行結(jié)果:Thread-1:981361Thread-2:1220878MainThread:1220878線程鎖05線程鎖的基本含義按以往的思路,線程1(Thread-1)執(zhí)行plus()函數(shù),number計數(shù)結(jié)果是1000000,線程2(Thread-2)再執(zhí)行plus()函數(shù)number計數(shù)結(jié)果應(yīng)該是2000000然后主線程(MainThread)結(jié)束,計數(shù)結(jié)果應(yīng)該是2000000,結(jié)果卻顯示1220878,相去甚遠。原因就在于現(xiàn)在是多線程的運行環(huán)境,系統(tǒng)開啟了三個線程,它們彼此獨立,異步執(zhí)行,但共用了全局變量number,兩個線程在爭用同一個變量時發(fā)生數(shù)據(jù)混亂,產(chǎn)生了臟數(shù)據(jù),即數(shù)據(jù)出錯了,此時需要加一把互斥鎖。線程鎖05Lock互斥鎖互斥鎖是一種獨占鎖,即同一時刻只有一個線程可以訪問共享的資源,使用資源時先加鎖再訪問,使用完畢釋放鎖。【例8-16】Lock互斥鎖舉例。importthreadingimporttimenumber=0lock=threading.Lock()

#創(chuàng)建互斥鎖defplus(lk):globalnumberlk.acquire()for_inrange(1000000):number+=1線程鎖05Lock互斥鎖print(f'{threading.current_thread().name]:number]')lk.release()

#釋放鎖if__main__==’__main__’#線程在訪問數(shù)據(jù)的過程中不允許其他線程訪問,所以加上互斥鎖Lockthreading.Thread(target=plus,args=(lock,)).start()threading.Thread(target=plus,args=(lock,)).start()time.sleep(1)print(f'{threading.mainthread().name}:{number}')運行結(jié)果:Thread-1:1000000Thread-2:2000000MainThread:2000000運行結(jié)果完全正確。注意互斥鎖的使用方法:先初始化鎖對象,再將鎖當作參數(shù)傳遞給任務(wù)函數(shù)plus(),在任務(wù)中加鎖,使用后釋放,這兩個線程共享全局變量number,需要瓦斥使用。06文件IO文件IO06文件讀寫Python內(nèi)置了open方法,用于打開一個文件對象,才可以對文件進行讀寫操作。open方法的返回值是一個fle對象,可以將它賦值給一個變量。其基本語法格式為:f=open(filename,mode)filename:要訪問的文件名;mode:打開文件的模式,如表8-1所示。文件IO06擴展模式在模式w、a、r基礎(chǔ)上加上“+”,構(gòu)成w+、a+、r,意味著在原來的基礎(chǔ)上增加讀或?qū)懙墓δ?,如r+就是在讀基礎(chǔ)上增加寫的功能。注意:①對于w+模式,在讀寫前會清空文件的內(nèi)容;②對于a模式,永遠只能在文件的末尾寫入;③對于r+模式,也就是讀寫模式,配合seek和tell方法,可以實現(xiàn)更多操作。【例8-21】打開文的模式。f=open('log','a+')

#文件追加方式f.write("hello")f.write("\n")f.write("python")f.write("\n")f.write("world")f.close()文件IO06文件對象讀操作根據(jù)讀的方式文件讀操作分為三種:①read(size)方法讀取size大小的數(shù)據(jù);②readline方法,讀取一行內(nèi)容;③readlines方法,讀取所有行內(nèi)容。(1)read(size)方法read(size)方法讀取一定大小的數(shù)據(jù),然后作為字符串或字節(jié)對象返回。size是一個可選的數(shù)字類型參數(shù),用于指定讀取的數(shù)據(jù)量。當size忽略或者為負值時,該文件的所有內(nèi)容都將被讀取并返回。(2)readline方法從文件中讀取一行內(nèi)容,換行符為’\n’,如果返回一個空字符串,說明已經(jīng)讀取到最后一行。這種方法通常是讀一行,并且不能回退,只能前進,讀過的行不能重復(fù)讀。(3)readlines方法readlines方法將文件中所有的行全部讀入,每行作為一個元素加入列表并返回這個列表。文件IO06文件對象寫操作先打開文件,指定模式為寫操作:f=open('about.txt','w')然后使用write方法寫文件:f.write(str)用于將字符串或字節(jié)流寫入文件。寫動作可以多次重復(fù)進行,但都是在內(nèi)存中操作,并不會立刻寫回硬盤,直到執(zhí)行close方法后,才會將所有的寫入操作反映到硬盤上。在此過程中,如果想把內(nèi)存中的內(nèi)容直接保存到硬盤上,就可以使用fflush方法。文件IO06文件讀寫位置操作用ope方法打開文件時,文件指針定位在文件開頭位置,文件總是在指針所在位置處讀或?qū)懀S著讀寫操作的進行,文件指針會不斷地移動,如果需要獲得當前文件指針的位置或移動指針到指定位置,就要用到下面兩個方法。(1)tell方法f.tell()方法返回文件讀寫指針的位置,用從文件頭開始到當前位置的字節(jié)數(shù)來表達。(2)seek方法f.seek(offsetfromwhat)方法用于改變指針位置:offset是偏,fom_what是參照位置。例如,seek(x,0),從起始位置即文件首行首字符開始往后移動X個字符;seek(x,1),表示從當前位置往后移動個字符;seek(-x,2),表示從文件的結(jié)尾往前移動x個字符。07Pathlib

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論