《Python基础教程》学习笔记(14网络)

    xiaoxiao2021-03-25  62

    14. 网络编程

    14.1 少数几个网络设计模块

    14.1.1 socket模块

    一个套接字就是一个socket模块中的socket类的实例。它的实例化需要3个参数:

    第1个参数是地址族(默认:socket.AF_INET);第2个参数是流(默认:socket.SOCK_STREAM)或数据报(socket.SOCK_DGRAM)套接字;第3个参数是使用的协议(默认0)。

    服务器端套接字使用bind方法后,再调用listen方法去监听给定的地址。一个地址就是一个格式为(host, port)的元组。

    客户端套接字使用connect方法连接到服务器在connect方法中使用的地址与bind方法中的地址相同。

    listen方法只有一个参数,即服务器未处理的连接的长度(即允许排队等待的连接数目,这些连接在停止接收之前等待接收)。

    服务器端开始监听后,使用accept方法接受客户端的连接。该方法会阻塞直到客户端连接,然后返回(client, address)的元组,client是一个客户端套接字,address是一个前面解释过的地址。

    套接字有两个方法:send和recv(用于接收),用于传输数据。

    # 服务器端 import socket s = socket.socket() host = socket.gethostname() port = 1234 s.bind((host, port)) s.listen(5) while True: c, addr = s.accept() print 'Got connection from', addr c.send('Thank you for connecting') c.close() # 客户端 import socket s = socket.socket() host = socket.gethostname() port = 1234 s.connect((host, port)) print s.recv(1024)

    14.1.2 urllib和urllib2模块

    打开远程文件

    from urllib import urlopen webpage = urlopen('http://python.org') # localfile = urlopen('file:C:\\somefile.txt')

    urlopen返回的类文件对象支持close、read、readline、readlines方法,当然也支持迭代。

    下例:想要提取前面打开的Python页中 “About” 连接的(相对)URL

    import re text = webpage.read() m = re.search('<a href="([^"]+)" .*?>about</a>', text, re.IGNORECASE m.group(1)

    获取远程文件

    如果想下载文件并在本地存储一个文件的副本,可以使用urlretrieve,它返回一个元组(filename, headers),filename是本地文件的名字(由urllib自动创建),headers包含一些远程文件的信息。

    # 第二个参数为下载后的文件名,如果没指定,则会存放在临时的位置,用open函数可以打开它。 # 要清理临时文件,可以调用urlcleanup函数。 urlretrieve('http://www.python.org', 'C:\\python_webpage.html')

    14.1.3 其他模块

    模块描述asynchatasyncore的增强版本asyncore异步套接字处理程序cgi基本的CGI支持CookieCookie对象操作,主要用于服务器cookielib客户端cookie支持emailE-mail消息支持(包括MIME)ftplibFTP客户端模块gopherlibgopher客户端模块httplibHTTP客户端模块imaplibIMAP4客户端模块mailbox读取集中邮箱的格式mailcap通过mailcap文件访问MIME配置mhlib访问MH邮箱nntplibNNTP客户端poplibPOP客户端robotparser支持解析Web服务器的robot文件SimpleXMLRPCServer一个简单的XML-RPC服务器smtpdSMTP服务器smtplibSMTP客户端telnetlibTelnet客户端urlparse支持解释URLxmlrpclibXML-RPC的客户端支持

    14.2 SocketServer

    SocketServer模块是标准库中很多服务器框架的基础,这些服务器框架包括BaseHTTPServer、SimpleHTTPServer、CGIHTTPServer、SimpleXMLRPCServer和DocXMLRPCServer。

    SocketServer包含4个基本的类:

    针对TCP套接字流的TCPServer;针对UDP数据报套接字的UDPServer;以及针对性不强的UnixStreamServer和UnixDatagramServer。 # 一个基于SocketServer的服务器 from SocketServer import TCPServer, StreamRequestHandler class Handler(StreamRequestHandler): def handle(self): addr = self.request.getpeername() print 'Got connection from', addr # self.rfile用户读,self.wfile用户写入 self.wfile.write('Thank you for connecting') server = TCPServer(('', 1234), Handler) server.serve_forever()

    14.3 多连接

    以上讨论的都是同步的。下面同时处理多个连接。

    有3中主要的方法能实现这个目的:分叉(forking)、线程(threading)以及异步IO(asynchronous I/O)。

    14.3.1 使用SocketServer进行分叉和县城处理

    使用了分叉技术的服务器

    from SocketServer import TCPServer, ForkingMixIn, StreamRequestHandler class Server(ForkingMixIn, TCPServer): pass class Handler(StreamRequestHandler): def handle(self): addr = self.request.getpeername() print 'Got connection from', addr self.wfile.write('Thank you for connecting') server = Server(('', 1234), Handler) server.serve_forever()

    使用线程处理的服务器

    from SocketServer import TCPServer, ThreadingMixIn, StreamRequestHandler class Server(ThreadingMinIn, TCPServer): pass class Handler(StreamRequestHandler): def handle(self): addr = self.request.getpeername() print 'Got connection from', addr self.wfile.write('Thank you for connecting') server = Server(('', 1234), Handler) server.serve_forever()

    14.3.2 带有select和poll的异步I/O

    select函数需要3个序列作为它的必选参数,此外还有一个可选的以秒为单位的超时时间作为第4个参数。

    示例:使用了select的简单服务器

    import socket, select s = socket.socket() host = socket.gethostname() port = 1234 s.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

    select模块中的polling事件常量

    事件名描述POLLIN读取来自文件描述符的数据POLLPRI读取来自文件描述符的紧急数据POLLOUT文件描述符已经准备好数据,写入时不会发生阻塞POLLERR与文件描述符有关的错误情况POLLHUP挂起,连接丢失POLLNVAL无效请求,连接没有打开

    示例:使用poll的简单服务器

    import socket, select s = socket.socket() host = socket.gethostname() port = 1234 s.bind((host, port)) # 从文件描述符到套接字对象的映射 fdmap = {s.fileno(): s} s.listen(5) p = select.poll() # 注册一个文件描述符(或带有fileno方法的对象) p.register(s) while True: events = p.poll() # fd是文件描述符,event则告诉发生了什么,是一个位掩码(见上表) 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

    14.4 Twisted

    Twisted是一个事件驱动的Python网络矿建。支持Web服务器、客户机、SSH2、SMTP、POP3、IMAP4、AIM、ICQ、IRC、MSN、Jabber、NNTP和DNS等等。

    14.4.1 下载并安装

    官网点击下载。

    # 运行Distutils脚本安装 python setup.py install

    14.4.2 编写Twisted服务器

    使用Twisted的简单服务器

    from twisted.internet from reactor from twisted.internet.protocol import Protocol, Factory class SimpleLogger(Protocol) # 得到一个连接后,会被调用 def connectionMade(self): print 'Got connection from', self.transport.client # 丢失一个连接后,会被调用 def connectionLost(self, reason): print self.transport.client, 'disconnected' # 通过dataReceived处理来自客户端的数据 # 使用对象self.transport把数据发回到客户端, # 这个对象有一个write方法,也有一个包含客户机地址的client属性 def dataReceived(self, data): print data factory = Factory() # 设置自定义协议 factory.protocol = SimpleLogger reactor.listenTCP(1234, factory) reactor.run()

    使用LineReceiver协议改进的记录服务器

    from twisted.internet import reactor from twisted.internet.protocol import Factory from twisted.protocols.basic import LineReceiver class SimpleLogger(LineReceiver): def connectionMade(self): print 'Got connection from', self.transport.client def connectionLost(self, reason): print self.transport.client, 'disconnected' # 只要收到了一整行就调用事件处理程序lineReceived def lineReceived(self, line): print line factory = Factory() factory.protocol = SimpleLogger reactor.listenTCP(1234, factory) reactor.run()

    14.5 本章的新函数

    函数描述urllib.urlopen(url[, data[, proxies]])通过URL打开一个类文件对象urllib.rulretrieve(url[, fname[, hook[, data]]])通过URL下载一个文件urllib.quote(string[, safe])引用特定的URL字符urllib.quote_plus(string[, safe])和quote相同,但是将空格引用为+urllib.unquote(string)和quote相反urllib.unquote_plus(string)和quote_plus相反urllib.urlencode(query[, doseq])在CGI请求中使用的编码映射select.select(iseq, oseq, eseq[, timeout])找出准备好读/写的套接字select.poll()为polling套接字创建一个poll对象reactor.listenTCP(port, factory)Twisted函数,监听连接reactor.run()Twisted函数,主服务器循环
    转载请注明原文地址: https://ju.6miu.com/read-34024.html

    最新回复(0)