日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python学习笔记(十 三)、网络编程

發布時間:2023/12/10 python 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python学习笔记(十 三)、网络编程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近心情有點兒浮躁,難以靜下心來

?

  Python提供了強大的網絡編程支持,很多庫實現了常見的網絡協議以及基于這些協議的抽象層,讓你能夠專注于程序的邏輯,而無需關心通過線路來傳輸比特的問題。

1 幾個網絡模塊

  1.1 模塊socket

  網絡編程中的一個基本組件是套接字(socket)。套接字基本上是一個信息通道,兩端各有一個程序。這些程序可能位于(通過網絡相連接的)不同的計算機上,通過套接字向對方發送消息。在Python中,大多數網絡編程都隱藏了模塊socket的基本工作原理,不與套接字直接交互。

  套接字分為兩類:服務端套接字和客戶端套接字。創建服務端套接字后,讓它等待連接請求的到來。這樣,它將在某個網絡地址(由IP地址和端口號組成)處監聽,知道客戶端套接字建立連接,還必須處理多個連接;而客戶端套接字只需連接,完成任務后再斷開連接即可。

  套接字是模塊socket中socket類的實例。實例化套接字時最多可指定三個參數:一個地址族(默認為socket.AF_INET);是流套接字(socket.SOCK_STREAM,默認設置)還是數據報套接字(socket.SOCK_DGRAM);協議(使用默認值0就好)。

  服務器套接字先調用方法bind,在調研方法listen來監聽特定的地址。然后,客戶端套接字通過調用方法connect并提供bind時指定的地址來連接服務端。這里的地址是一個格式為(host, port)的元祖,其中host是主機名,port是端口號。方法listen接收一個參數——代辦任務清單的長度(即最多可有多少個連接在隊列中等待接納,到達這個數量后將開始拒絕連接)。

  服務端套接字開始監聽后,就可接收客戶端連接,使用方法accept來等待連接。這個方法將阻斷(等待)到客戶端連接到來為止(有點類似與yield關鍵字),然后返回一個格式為(client, address)的元組,其中client為客戶端套接字,而address為地址。服務端能以其認為合適的方式處理客戶端連接,然后再次調用accept以等待新連接到來。

  為傳輸數據,套接字提供了兩個方法:send-發送和recv-接收(表示receive),這兩個方法都是接收或發送字節流數據。

  簡單的服務器:

import socket#創建套接字 s = socket.socket()#獲取主機名 host = socket.gethostname() #端口號 port = 8080 address = (host, port) #創建連接 s.bind(address)#監聽:最大連接數為5 s.listen(5) while True:#等待連接client, addr = s.accept()#接收消息str = bytes.decode(client.reve(1024))#發送消息client.send(str.encode('我是服務端!','utf-8'))

  簡單的客服端:

import socket s = socket.socket()#連接服務端地址 host = socket.gethostname() port = 8080 address = (host, port) #連接 s.connect(address) #接收消息 str = bytes.decode(s.reve(1024)) #發送消息 s.sent(str.encode('我是客戶端!','utf-8'))

  1.2 模塊urllib和urllib2

  模塊urllib和urllib2,由名字可知,它們讓你能夠通過網絡訪問文件,就像這些文件位于你的計算機中一樣。只需一個簡單的函數調用,就幾乎可將統一資源定位符(URL)可指向的任何動作作為程序的輸入。這兩個模塊一般用于下載網頁、從中提取信息自動生成研究報告等。對于簡單的操作,urllib綽綽有余,如果要實現HTTP身份驗證或Cookie,或編寫擴展來處理自己的協議,urllib2可能是更好的選擇。

  1.2.1 打開遠程文件

  使用模塊urllib.request中的函數urlopen來打開遠程文件,只能進行讀取操作。如:

  from urllib.request import urlopen

  page = urlopen('www.baidu.com')

  如果連接到網絡,變量page將包含一個類似于文件的對象,這個對象與你所連接的地址相關聯。urlopen返回類似于文件的對象支持方法clost、read、readline和readlines,還支持迭代等。

  1.2.2 獲取遠程文件

  函數urlopen返回一個類似于文件的對象,可從中讀取數據。如果要讓urllib替你下載文件,并將其副本存儲在本地,可使用urllib.request中的函數urlretrieve。這個函數返回一個格式為(filename, headers)的元祖,其中filename是本地文件的名稱(由urllib自動創建),而headers包含一些有關遠程文件的信息。如果要給下載的副本指定文件名,可通過函數urlretrieve的第二個參數來指定。

  函數格式為: urlretrieve(url, filename=None, reporthook=None, data=None),函數urlretrieve將url中的內容存儲在filename中,如果filename沒有指定,下載的副本將放在某個臨時位置,可使用函數open來打開。但使用完畢后,你可能想將其刪除,以免暫用磁盤空間,可調用函數urlcleanup來替你完成清除工作。

  1.2.3 其他模塊

  Python標準庫提供了一些與網絡相關的模塊,如下(只列舉了一些常用的):

  cgi          ? 基本的CGI文件

  asyncore        異步套接字處理程序

  asynchat        包含補充asyncore的功能

  Cookie        ? ?Cookie對象操作,主要用于服務器

  cookielib        客戶端Cookie支持

  email         ? 電子郵件支持

  ftplib          FTP客戶端模塊

  httplib         ? HTTP客戶端模塊

  mailbox        ? 讀取多種郵箱格式

  urlparse        ? 用于解讀URL

2 SocketServer及相關的類

  模塊SocketServer是標準庫提供的服務器框架的基石,這個框架包括BaseHTTPServer、SimpleHTTPServer、CGIHTTPServer、SimpleXMLRPCServer和DocXMLRPCServer等服務器,它們在基本服務器的基礎上添加了各種功能。

  SocketServer包含4個基本的服務器:TCPServer(支持TCP套接字流)、UDPServer(支持UDP套接字流)、UnixStreamServer和UnixDatagramServer。后面3個不常用。

  使用模塊SocketServer編寫服務器時,大部分代碼都位于請求處理中。每當服務器收到客戶端的連接請求時,都將實例化一個請求處理程序,并對其調用各種處理方法來處理請求。基本請求處理程序類BaseRequestHandler將所有操作都放在一個方法中——服務器自動調用的方法handle。這個方法可通過書信self.request來訪問客戶端套接字。如果處理的是流(TCPServer時很可能如此),可使用StreamRequestHandler類,它包含另外兩個屬性:self.rfile(用于讀取)和self.wfile(用于寫入)。你可以使用這兩個類似與文件的對象來與客戶端通信。

  模塊SocketServer還包含很多其他的類,它們為HTTP服務器提供基本的支持,以及XML-RPC支持。

  

from socketserver import TCPServer,StreamRequestHandlerclass Handle(StreamRequestHandler):def handle(self):addr = self.request.getpeername()print("addr:", addr)self.wfile.write("謝謝")server = TCPServer(('',1234), Handle) server.serve_forever()

3 多個連接

  處理多個連接的主要方式有三種:分叉(forking)、線程化和異步I/O。通過結合使用SocketServer中的混合類和服務器類,很容易實現分叉和線程化。但是,分叉占用資源較多,且在客戶端很多時可伸縮性不高;而線程化可能帶來同步問題。并且Windows不支持分叉,分叉是UNIX術語。

  3.1 使用SocketServer實現分叉和線程化

  使用框架SocketServer創建分叉或線程化服務器非常簡單,一般僅當方法handle需要很長時間才能執行完畢是,分叉和線程化才能提供有效幫助。創建如下:

  1.分叉服務器

from socketserver import TCPServer,StreamRequestHandler,ForkingMixInclass Server(ForkingMixIn, TCPServer):passclass Handle(StreamRequestHandler):def handle(self):addr = self.request.getpeername()print("addr:", addr)self.wfile.write("謝謝")server = Server(('',1234), Handle) server.serve_forever()

  2.線程化服務器

from socketserver import TCPServer,StreamRequestHandler,ThreadingMixInclass Server(ThreadingMixIn, TCPServer):passclass Handle(StreamRequestHandler):def handle(self):addr = self.request.getpeername()print("addr:", addr)self.wfile.write("謝謝")server = Server(('',1234), Handle) server.serve_forever()

  3.2 使用select和poll實現異步I/O

  當服務器與客戶端通信時,來自客戶端的數據可能時斷時續。如果使用了分叉和線程化,這就不是問題:因為一個進程(線程)等待數據時,其他進程(線程)可繼續處理其客戶端。然而,另一種做法是只處理正在通信的客戶端。你甚至無需不斷監聽,只需監聽后將客戶端加入隊列即可。

  這就是框架asyncore/asynchat 和 Twisted采取的方法。這種功能的基石是函數select或poll(只支持UNIX系統)。這兩個函數都位于模塊select中,其中poll的可伸縮性更高。

  函數select接收三個必不可少的參數和一個可選參數,其中前三個參數為序列,而第四個參數為超時時間(單位為秒)。這些序列包含文件描述符整數(也可以是包含返回文件描述符整數的方法fileno),表示我們正在等待的連接。這三個序列分別表示需要輸入和輸出以及發生異常(錯誤等)的連接。如果沒有指定超時時間,select將阻斷(即等待)到有文件描述符準備就緒;如果指定了超時時間,select將最多阻斷指定的秒數;如果超時時間為0,select將不斷輪詢(即不阻斷)。select返回三個序列(即一個長度為3的元祖),其中每個序列都包含相應參數中處于活動狀態的文件描述符。

  如下所示,一個使用select的簡單服務器:import socket, select

s = socket.socket() host = socket.gethostname() port = 8080 s.bind((host,port)) s.listen(5) inputs = [s] while True:
   # 方法select返回三個參數,通過序列解包賦值rs, ws, es
= select.select(inputs, [], [])for r in rs:if r is s:c, addr = s.accept()print("addr:", addr)inputs.append(c)else:try:data = r.reve(1024)discon = not dataexcept socket.error:discon = Trueif discon:
          # 1.getpeername():用于獲取與某個套接字關聯的外地協議地址
         # 2.getsockname():用于獲取與某個套接字關聯的本地協議地址
print(r.getpeername(), 'discon')inputs.remove(r)else:print(data)

  方法poll 使用起來比select容易。調用poll 時,將返回一個輪詢對象。你可以使用方法register 向這個對象注冊文件描述符(或包含方法fileno的對象)。注冊后可使用方法unregister 將它們刪除。注冊對象(如套接字)后,可調用其方法poll(它接受一個可選的超時時間參數)。這將返回一個包含(fd, event)元祖的列表(可能為空),其中fd為文件描述符,event是發生的事件。event是一個位掩碼,這意味著它是一個整數,其各個位對應于不同的事件。各種事件是用select 模塊中的常量表示的,如下表。要檢查指定的位是否為1 (即是否發生了相應的事件),可使用按位與運算符( & ):

  if event & select.POLLIN: pase

  事件名              描述

  POLLIN             ? 文件描述符中有需要讀取的數據

  POLLPRI            ? ?文件描述符中有需要讀取的 緊急數據

  POLLOUT          ? ? ? ? ?文件描述符為寫入數據做好了準備

  POLLERR            ? 文件描述符出現了錯誤狀態

  POLLHUP            ? 掛起。連接已斷開

  POLLNVAL             無效請求。連接未打開

  

  下面是一個使用poll的簡單服務器:

import socket, select s = socket.socket()host = socket.gethostname() port = 8080 s.bind((host, port))fdmp = {s.fileno(): s}s.listen(5) p = select.poll() p.register(s) while True:events = p.poll()for fd, event in events:if fd in fdmp:c, addr = s.accept()print("addr:", addr)p.register(c)fdmp[c.fileno()] = celif event & select.POLLIN:data = fdmp[fd].recv(1024)if not data:print(fdmp[fd].getpeername(),"discon")p.unregister(fd)del fdmp[fd]else:print(data)

4 Twisted

  這是Twisted Matrix Laboratories 開發的一個框架,功能豐富而復雜,支持大多數主要的網絡協議??蚣躎wisted是異步的,因此效率和可伸縮性都非常高。對很多自定義網絡應用程序來說,使用Twisted來開發可能是最佳選擇。

轉載于:https://www.cnblogs.com/www-123456/p/10638868.html

總結

以上是生活随笔為你收集整理的python学习笔记(十 三)、网络编程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。