网络编程+Python
一、網絡編程(模塊:socket,from socket import *):
1. 網絡層的IP地址可以唯一標識網絡中的主機,傳輸層的“協議+端口”則可以唯一標識主機中應用程序(進程)。
2. 套接字socket:實現網絡中不同主機間應用程序間的通信。類似電話插孔。
3. 服務器:提供服務; 客戶端:發出請求,請求服務,一般需要綁定端口,服務器才能向其發數據。
服務器有:打印機服務器(硬件服務器),文件服務器(硬件服務器),數據庫服務器(軟件服務器),web服務器(軟件服務器)
? ? 硬件服務器需要有專用的外圍設備,如磁盤驅動器,打印機等。軟件服務器提供主要的服務包括程序執行,數據傳輸檢索,更新等。
? ? 常見的架構有C/S(Client/Server)(客戶機/服務器)和B/S(Browser/Server)Browser/Server(瀏覽器/服務器)架構。
4. UDP與TCP的區別:
? ? UDP(用戶數據報協議),一個無連接的簡單的面向數據報的傳輸層協議,TFTP(簡單文件傳輸協議)就是基于UDP實現的。
? ? 特點是:通信時不需要建立連接,可實現廣播傳輸,不提供可靠性,即不保證目的地址能收到數據,且沒有超時重傳機制,傳輸數據時有大小限制,每個數據報在64kb以內
? ? 優點是:傳輸速度快
? ? 適用情況:多點通信和實時的數據業務,如:視頻,QQ,語音廣播,局域網中的視頻會議系統,保證連貫性和速度即可。
? ? TCP(傳輸控制協議),提供面向連接的、可靠的字節流服務。
? ? 特點是:clien和server交換數據前必須先建立可靠的連接(三次握手),提供超時重發,校驗數據等,保證數據能傳到目的地址。
? ? 適用情況:點對點通信。
5. 單播:點對點? ? ? ? 多播:一對多? ? ? 廣播:一對所有,廣播地址的最后一位為255
6. OSI模型:應用層,表示層,會話層,傳輸層,網絡層,數據鏈路層,物理層?
? ? 四層網絡模型:應用層(應用進程),傳輸層(UDP,TCP),網絡層(IP, ICMP,IGMP, ARP,RARP),鏈路層(網絡接口,負責報文傳輸)
? ? 說明:
? ? IP地址:標記邏輯地址? ?MAC地址:標記實際轉發數據時的設備地址,通常由分配廠商的代碼和適配器接口擴展標識符組成的。
? ? ICMP : ping網絡時使用的協議? ? ? ? ARP:地址解析協議,獲取一個電腦的網卡號,Mac地址時使用? ? ?
? ? RARP:逆地址解析協議, 使只知道自己硬件地址的主機能夠知道其IP地址,用的較少。
? ? DNS:域名解釋器? ?NET:網絡地址轉換器
? ? netmask:子網掩碼,和IP地址一起確認網絡號或主機號
不同局域網間通信過程中,IP地址不變,mac地址會在通信中改變,模擬過程可使用Cisco Packet Tracker工具(開源)查看。?
7. 長連接和短連接的區別:
? ? 長連接:client和server先建立連接,然后不斷開,再進行報文發送和接收,適用于頻繁連接的需求,常用于P2P通信
? ? ?建立連接——數據傳輸——(保持連接)——數據傳輸——關閉連接,可省去頻繁的進行tcp建立和關閉,節約時間,但占用資源,如視頻,數據庫連接
? ? 短連接:?client每次發送報文都要建立連接,通信完就斷開連接。常用于一點對多點通信,c/s通信,web網站的http服務一般是短連接,節省資源。
? ? 建立連接——數據傳輸——關閉連接——建立連接——數據傳輸——關閉連接,如網站訪問。
8. UDP網絡通信過程:
? ?創建UDP客戶端過程:
1 #coding=utf-8 2 from socket import * 3 # import socket 4 # udpsocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 5 #1.創建套接字 6 udpsocket = socket(AF_INET, SOCK_DGRAM) 7 #2. 準備接收方的地址 8 bindaddr = ('', 9090) 9 udpsocket.bind(bindaddr) 10 sendAddr = ('192.168.137.2 ', 8080) 11 #3.從鍵盤獲取數據: 12 sendData = raw_input("請輸入要發送的數據:") 13 #4. 發送數據到指定電腦 14 udpsocket.sendto(sendData.encode("gb2312"), sendAddr) 15 recvData = udpsocket.recvfrom(1024) 16 print(recvData[0].decode("gb2312")) 17 print(recvData[1][0].decode("gb2312")) 18 print(recvData[1][1]) 19 #5.關閉套接字 20 udpsocket.close()? 創建udp服務器過程:
#coding=utf-8 from socket import * #1.創建套接字 udpsocket = socket(AF_INET, SOCK_DGRAM) #2. 綁定服務器IP和port bindaddr = ('192.168.137.2', 8080) udpsocket.bind(bindaddr)#3.接收數據 while Ture:recvData = udpsocket.recvfrom(1024) print(recvData[0].decode("gb2312")) #打印接收到的數據#4.關閉套接字 udpsocket.close()? 基于UDP的多線程聊天,一臺電腦的話可以使用NetAssist網絡助手(開源)模擬實現,打開多個窗口,每個窗口綁定不同的端口,模擬不同的應用程序,從而模擬多用戶收發數據:
1 # -*- coding: utf-8 -*- 2 from threading import Thread 3 #import chardet 4 from socket import * 5 # import sys 6 # reload(sys) 7 # sys.setdefaultencodig('utf-8') 8 #多線程完成聊天 9 #1. 線程recvData 收數據 10 def recvData(udpsocket): 11 while True: 12 recvinfo = udpsocket.recvfrom(1024) 13 print(recvinfo) 14 print(" %s, %s"%(recvinfo[1], recvinfo[0].decode("gb2312"))) 15 16 #2. 線程sendData發數據 17 def sendData(udpsocket): 18 sendAddr = ('192.168.137.2 ', 8080) 19 while True: 20 sendinfo = raw_input() 21 #udpsocket.sendto(sendinfo, sendAddr) 22 udpsocket.sendto(sendinfo.decode('utf-8').encode("gb2312"), sendAddr) 23 24 #udpsocket = None #后面存的如果是對象,就定義None 25 26 27 #創建線程 28 def main(): 29 # global udpsocket 30 udpsocket = socket(AF_INET, SOCK_DGRAM) 31 setaddr = ("", 9090) 32 udpsocket.bind(setaddr) 33 recvdata = Thread(target=recvData, args=(udpsocket,)) 34 senddata = Thread(target=sendData, args=(udpsocket,)) 35 recvdata.start() 36 senddata.start() 37 senddata.join() 38 recvdata.join() 39 udpsocket.close() 40 41 42 if __name__ == "__main__": 43 main()說明: 單工:只能單向發送。 半雙工:同一時刻只有一端可以發送/接收? ? 全雙工:同一時刻兩端均可接收/發送。 本例實現的是全雙工。
9. 創建TCP過程:
? ? (1)創建tcp套接字:tcpsocket = socket(AF_INET, SOCK_STREAM)
(2)綁定IP和端口:? bindaddr = ('192.168.137.2', 8080)? ? ??
? ? tcpsocket.bind(bindaddr)
? ? (3)監聽連接listen:tcpsocket.listen(5)
? ? ?(4)接收客戶端連接:cs = tcpsocket.accpet()
? ? ?(5)接收或發送數據,用的是recv和send函數與udp不一樣。
? ? ?(6)關閉客戶端套接字:cs.close()
(7)關閉服務器套接字:tcpsocket.close()
10. TCP三次握手:
(1)客戶端發送一個包含SYN的TCP報文給服務器,該報文中包含客戶端使用的端口及TCP連接的初始序號等信息, SYN, seq =xxx。
(2)服務器接收到SYN報文后,返回一個SYN+ACK報文表示客戶端的請求被接收,SYN, seq=y, ACK=xxx+1
(3)客戶端收到SYN+ACK報文后,返回ACK確認包,ACK =y+1
?11.? 常見網絡攻擊:
(1)拒絕式服務攻擊(DOS):一直向服務器發送SYN,但是不反饋ACK,直到服務器listen隊列滿,從而導致正常用戶無法訪問服務器。TCP連接資源耗盡,停止響應正常請求,如SYN洪水攻擊。
(2)DNS攻擊:一種是DNS服務器劫持,即更改域名解析結果,將用戶引向錯誤的地址。另一種是DNS欺騙,即用假的DNS應答來欺騙用戶。
(3)ARP攻擊:在服務器和客戶端中間插入,攔截服務器發送信息,自己保存后再轉發給客戶端。
12. HTTP狀態碼含義:以2開頭的狀態代碼表示成功,以3開頭的狀態代碼表示由于各種不同的原因用戶請求被重定向到了其他位置,以4開頭的狀態代碼表示客戶端存在某種錯誤,以5開頭的狀態代碼表示服務器遇到了某個錯誤。常見的:200 :OK? ? ?302: Found? ? 400 :Bad Request? 404:Not Found? ?410:Gone? ? 500:Internal Server Error? 501 Not Implemented
二、python基礎知識
1. 基本數據類型有:列表,字符串,元組,字典,數字,還有集合和日期。 元組與列表的區別:元組不可更改,列表可變。
2. 列表常用方法:append,insert,extend, count, reverse, sort(原列表更改), sorted(原列表的副本更改), remove, pop
3.? 字符串常用方法:join(“分隔符”.join(object)),split,strip(刪除兩邊的空格),replace,zfill(n)(左側以0填充n個字符)
4. range與xrange區別:range生成一個列表,而xrange生成一個生成器對象,在數據量大的情況下,xrange性能更好一些,不用開辟大量內存存儲列表中的元素,從而節約內存
5. 多態:一類事物有多種形態,如動物,有貓,狗,鳥等。封裝:對象的具體實現等打包成整體,外界不用知道如何實現的也能能使。 繼承:子類繼承父類,減少重寫代碼
6. 迭代器和生成器:具有next方法的容器稱為迭代器,含有yeild語句的容器稱為生成器,生成器一定是迭代器,迭代器不一定是生成器,生成器保存的是算法,每次調用生成器的時候,都會返回到上次中斷的地方(yeild語句處)。生成器會自動創建next和__iter__方法,簡潔高效,節省內存。可以使用isinstance()判斷一個對象是否是可迭代對象,需要使用到collections模塊中的Iterable,如isinstance({},Iterable),返回布爾類型。
舉例:列表生成式? x = [ 2*a for a in range(5) ]? ?生成器:x = (2*a for a in range(5) )? next(x)?
7. 閉包和裝飾器:
閉包:一個函數內再定義一個函數,內層函數會引用外層函數作用域的變量,則內部函數就是閉包。作用:提高代碼的可復用性,減少代碼的可移植性。(如果不使用閉包,用兩個獨立的函數,則可能需要重復說明某些參數)
舉例說明:
1 def bibao(num1): 2 num1 += 10 3 def func(num2): 4 print("%d + %d = %d"%(num1, num2, num1+num2)) #內層函數有用到外層函數的局部變量,該內層函數就是一個閉包 5 return num1+num2 6 return func 7 8 9 ret = bibao(10) 10 print ret(20)裝飾器:格式:@函數名 (語法糖)緊挨著需要裝飾的函數上方。作用:引入日志,函數執行時間統計,執行函數前預處理和執行后的清理功能,權限校驗等場景,緩存。舉例說明如下:
1 #encoding=utf-8 2 from time import ctime, sleep 3 def timeFun(pre): 4 def innerTimeFun(func): 5 def wrappedFunc(): 6 print ("%s wrote at %s"%(pre, ctime())) 7 return func() 8 return wrappedFunc 9 return innerTimeFun 10 11 @timeFun("Mrs Peng") 12 def hello(): 13 print("hello!") 14 15 hello()分析:程序先運行15行,發現有11行的裝飾器,11行程序處理步驟為:先 執行timeFun("Mrs Peng"),程序跳到第3行函數,第3行函數返回innerTimeFun這個函數的引用,再執行@innerTimeFun,用其對hello()函數進行裝飾,等價于 hello =?innerTimeFun(hello),運行結果如下:
下面是使用裝飾器去統計函數執行時間的例子:
1 #encoding=utf-8 2 from time import time, sleep 3 """函數執行時間統計""" 4 def timeCount(func): 5 def intime(): 6 starttime = time() 7 func() 8 curtime = time() 9 usetime = curtime - starttime 10 return usetime 11 return intime 12 13 14 @timeCount 15 def test(): 16 print("Now it is beginning!") 17 sum = 0 18 for i in range(10000): 19 sum += i 20 print(sum) 21 print ("Now it is over!") 22 23 24 print(test())? 8. is 和==的區別:is 是比較兩個引用是否指向同一個對象,而==是看左右兩邊的值是否一樣。
9.? 深拷貝和淺拷貝:淺拷貝僅僅是拷貝了對象的引用,可以類似理解成windows桌面的快捷方式,一個應用可以創建多個快捷方式,但都指向同一個應用。淺拷貝,更改任何一個引用的內容,則所有指向該對象的引用及對象本身都會同步被更改,即你動我也動。另外,淺拷貝對于可變對象(如列表,字典等)來說,拷貝了對象的引用,且id號會變,而對不可變對象如元組等來說,就是拷貝引用,id號不變。深拷貝,是完全的拷貝對象,即重新開辟一個內存地址,該地址存儲的類型及內容與原對象一樣,只是地址不一樣,若改變其中某個,另一個不會隨之改變,即你動我不動。舉例說明:列表的復制,使用分片來實現復制,是深拷貝;將某變量x賦值給變量y,屬于淺拷貝,x,y均指向同一對象。如下:
a = [1,3,5,7,9] b = a[:] c = a a.append(11) print a, id(a) print b, id(b) print c, id(c)運行結果如下,從結果中可知,b和a的id不一樣,內容也不一樣,是深拷貝。a與c一樣,屬于淺拷貝。如果需要使用copy和deepcopy函數需要從模塊copy中導入這兩個方法。?
?10. 進制間的轉換:如:將十進制轉換成二進制、八進制、十六進制:bin(18),oct(18), hex(18). 將二進制、八進制、十六進制轉換成十進制:int("ob10010",2)、int("022",8)、int("0x12",16)。IP地址轉換為十進制時會使用到。
11. python內存管理:
垃圾回收:
(1)小整數對象池:[-5, 257]區間為小整數,這些整數對象是提前建立好,不會被垃圾回收,小整數和單個字符共用對象,常駐內存。
(2)單個單詞,默認開啟Intern機制,共用對象,引用計數,當引用計數為0時,則銷毀。
(3)字符串(含空格),沒有開啟intern機制,不共用對象,引用計數為0,則銷毀。
? ?python采用的GC機制(垃圾回收機制),主要是引用計數為主,隔代回收為輔。引用計數機制的缺點:維護引用計數消耗資源,同時循環引用會導致內存泄漏。引用計數就是指當對象的引用計數為0時則清理該對象的內存,隔代回收是指python會檢測循環引用的零代、一代和二代鏈表,每有一個引用被銷毀,引用計數減1,一旦零代鏈表的計數為0的時候,就徹底銷毀其內存。
?12. python常用模塊:
(1)Time:時間相關的,常用方法:ctime, asctime,time,sleep。
(2)re:正則表達式模塊,常用方法:match,findall, serach,sub, split。
(3)Random:隨機數模塊,常用方法:range,xrange,shuffle
(4)threading(Multiprocessing):多線程(多進程)模塊,常用方法:Thread,start, join(等待子進程結束后父進程才結束), run
(5)heapq:堆操作模塊,常用方法:heappush, heappop, nlargest
(6)OS:操作系統模塊,創建子進程方法:folk , getpid。
13. 進程和線程:
多任務:操作系統同時運行多個任務。
程序:代碼寫好,但沒運行的時候稱為程序。
進程(multiprocessin模塊中Process創建,進程池:Pool):正在運行的代碼。是操作系統進行資源分配和調度的基本單位,每個進程都獨享系統的一部分資源,進程間的資源不共享,各進程間的變量是相互獨立的。進程間通信方式:消息,隊列,信號量,一個進程可以包含多個線程,同一個進程中的不同線程共享該進程的環境資源。
線程(threading中的Thread):線程是進程的一個執行單元或實體,是CUP調度和分派的基本單位,線程間的共享變量,線程相比進程需要的資源較少(PC(程序計數器),寄存器和棧)。多線程程序執行順序是不確定的。五種狀態:新建、就緒、運行、等待、死亡。
區別:一個程序中至少有一個進程,一個進程中至少有一個線程。
線程所需的資源比進程少,使得多線程程序的并發性高。(并發:看上去是一起執行,任務數>核數。并行:真正的一起運行)
進程執行中擁有獨立的內存資源,進程間變量相互獨立,而多個線程是共享內存,共享變量的,從而提高了程序的運行效率。
線程不能獨立執行,必須存在進程中。進程的開銷比線程多。
可參考https://blog.csdn.net/afei__/article/details/80468265,很形象。
進程間通信舉例如下:
1 #encoding=utf-8 2 from multiprocessing import Process, Queue 3 import os, time, random 4 """進程間通信-消息隊列""" 5 def writeDates(q): 6 for value in ["a", "b","c"]: 7 q.put(value) 8 time.sleep(random.random()) 9 10 def readDates(q): 11 while True: 12 if not q.empty(): 13 value = q.get() 14 print("%s"%value) 15 time.sleep(random.random()) 16 else: 17 break 18 19 20 if __name__=="__main__": 21 q = Queue() #創建Queue隊列 22 writeProcess = Process(target=writeDates, args=(q,)) 23 readProcess = Process(target=readDates, args=(q,)) 24 writeProcess.start() 25 writeProcess.join() 26 readProcess.start() 27 readProcess.join()14. GIL:全局解釋器,此鎖能保證每次只有一個線程真正在運行。
15. 同步:協同步調,按預先的先后次序進行運行,A做完,B接著開始。如:A進程(線程)運行到一定程度,需要B進程(線程)執行完才能執行。這就是同步。
當多個線程同時修改某個共享數據時,需要同步控制,常見的同步控為互斥鎖。
16. 死鎖:舉例說明,A擁有鎖a,B擁有鎖b,A需要B釋放鎖b才能繼續運行,B需要A釋放鎖a才能進行運行,相互持有鎖而不釋放,等待對方釋放,這就是死鎖。避免死鎖的方法:銀行家算法,或添加超時等待,即看門狗。
? ? ? 互斥鎖:A擁有鎖a,相應資源“鎖定”,B不能對其進行操作。Lock模塊,acquire方法獲取鎖,release釋放鎖。
17. 生產者和消費者模式
生產者:生產數據的線程。消費者:消費數據的線程。生產者消費者模式是通過一個容器(阻塞隊列相當于一個緩沖區)來解決的是生產與消費速度不相匹配(強耦合)的問題。
18. re模塊:
(1)match函數:語法格式match(str1, str2)從str2中匹配是否含有str1,若有測返回對象,無返回None。注意是匹配str2是否以str1開頭,如:str1 = abc? str2=babc? 則返回None,顯示未匹配成功。若str2=abcd,則匹配成功,可用group顯示結果。
(2)search?函數:語法格式search(str1, str2)從str2中匹配是否含str1,與match的區別是,search是從從頭開始匹配,只要匹配到有str1即可。
(3)findall 函數:遍歷匹配,可以匹配出str2中所有包含str1的字符串,返回一個列表。
貪婪和非貪婪:所謂貪婪就是盡可能多的匹配,非貪婪就是盡可能匹配少的字符。非貪婪操作符?用在“?”,“+”,“*”后面,要求正則匹配的越少越好。
1 #encoding=utf-8 2 import os 3 import re 4 str = "how How are how you" 5 destr = "how" 6 # match匹配,字符串開頭。匹配到返回匹配對象,沒匹配到,返回None。 7 matchRes = re.match(destr, str) 8 if matchRes is not None: 9 print("match: %s"%matchRes.group()) 10 # search匹配,匹配首次搜到到字符串destr,匹配到返回匹配對象,沒匹配到,返回None。 11 str2 = "How how are how you" 12 searchRes = re.search(destr, str2) 13 if searchRes is not None: 14 print("search: %s"%searchRes.group()) 15 # findall匹配,匹配到所有結果以列表的形式返回。 16 findallRes = re.findall(destr, str, re.I) 17 print("findall: %s"%findallRes) 18 #finditer匹配,匹配到所有結果返回的是一個迭代器。 19 finditerRes = re.finditer(destr, str, re.I) 20 print("finditer:"), 21 try: 22 while True: 23 g = finditerRes.next() 24 print("%s"%g.group()),#python 2.x不換行用"," 25 # print("finditer: %s" % g.group(), end=" ")#python 3.x不換行:end = " " 26 except StopIteration: 27 pass?
轉載于:https://www.cnblogs.com/pengpp/p/9762980.html
總結
以上是生活随笔為你收集整理的网络编程+Python的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSS3 选择器 基本选择器介绍
- 下一篇: [转]Android Studio系列教