Python 内置封装了很多常见的网络协议的库,因此Python成为了一个强大的网络编程工具,这里是对Python的网络方面编程的一个简单描述。

1. 常用的网络设计模块

在标准库中有很多网络设计相关的模块,除了那些明确处理网络事务的模块外,还有很多模块也是是和网络相关的,下面是几个常用的网络设计模块:

1.1 socket 模块

socket 模块是网络编程中的基础组件。socket 主要的作用就是作为两个程序之间的“通信信道”,不同进程(不同主机)可以通过socket相互发送信息,以达到网络通信的目的。socket 包括两个部分:服务端和客户端。服务端监听端口号,等待客户端发送的消息;而客户端在需要发送信息是,连接服务端,将信息发送出去即可。下面是一个简单的同步网络编程的简单示例:

这是Socket Server 部分:

  1. import socket
  2. s = socket.socket()
  3. host = socket.gethostname()
  4. port = 8088
  5. s.bind((host,port))
  6. s.listen(5)
  7. while True:
  8. c, addr = s.accept()
  9. print 'Got connection from', addr
  10. c.send('Thank you for connection')
  11. c.close()

这是Socket Client 部分:

  1. import socket
  2. s = socket.socket()
  3. host = socket.gethostname()
  4. port = 8088
  5. s.connect((host,port))
  6. print s.recv(1024)

运行时,请将对应的端口(这里是8088)添加到防火墙的InBound和OutBound的规则中。

1.2 urllib 和 urllib2 模块

urlliburllib2 是Python标准库中最强的的网络工作库。通过这两个库所提供的上层接口,使我们可以像读取本地文件一样读取网络上的文件。而且 urllib2 并不是 urllib 的升级版本(应该是一种补充),二者是不可相互替代的。

通过使用 urlliburlopen 函数可以很容易的打开远程的文件,如下:

  1. from urllib import urlopen
  2. webpage = urlopen('http://www.cnblogs.com/IPrograming/')
  3. txt = webpage.readline(45)
  4. print txt # !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0

也可以通过在通过在路径的前面添加 file: 来访问本地文件:

  1. from urllib import urlopen
  2. webpage = urlopen(r'file:D:\H\sr23upd\ADD_ABBR.txt')
  3. txt = webpage.readline(45)
  4. print txt

如果你还可以通过 urllib 提供的 urlretrieve函数,来直接保存远程文件副本:

  1. from urllib import urlretrieve
  2. webpage = urlretrieve('http://www.cnblogs.com/IPrograming/','C:\\temp.html')
  3. print type(webpage) # <type 'tuple'>

1.3 其他与网络相关的模块

除了 socket、urllib和urllib2这些模块以外标准库还有很多和网络相关的模块,下面的列表是其中的一部分:

  1. ===========================================================
  2. 模块 描述
  3. ===========================================================
  4. asynchat asyncore的增强版本
  5. asyncore 异步socket处理程序
  6. cgi 基本的CGI支持
  7. Cookie Cookie对象操作,主要用于服务器操作
  8. cookielib 客户端cookie支持
  9. email E-mail消息支持(包括MIME)
  10. ftplib FTP客户端模块
  11. gopherlib gopher客户端博客
  12. httplib HTTP客户端模块
  13. imaplib IMAP4客户端模块
  14. mailbox 读取几种邮件的格式
  15. mailcap 通过mailcap文件访问MIME配置
  16. mhlib 访问MH邮箱
  17. nntplib NNTP客户端模块
  18. poplib POP客户端模块
  19. robotparser 支持解析Web服务器的robot文件
  20. SimpleXMLRPCServer 一个简单的XML-RPC服务器
  21. stmpd SMTP服务器模块
  22. smtplib SMTP客户端模块
  23. telnetlib Telnet客户端模块
  24. urlparse 支持解析URL
  25. xmlrpclib XML-RPC的客户端支持

2. SocketServer

SocketServer模块是标准库中很多其他服务器框架的基础,这些服务器框架包括:BaseHTTPServer、SimpleHTTPServer、CGIHTTPServer、SimpleXMLRPCServer和DocXMLRPCServer,这些服务框架都是在基础框架上增加了特定的功能。SocketServer包含了4个基本的类:

  • TCPServer,针对TCP的Socket
  • UDPServer,针对UDP数据报的Socket
  • UnixStreamServer
  • UnixDatagramServer

下面是一个基于SocketServer的简单Socket Server端示例:

  1. from SocketServer import TCPServer, StreamRequestHandler
  2. class Handler(StreamRequestHandler):
  3. def handle(self):
  4. addr = self.request.getpeername()
  5. self.wfile.write('Thank you for connectiong')
  6. server = TCPServer(('',8088),Handler)
  7. server.serve_forever()

3. 多连接

一般情况下Socket中的Client端常常不止一个,想要使Socket Server端能同时处理多个Client的连接一般由三种主要的方法:

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

3.1 使用分叉

分叉(fork)是一个UNIX术语;当分叉一个进程(一个运行的程序)时,基本上时复制了它,并且分叉后的两个进程都从当前执行的点继续运行,并且每个进程都有自己的内存副本。一个进程(开始的那个)成为另一个进程的(复制的,也就是子进程)的父进程。在一个使用分叉的服务器中,每个客户端连接都利用分叉创建一个子进程。父进程继续监听连接,同时子进程处理客户端。当客户端的请求结束时,子进程退出。分叉的进程是并行执行的,客户端直接不必相互等待。分叉的缺点是比较耗费资源(每个分叉出来的进程都需要自己的内存)。下面是一个使用分叉创建Socket服务端的示例:

  1. # --coding:utf-8--
  2. # 使用了分叉(fork),Windows系统不支持
  3. from SocketServer import TCPServer, ForkingMixIn, StreamRequestHandler
  4. class Server(ForkingMixIn, TCPServer):pass
  5. class Handler(StreamRequestHandler):
  6. def handle(self):
  7. addr = self.request.getpeername()
  8. print 'Got connection from', addr
  9. self.wfile.write('Thank you for connectiong')
  10. server = Server(('',1234),Handler)
  11. server.serve_forever()

3.2 使用线程

线程是轻量级的进程或子进程,所有的线程都存在于相同的进程(一个运行的程序)中,且共享内存。虽然使用多线程相对于分叉占用的资源较少,但是由于共享内存,所有必需要确保它们的变量不会冲突,或者是同一时间修改同一内容,这样会造成混乱。这些问题可以归结为同步问题。下面是使用多线程的一个简单示例:

  1. # --coding:utf-8--
  2. # 使用多线程
  3. from SocketServer import TCPServer, ThreadingMixIn, StreamRequestHandler
  4. class Server(ThreadingMixIn,TCPServer):pass
  5. class Handler(StreamRequestHandler):
  6. def handle(self):
  7. addr = self.request.getpeername()
  8. print 'Got connection from', addr
  9. self.wfile.write('Thank you for connection')
  10. server = Server(('',1234),Handler)
  11. 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 的简单示例:

  1. import socket, select
  2. s = socket.socket()
  3. host = socket.gethostname()
  4. port = 1234
  5. s.bind((host,port))
  6. s.listen(5)
  7. inputs = [s]
  8. while True:
  9. rs, ws, es = select.select(inputs,[],[])
  10. for r in rs:
  11. if r is s:
  12. c, addr = s.accept()
  13. print 'Got connection from', addr
  14. inputs.append(c)
  15. else:
  16. try:
  17. data = r.recv(1024)
  18. disconnected = not data
  19. except socket.error:
  20. disconnected = True
  21. if disconnected:
  22. print r.getpeername(), 'disconnected'
  23. inputs.remove(r)
  24. else:
  25. print data

poll 方法比 select 使用起来简单,下面的时候就是上面示例的 poll 版本:

  1. # -- coding: utf-8 --
  2. # Windows 系统不支持poll
  3. import socket, select
  4. s = socket.socket()
  5. host = socket.gethostname()
  6. port = 1234
  7. s.bind((host,port))
  8. fdmap = {s.fileno(): s}
  9. s.listen(5)
  10. p = select.poll()
  11. p.register(s)
  12. while True:
  13. events = p.poll()
  14. for fd, event in events:
  15. if fd in fdmap:
  16. c, addr = s.accept()
  17. print 'Got connection from', addr
  18. p.register(c)
  19. fdmap[c.fileno()] = c
  20. elif event & select.POLLIN:
  21. data = fdmap[fd].recv(1024)
  22. if not data:# 如果没有数据,关闭连接
  23. print fdmap[fd].getpeername(), 'disconnected'
  24. p.unregister(fd)
  25. del fdmap[fd]
  26. else:
  27. print data

4. 使用Twisted

Twisted 是一个事件驱动的Python网络框架。使用 Twisted 框架首先需要单独下载安装。我们可以使用pip包管理工具来进行安装,参考:http://www.cnblogs.com/IPrograming/p/Python_module_package.html#pip。下面是使用Twisted的两个简单示例:

4.1 使用 Twisted

  1. from twisted.internet import reactor
  2. from twisted.internet.protocol import Protocol, Factory
  3. class SimpleLogger(Protocol):
  4. def connectionMade(self):
  5. print 'Got connection from', self.transport.client
  6. def connectionLost(self, reason):
  7. print self.transport.client, 'disconnected'
  8. def dataReceived(self, data):
  9. print data
  10. factory = Factory()
  11. factory.protocol = SimpleLogger
  12. reactor.listenTCP(1234,factory)
  13. reactor.run()

使用LineReceiver协议改进的版本:

  1. from twisted.internet import reactor
  2. from twisted.internet.protocol import Factory
  3. from twisted.protocols.basic import LineReceiver
  4. class SimpleLogger(LineReceiver):
  5. def connectionMade(self):
  6. print 'Got connection from', self.transport.client
  7. def connectionLost(self, reason):
  8. print self.transport.client, 'disconnected'
  9. def lineReceived(self,line):
  10. print line
  11. factory = Factory()
  12. factory.protocol = SimpleLogger
  13. reactor.listenTCP(1234, factory)
  14. reactor.run()

参考资料&进一步阅读

Python基础教程(第二版)

Twisted

【循序渐进学Python】15.网络编程的更多相关文章

  1. python基础网络编程--转

    python之网络编程 本地的进程间通信(IPC)有很多种方式,但可以总结为下面4类: 消息传递(管道.FIFO.消息队列) 同步(互斥量.条件变量.读写锁.文件和写记录锁.信号量) 共享内存(匿名的 ...

  2. python之网络编程

    本地的进程间通信(IPC)有很多种方式,但可以总结为下面4类: 消息传递(管道.FIFO.消息队列) 同步(互斥量.条件变量.读写锁.文件和写记录锁.信号量) 共享内存(匿名的和具名的) 远程过程调用 ...

  3. Python的网络编程--思维导图

    Python的网络编程--思维导图

  4. Python高级网络编程系列之第一篇

    在上一篇中我们简单的说了一下Python中网络编程的基础知识(相关API就不解释了),其中还有什么细节的知识点没有进行说明,如什么是TCP/IP协议有几种状态,什么是TCP三次握手,什么是TCP四次握 ...

  5. python 基础网络编程2

    python 基础网络编程2 前一篇讲了socketserver.py中BaseServer类, 下面介绍下TCPServer和UDPServer class TCPServer(BaseServer ...

  6. python 基础网络编程1

    python 基础网络编程1 Source code: Lib/socketserver.py lib的主目录下有一个sockserver.py文件, 里面是python基本的网络编程模型 共有一个b ...

  7. Python Socket 网络编程

    Socket 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于 Socket 来完成通信的,例如我们每天浏览网页.QQ ...

  8. python中网络编程基础

    一:什么是c\s架构 1.c\s即client\server 客户端\服务端架构. 客户端因特定的请求而联系服务器并发送必要的数据等待服务器的回应最后完成请求 服务端:存在的意义就是等待客户端的请求, ...

  9. Python Socket 网络编程 (客户端的编程)

    Socket 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于 Socket 来完成通信的,例如我们每天浏览网页.QQ ...

随机推荐

  1. 为大家分享一个 Ajax Loading —— spin.js

    我们在做Ajax 异步请求的时候,一般都会利用一个动态的 Gif 小图片来制作一个Ajax Loading ,以便增加用户体验. 今天在网上发现了一个 Spin.js ,该 js 脚本压缩后5k,可以 ...

  2. linux命令分享(四):iostat

    简介 iostat主要用于监控系统设备的IO负载情况,iostat首次运行时显示自系统启动开始的各项统计信息,之后运行iostat将显示自上次运行该命令以后的统计信息.用户可以通过指定统计的次数和时间 ...

  3. [转载]基于TFS实践敏捷-实现用户场景

    您是新用户的 Visual Studio 应用程序生命周期管理 (ALM) 和 Team Foundation Server (TFS) 吗? 您想知道如何您和您的团队可以获得最大受益的这些工具来生成 ...

  4. ionic+nodejs开发遇到的跨域和post请求数据问题

    最近学习ionic+nodejs开发混合app中遇到了一些问题,在此总结一下. 开发环境搭建 项目地址 https://github.com/ytudt/nodejsApp 代码和问题都会在之后的学习 ...

  5. Spring MVC异常处理详解

    Spring MVC中异常处理的类体系结构 下图中,我画出了Spring MVC中,跟异常处理相关的主要类和接口. 在Spring MVC中,所有用于处理在请求映射和请求处理过程中抛出的异常的类,都要 ...

  6. 第22/24周 等待和I/O延迟统计

    大家好,欢迎回到性能调优培训的第22周.上周我谈了SQL Server里的基线,今天我们继续,谈下SQL Server里的等待和I/O延迟统计.当我进行SQL服务器健康检查时,我总会使用这2个维度全局 ...

  7. javascrpt插入html中中文字符乱码问题记录

    问题就是我使用js做这么个事情: var description = [ '你好', '你好', '你好', '你好' ]; var link = ''; var logLink = ''; ; i ...

  8. 会员管理系统的设计和开发(2)-- RDLC报表的设计及动态加载

    在上篇<会员管理系统的设计和开发(1)>介绍了关于会员系统的一些总体设计思路和要点,经过一段时间开发,软件终于完成并发布.在这期间,碰到了不少技术难点,并积累了不少开发心得和经验,本篇继续 ...

  9. .net又一个生成缩略图的方法,不变形

    生成缩略图是一个十分常用功能,找到了一个方法,重写部分代码,实用又好用,.net又一个生成缩略图的方法,不变形 /// <summary> /// 为图片生成缩略图 by 何问起 /// ...

  10. 15天玩转redis —— 第六篇 有序集合类型

    今天我们说一下Redis中最后一个数据类型 “有序集合类型”,回首之前学过的几个数据结构,不知道你会不会由衷感叹,开源的世界真好,写这 些代码的好心人真的要一生平安哈,不管我们想没想的到的东西,在这个 ...