python网络编程
此篇博文是《python核心编程》的第16章的笔记
主要介绍了基于套接字的这种低级别的协议的使用,由于是底层的所以在调bug神马会非常受用
客户、服务器的几个例子:
硬件形式的:打印机服务器、文件服务器
软件形式的:web服务器、数据库服务器、窗口服务器
关于银行出纳也是这样类似的客户服务器模型
关于套接字
套接字是网络通信最为底层的东西
套接字的两个分类分别是:
AF_UNIX(用于本地)与AF_INET(用于网络)
Python 只支持AF_UNIX,AF_NETLINK,和AF_INET 家族。由于我们只关心网络编程,所以在本
章的大部分时候,我们都只用AF_INET
地址和端口
如果把套接字比做电话的插口——即通讯的最底层结构,那主机与端口就像区号与电话号码的
一对组合。有了能打电话的硬件还不够,你还要知道你要打给谁,往哪打。
套接字的另外一种分类方式:
面向连接
实现这种连接的主要协议就是传输控制协议(即TCP)。要创建TCP 套接字就得在创建的时候,
指定套接字类型为SOCK_STREAM。TCP 套接字采用SOCK_STREAM 这个名字,表达了它做为流套接字的
特点。由于这些套接字使用Internet 协议(IP)来查找网络中的主机,这样形成的整个系统,一般
会由这两个协议(TCP 和IP)来提及,即TCP/IP。
无连接
实现这种连接的主要协议就是用户数据报协议(即UDP)。要创建UDP 套接字就得在创建的时候,
指定套接字类型为SOCK_DGRAM。SOCK_DGRAM 这个名字,也许你已经猜到了,来自于单词“datagram”
(“数据报”)。由于这些套接字使用Internet 协议来查找网络中的主机,这样形成的整个系统,一
般会由这两个协议(UDP 和IP)来提及,即UDP/IP。
python中的套接字
使用socket模块
使用该模块的方法你可以Google或者查看help(socket)
使用它是通过创建一个socket对象,然后所有的操作通过对象的方法来实现,socket对象构建额参数就是上面所说的几个概念
使用socket开发服务器
你也许想知道很多软件服务器是如何开发出来的,既然socket是底层的网络编程的组件,那么可以用它来开发一个网络服务器,下面的代码使用socket模块实现了一个简单的时间服务器,使用TCP/IP,使用UDP的例子可以参考原书
服务端代码:
import socket from time import ctime # 创建一个套接字对象 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #把这个套接字对象绑定到一个服务器地址,这里是本地 sock.bind(('localhost', 8001)) ##设置好套接字开始监听,里面的5是什么意思呢 sock.listen(5) # 开始无限等待服务的循环 while True: print 'waiting for connection..' ##当用户请求时,创建一个关于该用户的套接字,和该用户的地址 cliensock,address = sock.accept() print cliensock print 'conncet from', address try: ##设置客户请求的等待时间 cliensock.settimeout(5) ## 接受客户的请求,data是返回的数据,似乎例子中是string类型的 data = cliensock.recv(1024) ##返回一个字符类型的数据,使用send方法 cliensock.send('[%s]%s'%(ctime(),data)) except socket.timeout: print 'time out' cliensock.close()
客户端代码
import socket #创建套接字对象 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #链接到一个服务器地址 sock.connect(('localhost', 8001)) #发送数据,string类型的 sock.send('fvsbvdb') #接受返回的数据 print sock.recv(1024) sock.close()
一个增强socket模块?
SocketServer 是标准库中一个高级别的模块。用于简化网络客户与服务器的实现。模块中,
已经实现了一些可供使用的类。
你也会注意到,我们的程序现在是“事件驱动”了。这就意味着,只有在事件出现的时候,程序才有“反应”。界面编程(第18 章)也是事件驱动的。你会注意到有一个相似之处,即在代码的最后一行都有一个服务器的无限循环,等待并处理客户的服务请求。
请仔细看看下面的代码实现上面的时间服务器,你会发现这里变成面向对象编程以及事件驱动了
服务器段代码
from SocketServer import TCPServer as TCP,StreamRequestHandler as SRH from time import ctime HOST = '' PORT = 21567 ADDR = (HOST, PORT) class MyRequestHandler(SRH): def handle(self): print '...connected from:', self.client_address self.wfile.write('[%s] %s' % (ctime(),self.rfile.readline())) tcpServ = TCP(ADDR, MyRequestHandler) print 'waiting for connection...' tcpServ.serve_forever()
客户端代码
from socket import * HOST = 'localhost' PORT = 21567 BUFSIZ = 1024 ADDR = (HOST, PORT) while True: tcpCliSock = socket(AF_INET, SOCK_STREAM) tcpCliSock.connect(ADDR) data = raw_input('> ') if not data: break tcpCliSock.send('%s\r\n' % data) data = tcpCliSock.recv(BUFSIZ) if not data: break print data.strip() tcpCliSock.close()
Twisted 框架???
Twisted 是一个完全事件驱动的网络框架。它允许你使用和开发完全异步的网络应用程序和协议。
它为你创建一个完整系统提供了很大的帮助。系统中可以有:网络协议,线程,安全和认证,聊天/即时通讯,数据库管理,关系数据库集成,网页/互联网,电子邮件,命令行参数,图形界面集成等。
与网络和套接字相关的Python 模块
socket 底层网络接口。
asyncore/ 为能异步处理客户请求的网络应用程序提供底层功能。
asynchat
select 在单线程网络服务器程序中,管理多个套接字连接。
SocketServer 包含了写网络应用程序服务器所需要的高级别模块。提供了完整的进程和线程
的版本。
建议
async*和SocketServer 模块在创建服务器方面都提供了高层次的功能。由于是基于socket 和
(或)select 模块,封装了所有的底层的代码,它们使得你可以快速开发客户/服务器的系统。
虽然async*是标准库提供的唯一的异步开发支持库。我们也可选择如Twisted 这样的,相对标
准库更现代,更强大的第三方库。
我们本章所讨论的主题涵盖了在Python 中用socket 网络编程和如何用低级别的协议如TCP/IP
和UDP/IP 来创建应用程序。如果你想要开发高层次的网页和Internet 应用程序,我们强烈建议你
阅读第17 章和第20 章。
第17章和第20章是:网络客户端编程以及web编程
号外:关于阻塞非阻塞,同步异步的解释