少数几个网络设计模块
socket模块
网络编程中一个基本组件就是套接字(socket)——两个端点的程序之间的“信息通道”。程序通过网络连接,通过套接字相互发送信息。
套接字包括两个:服务器套接字和客户机套接字。在创建一个服务器套接字后,让它在某个网络地址处(IP地址和端口的组合)监听,直到有客户端套接字连接。连接完成后,两者就可以进行交互了。
服务器端套接字使用bind方法后,再调用listen方法去监听某个特定的地址。客户端套接字使用connect方法连接到服务器,在connect方法中使用的地址与服务器在bind方法中的地址相同。
一个小型服务器
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)
urllib和urllib2模块
在能使用的各种网络函数库中,功能最强大的可能是urllib和urllib2了。通过它们在网络上访问文件,就好像访问本地电脑上的文件一样。通过一个简单的函数调用,几乎可以把任何URL所指向的东西用作程序输入。
打开远程文件
可以像打开本地文件一样打开远程文件,不同之处是只能使用只读模式。使用来自urllib模块的urlopen:
>>> from urllib import urlopen
>>> webpage = urlopen('http://www.python.org')
urlopen返回的类文件对象支持close、read、readline和readlines方法,当然也支持迭代。
获取远程文件
urllib为你下载文件并在本地文件中储存一个文件的副本——urlretrieve。
urlretrieve('http://www.python.org', 'C://python_webpage.html')
清理临时文件使用urlcleanup
其他模块
模块 | 描述 |
---|---|
asynchat | asyncore的增强版本 |
asyncore | 异步套接字处理程序 |
cgi | 基本的CGI支持 |
Cookie | Cookie对象操作,主要用于服务器 |
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服务器 |
smtpd | SMTP服务器端模块 |
smtplib | SMTP客户端模块 |
telnetlib | Telnet客户端模块 |
urlparse | 支持解释URL |
xmlrpclib | XML-RPC的客户端支持 |
SocketServer和它的朋友们
SocketServer模块是标准库中很多服务器框架的基础——这些服务器包括BaseHTTPServer、SimpleHTTPServer、CGIHTTPServer、SimpleXMLRPCServer和DocXMLRPCServer,所有这些服务器框架都为基础服务器增加了特定的功能。
多个连接
分叉、线程、异步I/O连接
使用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(ThreadingMixIn, 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()
带有select和poll的异步I/O
使用了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
使用了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()
p.register(s)
while True:
events = p.poll()
for fd, event in events:
if fdmap[fd] is s:
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: # No data -- connection closed
print fdmap[fd].getpeername(), 'disconnected'
p.unregister(fd)
del fdmap[fd]
else:
print data
Twisted
Twisted是一个事件驱动的Python网络框架,原来是为网络游戏开发的,现在被所有类型的网络软件使用。
下载安装Twisted
编写Twisted服务器
使用Twisted的简单服务器
from twisted.internet import 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'
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'
def lineReceived(self, line):
print line
factory = Factory()
factory.protocol = SimpleLogger
reactor.listenTCP(1234, factory)
reactor.run()
小结
套接字和socket模块
urllib和urllib2
SocketServer框架
select和poll
Twisted