国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

【循序漸進學Python】15.網絡編程

2019-11-14 17:32:26
字體:
來源:轉載
供稿:網友

Python 內置封裝了很多常見的網絡協議的庫,因此Python成為了一個強大的網絡編程工具,這里是對Python的網絡方面編程的一個簡單描述。

1. 常用的網絡設計模塊

在標準庫中有很多網絡設計相關的模塊,除了那些明確處理網絡事務的模塊外,還有很多模塊也是是和網絡相關的,下面是幾個常用的網絡設計模塊:

1.1 socket 模塊

socket 模塊是網絡編程中的基礎組件。socket 主要的作用就是作為兩個程序之間的“通信信道”,不同進程(不同主機)可以通過socket相互發送信息,以達到網絡通信的目的。socket 包括兩個部分:服務端和客戶端。服務端監聽端口號,等待客戶端發送的消息;而客戶端在需要發送信息是,連接服務端,將信息發送出去即可。下面是一個簡單的同步網絡編程的簡單示例:

這是Socket Server 部分:

import sockets = socket.socket()host = socket.gethostname()port = 8088s.bind((host,port))s.listen(5)while True:	c, addr = s.accept()	PRint 'Got connection from', addr	c.send('Thank you for connection')	c.close()

這是Socket Client 部分:

import sockets = socket.socket()host = socket.gethostname()port = 8088s.connect((host,port))print s.recv(1024)

運行時,請將對應的端口(這里是8088)添加到防火墻的InBound和OutBound的規則中。

1.2 urllib 和 urllib2 模塊

urlliburllib2 是Python標準庫中最強的的網絡工作庫。通過這兩個庫所提供的上層接口,使我們可以像讀取本地文件一樣讀取網絡上的文件。而且 urllib2 并不是 urllib 的升級版本(應該是一種補充),二者是不可相互替代的。

通過使用 urlliburlopen 函數可以很容易的打開遠程的文件,如下:

from urllib import urlopenwebpage = urlopen('http://m.survivalescaperooms.com/iprograming/')txt = webpage.readline(45)print txt  # !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 

也可以通過在通過在路徑的前面添加 file: 來訪問本地文件:

from urllib import urlopenwebpage = urlopen(r'file:D:/H/sr23upd/ADD_ABBR.txt')txt = webpage.readline(45)print txt 

如果你還可以通過 urllib 提供的 urlretrieve函數,來直接保存遠程文件副本:

from urllib import urlretrievewebpage = urlretrieve('http://m.survivalescaperooms.com/IPrograming/','C://temp.html')print type(webpage) # <type 'tuple'>

1.3 其他與網絡相關的模塊

除了 socket、urllib和urllib2這些模塊以外標準庫還有很多和網絡相關的模塊,下面的列表是其中的一部分:

===========================================================模塊                        描述===========================================================asynchat                asyncore的增強版本                 asyncore                異步socket處理程序                 cgi                     基本的CGI支持                      Cookie                  Cookie對象操作,主要用于服務器操作 cookielib               客戶端cookie支持                   email                   E-mail消息支持(包括MIME)           ftplib                  FTP客戶端模塊                      gopherlib               gopher客戶端博客                   httplib                 HTTP客戶端模塊                     imaplib                 IMAP4客戶端模塊                    mailbox                 讀取幾種郵件的格式                 mailcap                 通過mailcap文件訪問MIME配置        mhlib                   訪問MH郵箱                         nntplib                 NNTP客戶端模塊                     poplib                  POP客戶端模塊                      robotparser             支持解析Web服務器的robot文件       SimplexmlRPCServer      一個簡單的XML-RPC服務器            stmpd                   SMTP服務器模塊                     smtplib                 SMTP客戶端模塊                     telnetlib               Telnet客戶端模塊                   urlparse                支持解析URL                        xmlrpclib               XML-RPC的客戶端支持                 

2. SocketServer

SocketServer模塊是標準庫中很多其他服務器框架的基礎,這些服務器框架包括:BaseHTTPServer、SimpleHTTPServer、CGIHTTPServer、SimpleXMLRPCServer和DocXMLRPCServer,這些服務框架都是在基礎框架上增加了特定的功能。SocketServer包含了4個基本的類:

  • TCPServer,針對TCP的Socket
  • UDPServer,針對UDP數據報的Socket
  • UnixStreamServer
  • UnixDatagramServer

下面是一個基于SocketServer的簡單Socket Server端示例:

from SocketServer import TCPServer, StreamRequestHandlerclass Handler(StreamRequestHandler):	def handle(self):		addr = self.request.getpeername()		self.wfile.write('Thank you for connectiong')server = TCPServer(('',8088),Handler)server.serve_forever()

3. 多連接

一般情況下Socket中的Client端常常不止一個,想要使Socket Server端能同時處理多個Client的連接一般由三種主要的方法:

  • 分叉(forking)(windows 不支持)
  • 線程(threading)
  • 異步I/O(asynchronous I/O)

3.1 使用分叉

分叉(fork)是一個UNIX術語;當分叉一個進程(一個運行的程序)時,基本上時復制了它,并且分叉后的兩個進程都從當前執行的點繼續運行,并且每個進程都有自己的內存副本。一個進程(開始的那個)成為另一個進程的(復制的,也就是子進程)的父進程。在一個使用分叉的服務器中,每個客戶端連接都利用分叉創建一個子進程。父進程繼續監聽連接,同時子進程處理客戶端。當客戶端的請求結束時,子進程退出。分叉的進程是并行執行的,客戶端直接不必相互等待。分叉的缺點是比較耗費資源(每個分叉出來的進程都需要自己的內存)。下面是一個使用分叉創建Socket服務端的示例:

# --coding:utf-8--# 使用了分叉(fork),Windows系統不支持from SocketServer import TCPServer, ForkingMixIn, StreamRequestHandlerclass Server(ForkingMixIn, TCPServer):passclass Handler(StreamRequestHandler):	def handle(self):		addr = self.request.getpeername()		print 'Got connection from', addr		self.wfile.write('Thank you for connectiong')server = Server(('',1234),Handler)server.serve_forever()

3.2 使用線程

線程是輕量級的進程或子進程,所有的線程都存在于相同的進程(一個運行的程序)中,且共享內存。雖然使用多線程相對于分叉占用的資源較少,但是由于共享內存,所有必需要確保它們的變量不會沖突,或者是同一時間修改同一內容,這樣會造成混亂。這些問題可以歸結為同步問題。下面是使用多線程的一個簡單示例:

# --coding:utf-8--# 使用多線程from SocketServer import TCPServer, ThreadingMixIn, StreamRequestHandlerclass Server(ThreadingMixIn,TCPServer):passclass Handler(StreamRequestHandler):	def handle(self):		addr = self.request.getpeername()		print 'Got connection from', addr		self.wfile.write('Thank you for connection')server = Server(('',1234),Handler)server.serve_forever()

3.3 帶有 select 和 poll 的異步I/O

在Python中的異步I/O的基礎就是 select 模塊的 select 函數。標準庫中的 asyncoreasynchat 模塊對它們進行了進一步的包裝,可以從更高層次來處理異步I/O。poll 函數和 select 函數一樣,也屬于 select 模塊,這兩個函數的功能基本一樣,相對而言 poll 的伸縮性更好,但其職能在UNIX系統使用使用。

select 函數需要3個序列作為它的必選參數(輸入、輸出、異常情況),第四個參數是可選的,表示以秒為單位的超時時間。下面是一個使用 select 的簡單示例:

import socket, selects = socket.socket()host = socket.gethostname()port = 1234s.bind((host,port))s.listen(5)inputs = [s]while True:	rs, ws, es = select.select(inputs,[],[])	for r in rs:		if r is s:			c, addr = s.accept()			print 'Got connection from', addr			inputs.append(c)		else:			try:				data = r.recv(1024)				disconnected = not data			except socket.error:				disconnected = True			if disconnected:				print r.getpeername(), 'disconnected'				inputs.remove(r)			else:				print data

poll 方法比 select 使用起來簡單,下面的時候就是上面示例的 poll 版本:

# -- coding: utf-8 --# Windows 系統不支持pollimport socket, selects = socket.socket()host = socket.gethostname()port = 1234s.bind((host,port))fdmap = {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 fdmap:			c, addr = s.accept()			print 'Got connection from', addr			p.register(c)			fdmap[c.fileno()] = c		elif event & select.POLLIN:			data = fdmap[fd].recv(1024)			if not data:# 如果沒有數據,關閉連接				print fdmap[fd].getpeername(), 'disconnected'				p.unregister(fd)				del fdmap[fd]			else:				print data

4. 使用Twisted

Twisted 是一個事件驅動的Python網絡框架。使用 Twisted 框架首先需要單獨下載安裝。我們可以使用pip包管理工具來進行安裝,參考:http://m.survivalescaperooms.com/IPrograming/p/Python_module_package.html。下面是使用Twisted的兩個簡單示例:

4.1 使用 Twisted

from twisted.internet import reactorfrom twisted.internet.protocol import Protocol, Factoryclass SimpleLogger(Protocol):	def connectionMade(self):    	print 'Got connection from', self.transport.client	def connectionLost(self, reason):    	print self.transport.client, 'disconnected'	def dataReceived(self, data):    	print datafactory = Factory()factory.protocol = SimpleLoggerreactor.listenTCP(1234,factory)reactor.run()

使用LineReceiver協議改進的版本:

from twisted.internet import reactorfrom twisted.internet.protocol import Factoryfrom twisted.protocols.basic import LineReceiverclass SimpleLogger(LineReceiver):	def connectionMade(self):    	print 'Got connection from', self.transport.client	def connectionLost(self, reason):    	print self.transport.client, 'disconnected'	def lineReceived(self,line):    	print linefactory = Factory()factory.protocol = SimpleLoggerreactor.listenTCP(1234, factory)reactor.run()

參考資料&進一步閱讀

Python基礎教程(第二版)

Twisted


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 嘉定区| 娱乐| 文水县| 麦盖提县| 介休市| 连州市| 南丹县| 石门县| 响水县| 肇州县| 乐安县| 延寿县| 衡阳县| 剑川县| 陆良县| 手机| 南开区| 吕梁市| 临夏市| 新郑市| 富阳市| 会东县| 西乌珠穆沁旗| 平安县| 徐水县| 乌拉特前旗| 卓资县| 淮安市| 安远县| 阜南县| 杭锦后旗| 湘西| 金昌市| 庆城县| 垦利县| 民丰县| 红桥区| 青海省| 富顺县| 马公市| 丰原市|