Python 网络编程(14) 持续更新
socket 模块
套接字(socket)。包括服务器套接字和客户机套接字。
socket模块中有一个socket类
初始化
import socket socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)
第一个参数 地址族 第二个参数 流 socket.SOCK_STREAM 或 数据报 socket.SOCK_DGRAM 第三个参数 使用的协议 0
绑定 (bind)
监听 (listen)
listen 参数 允许排队等待的连接数目。
accept 接受客户端连接 (该方法会阻塞)直到客户端连接,返回(client,address)元组,client 客户端套接字,address地址。处理完后,再调用accept方法等待下一个连接,无限循环中。
客户端套接字
connect方法连接服务器 参数 和 绑定一样。
send 发送数据
recv 接收数据
需要一个 参数 (所需要的最大的字节数)
在Linux或UNIX系统中,只有系统管理员的权限,才可以开1024以下的端口。这些低于1024端口被用于标准服务,如果用Ctrl+C停止服务器,可能要等一段时间,才能使用端口。
socket_server.py
# coding: utf-8 import socket s = socket.socket() host = socket.gethostname() port = 1234 s.bind((host, port)) s.listen(5) while True: client, addr = s.accept() print '客户端新连接', addr client.send('Thank you connecting') client.close()
socket_client.py
# coding: utf-8 import socket s = socket.socket() host = socket.gethostname() port = 1234 s.connect((host, port)) print s.recv(1024)
urllib 和 urllib2 模块
urllib 可以下载Web页面,提取信息。
urllib2 更强大一些,支持 http验证 和 cookie。或者为自己的协议编写扩展程序。
打开远程文件
from urllib import urlopen web_page = urlopen('http://www.baidu.com') web_text = web_page.read() print web_text
获取远程文件
使用urlretrieve返回一个元组(filename, headers) filename是本地文件名(有urllib自动创建),headers包含远程文件信息
from urllib import urlopen, urlretrieve, urlcleanup urlretrieve('http://www.baidu.com', 'D:\\python_web_page.html')
urlretrieve 第二个参数 如果不指定文件名,文件会放在临时的位置,用open函数可以打开。完成操作后,可以用 urlcleanup 函数 可以清理临时文件。
其他方法
- quote 在特殊的字符串,转成url编码 如 %7E
- quote_plus 功能和quote差不多,但用+代替空格
- unquote 和quote相反
- unquote_plus 和quote_plus相反
- urlencode 把映射(比如字典)或者包含两个元素的元组的序列----(key,value)这种形式----转换为 url编码字符串
其他网络模块
asynchat asyncore的增强版本
asyncore 异步套接字处理程序
cgi 基本的CGI支持
cookie cookie对象操作,主要用于服务器
cookielib 客户端cookie支持
email email消息支持(包括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服务器模块
smtpdlib SMTP客户端模块
telnetlib Telnet客户端模块
urlparse 支持解析URL
xmlrpclib XML-RPC客户端支持
SocketServer
该模块包括 BaseHttpServer、SimpleHttpServer、CGIHttpServer、SimpleXMLRPCserver、DocXMLRPCServer
SoceketServer包含基本的4个类
TCP流式套接字 TCPServer
UDP数据报套接字 UDPServer、UnixStreamServer和UnixDatagramServer。
socketserver_test.py
from SocketServer import TCPServer, StreamRequestHandler class Handler(StreamRequestHandler): def handle(self): addr = self.request.getpeername() print 'Hello',addr self.wfile.write('Thank you for connecting') server = TCPServer(('', 1234), Handler) server.serve_forever()
多个连接
以上解决方案都是同步的。但是有的时候像完整的聊天会话,需要同时处理多个连接就很重要。
现在有3中方法实现 分叉(forking)、线程(threading)和 异步I/O
分叉是UNIX术语,当分叉一个进程时,基本上是复制了它,并且分叉后的两个进程都从当前的执行点继续运行,并且每个进程都有自己的内存副本(如变量)。一个进程称为父进程,另一个进程(复制的)称为子进程。
在一个使用分叉的服务器中,每一个客户端机连接都利用分叉创造一个子进程。父进程继续监听新的连接,同时子进程处理客户端。当客户端的请求结束时,子进程就退出了。因为分叉的进程时并行运行的,客户端之间不必互相等待。
分叉不支持Window的
因为分叉比较耗资源,又出现另一种方法 线程。
因为线程共享内存,所以必须确保它们的变量不会冲突,或者同一时间修改同一内容,就会造成混乱。
避免线程和分叉的另外一种方法是转换到 Stackless Python 能够在不同的上下文之间快递、方便切换而设计的Python的版本。支持微线程(microthreads)的类线程的并行形式,微线程比真线程的伸缩性好 如 Stackless Python已被用在星战前夜在线(EVE Online)。
异步有一个非常强大的异步网络编程框架(Twisted)
forking_test.py
from SocketServer import TCPServer, ForkingMixIn, StreamRequestHandler class Server(ForkingMixIn, TCPServer): pass class Handler(StreamRequestHandler): def handle(self): addr = self.request.getpeername() print 'Hello', addr self.wfile.write('Thank you for connecting') server = Server(('', 1234), Handler) server.serve_forever()
thread_test.py
from SocketServer import TCPServer, ThreadingMixIn, StreamRequestHandler class Server(ThreadingMixIn, TCPServer): pass class Handler(StreamRequestHandler): def handle(self): addr = self.request.getpeername() print 'Hello', addr self.wfile.write('Thank you for connecting') server = Server(('', 1234), Handler) server.serve_forever()
带有 select 和 poll 的异步I/O
这两个函数都来自select模块,但它只能在UNIX系统中使用。
select_test.py
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: client, addr = s.accept() print 'Hello', addr inputs.append(client) 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_test.py
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 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: # No data -- connection closed 没有数据关闭连接 print fdmap[fd].getpeername(), 'disconnected' p.unregister(fd) del fdmap[fd] else: print data
Twisted事件驱动Python网络框架
Twisted 支持Web服务器、客户机、SSH2、SMTP、POP3、IMAP4、AIM、ICQ、IRC、MSN、Jabber、NNTP和DNS等等。
安装Twisted
从官网下载文件,解压后。运行
python setup.py install
如果发现这个报错
error: Setup script exited with error: Microsoft Visual C++ 9.0 is required (Unable to find vcvarsall.bat). Get it from http://aka.ms/vcpython27
For Windows installations:
While running setup.py for package installations, Python 2.7 searches for an installed Visual Studio 2008. You can trick Python to use a newer Visual Studio by setting the correct path in VS90COMNTOOLS environment variable before calling setup.py.
If you have Visual Studio 2010 installed, execute
SET VS90COMNTOOLS=%VS100COMNTOOLS%
or with Visual Studio 2012 installed (Visual Studio Version 11)
SET VS90COMNTOOLS=%VS110COMNTOOLS%
or with Visual Studio 2013 installed (Visual Studio Version 12)
SET VS90COMNTOOLS=%VS120COMNTOOLS%
在执行这句前 python setup.py install 先执行以上语句,就解决问题了。
http://www.cnblogs.com/pang1567/p/4168768.html
twisted_test.py
from twisted.internet import reactor from twisted.internet.protocol import Factory from twisted.protocols.basic import LineReceiver class SimpleLogger(LineReceiver): def connectionMade(self): print '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(2443, factory) reactor.run()
line_receiver_test.py 每次接收一行数据
from twisted.internet import reactor from twisted.internet.protocol import Factory from twisted.protocols.basic import LineReceiver class SimpleLogger(LineReceiver): def connectionMade(self): print '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(2443, factory) reactor.run()

浙公网安备 33010602011771号