python学习笔记(十 三)、网络编程

最近心情有点儿浮躁,难以静下心来

 

  Python提供了强大的网络编程支持,很多库实现了常见的网络协议以及基于这些协议的抽象层,让你能够专注于程序的逻辑,而无需关心通过线路来传输比特的问题。

1 几个网络模块

  1.1 模块socket

  网络编程中的一个基本组件是套接字(socket)。套接字基本上是一个信息通道,两端各有一个程序。这些程序可能位于(通过网络相连接的)不同的计算机上,通过套接字向对方发送消息。在Python中,大多数网络编程都隐藏了模块socket的基本工作原理,不与套接字直接交互。

  套接字分为两类:服务端套接字和客户端套接字。创建服务端套接字后,让它等待连接请求的到来。这样,它将在某个网络地址(由IP地址和端口号组成)处监听,知道客户端套接字建立连接,还必须处理多个连接;而客户端套接字只需连接,完成任务后再断开连接即可。

  套接字是模块socket中socket类的实例。实例化套接字时最多可指定三个参数:一个地址族(默认为socket.AF_INET);是流套接字(socket.SOCK_STREAM,默认设置)还是数据报套接字(socket.SOCK_DGRAM);协议(使用默认值0就好)。

  服务器套接字先调用方法bind,在调研方法listen来监听特定的地址。然后,客户端套接字通过调用方法connect并提供bind时指定的地址来连接服务端。这里的地址是一个格式为(host, port)的元祖,其中host是主机名,port是端口号。方法listen接收一个参数——代办任务清单的长度(即最多可有多少个连接在队列中等待接纳,到达这个数量后将开始拒绝连接)。

  服务端套接字开始监听后,就可接收客户端连接,使用方法accept来等待连接。这个方法将阻断(等待)到客户端连接到来为止(有点类似与yield关键字),然后返回一个格式为(client, address)的元组,其中client为客户端套接字,而address为地址。服务端能以其认为合适的方式处理客户端连接,然后再次调用accept以等待新连接到来。

  为传输数据,套接字提供了两个方法:send-发送和recv-接收(表示receive),这两个方法都是接收或发送字节流数据。

  简单的服务器:

import socket#创建套接字
s = socket.socket()#获取主机名
host = socket.gethostname()
#端口号
port = 8080
address = (host, port)
#创建连接
s.bind(address)#监听:最大连接数为5
s.listen(5)
while True:#等待连接client, addr = s.accept()#接收消息str = bytes.decode(client.reve(1024))#发送消息client.send(str.encode('我是服务端!','utf-8'))

  简单的客服端:

import socket
s = socket.socket()#连接服务端地址
host = socket.gethostname()
port = 8080
address = (host, port)
#连接
s.connect(address)
#接收消息
str = bytes.decode(s.reve(1024))
#发送消息
s.sent(str.encode('我是客户端!','utf-8'))

  1.2 模块urllib和urllib2

  模块urllib和urllib2,由名字可知,它们让你能够通过网络访问文件,就像这些文件位于你的计算机中一样。只需一个简单的函数调用,就几乎可将统一资源定位符(URL)可指向的任何动作作为程序的输入。这两个模块一般用于下载网页、从中提取信息自动生成研究报告等。对于简单的操作,urllib绰绰有余,如果要实现HTTP身份验证或Cookie,或编写扩展来处理自己的协议,urllib2可能是更好的选择。

  1.2.1 打开远程文件

  使用模块urllib.request中的函数urlopen来打开远程文件,只能进行读取操作。如:

  from urllib.request import urlopen

  page = urlopen('www.baidu.com')

  如果连接到网络,变量page将包含一个类似于文件的对象,这个对象与你所连接的地址相关联。urlopen返回类似于文件的对象支持方法clost、read、readline和readlines,还支持迭代等。

  1.2.2 获取远程文件

  函数urlopen返回一个类似于文件的对象,可从中读取数据。如果要让urllib替你下载文件,并将其副本存储在本地,可使用urllib.request中的函数urlretrieve。这个函数返回一个格式为(filename, headers)的元祖,其中filename是本地文件的名称(由urllib自动创建),而headers包含一些有关远程文件的信息。如果要给下载的副本指定文件名,可通过函数urlretrieve的第二个参数来指定。

  函数格式为: urlretrieve(url, filename=None, reporthook=None, data=None),函数urlretrieve将url中的内容存储在filename中,如果filename没有指定,下载的副本将放在某个临时位置,可使用函数open来打开。但使用完毕后,你可能想将其删除,以免暂用磁盘空间,可调用函数urlcleanup来替你完成清除工作。

  1.2.3 其他模块

  Python标准库提供了一些与网络相关的模块,如下(只列举了一些常用的):

  cgi            基本的CGI文件

  asyncore        异步套接字处理程序

  asynchat        包含补充asyncore的功能

  Cookie           Cookie对象操作,主要用于服务器

  cookielib        客户端Cookie支持

  email           电子邮件支持

  ftplib          FTP客户端模块

  httplib           HTTP客户端模块

  mailbox          读取多种邮箱格式

  urlparse          用于解读URL

2 SocketServer及相关的类

  模块SocketServer是标准库提供的服务器框架的基石,这个框架包括BaseHTTPServer、SimpleHTTPServer、CGIHTTPServer、SimpleXMLRPCServer和DocXMLRPCServer等服务器,它们在基本服务器的基础上添加了各种功能。

  SocketServer包含4个基本的服务器:TCPServer(支持TCP套接字流)、UDPServer(支持UDP套接字流)、UnixStreamServer和UnixDatagramServer。后面3个不常用。

  使用模块SocketServer编写服务器时,大部分代码都位于请求处理中。每当服务器收到客户端的连接请求时,都将实例化一个请求处理程序,并对其调用各种处理方法来处理请求。基本请求处理程序类BaseRequestHandler将所有操作都放在一个方法中——服务器自动调用的方法handle。这个方法可通过书信self.request来访问客户端套接字。如果处理的是流(TCPServer时很可能如此),可使用StreamRequestHandler类,它包含另外两个属性:self.rfile(用于读取)和self.wfile(用于写入)。你可以使用这两个类似与文件的对象来与客户端通信。

  模块SocketServer还包含很多其他的类,它们为HTTP服务器提供基本的支持,以及XML-RPC支持。

  

from socketserver import TCPServer,StreamRequestHandlerclass Handle(StreamRequestHandler):def handle(self):addr = self.request.getpeername()print("addr:", addr)self.wfile.write("谢谢")server = TCPServer(('',1234), Handle)
server.serve_forever()

3 多个连接

  处理多个连接的主要方式有三种:分叉(forking)、线程化和异步I/O。通过结合使用SocketServer中的混合类和服务器类,很容易实现分叉和线程化。但是,分叉占用资源较多,且在客户端很多时可伸缩性不高;而线程化可能带来同步问题。并且Windows不支持分叉,分叉是UNIX术语。

  3.1 使用SocketServer实现分叉和线程化

  使用框架SocketServer创建分叉或线程化服务器非常简单,一般仅当方法handle需要很长时间才能执行完毕是,分叉和线程化才能提供有效帮助。创建如下:

  1.分叉服务器

from socketserver import TCPServer,StreamRequestHandler,ForkingMixInclass Server(ForkingMixIn, TCPServer):passclass Handle(StreamRequestHandler):def handle(self):addr = self.request.getpeername()print("addr:", addr)self.wfile.write("谢谢")server = Server(('',1234), Handle)
server.serve_forever()

  2.线程化服务器

from socketserver import TCPServer,StreamRequestHandler,ThreadingMixInclass Server(ThreadingMixIn, TCPServer):passclass Handle(StreamRequestHandler):def handle(self):addr = self.request.getpeername()print("addr:", addr)self.wfile.write("谢谢")server = Server(('',1234), Handle)
server.serve_forever()

  3.2 使用select和poll实现异步I/O

  当服务器与客户端通信时,来自客户端的数据可能时断时续。如果使用了分叉和线程化,这就不是问题:因为一个进程(线程)等待数据时,其他进程(线程)可继续处理其客户端。然而,另一种做法是只处理正在通信的客户端。你甚至无需不断监听,只需监听后将客户端加入队列即可。

  这就是框架asyncore/asynchat 和 Twisted采取的方法。这种功能的基石是函数select或poll(只支持UNIX系统)。这两个函数都位于模块select中,其中poll的可伸缩性更高。

  函数select接收三个必不可少的参数和一个可选参数,其中前三个参数为序列,而第四个参数为超时时间(单位为秒)。这些序列包含文件描述符整数(也可以是包含返回文件描述符整数的方法fileno),表示我们正在等待的连接。这三个序列分别表示需要输入和输出以及发生异常(错误等)的连接。如果没有指定超时时间,select将阻断(即等待)到有文件描述符准备就绪;如果指定了超时时间,select将最多阻断指定的秒数;如果超时时间为0,select将不断轮询(即不阻断)。select返回三个序列(即一个长度为3的元祖),其中每个序列都包含相应参数中处于活动状态的文件描述符。

  如下所示,一个使用select的简单服务器:import socket, select

s = socket.socket()
host = socket.gethostname()
port = 8080
s.bind((host,port))
s.listen(5)
inputs = [s]
while True:
   # 方法select返回三个参数,通过序列解包赋值rs, ws, es
= select.select(inputs, [], [])for r in rs:if r is s:c, addr = s.accept()print("addr:", addr)inputs.append(c)else:try:data = r.reve(1024)discon = not dataexcept socket.error:discon = Trueif discon:
          # 1.getpeername():用于获取与某个套接字关联的外地协议地址
         # 2.getsockname():用于获取与某个套接字关联的本地协议地址
print(r.getpeername(), 'discon')inputs.remove(r)else:print(data)

  方法poll 使用起来比select容易。调用poll 时,将返回一个轮询对象。你可以使用方法register 向这个对象注册文件描述符(或包含方法fileno的对象)。注册后可使用方法unregister 将它们删除。注册对象(如套接字)后,可调用其方法poll(它接受一个可选的超时时间参数)。这将返回一个包含(fd, event)元祖的列表(可能为空),其中fd为文件描述符,event是发生的事件。event是一个位掩码,这意味着它是一个整数,其各个位对应于不同的事件。各种事件是用select 模块中的常量表示的,如下表。要检查指定的位是否为1 (即是否发生了相应的事件),可使用按位与运算符( & ):

  if event & select.POLLIN: pase

  事件名              描述

  POLLIN               文件描述符中有需要读取的数据

  POLLPRI               文件描述符中有需要读取的 紧急数据

  POLLOUT                   文件描述符为写入数据做好了准备

  POLLERR              文件描述符出现了错误状态

  POLLHUP              挂起。连接已断开

  POLLNVAL             无效请求。连接未打开

  

  下面是一个使用poll的简单服务器:

import socket, select
s = socket.socket()host = socket.gethostname()
port = 8080
s.bind((host, port))fdmp = {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 fdmp:c, addr = s.accept()print("addr:", addr)p.register(c)fdmp[c.fileno()] = celif event & select.POLLIN:data = fdmp[fd].recv(1024)if not data:print(fdmp[fd].getpeername(),"discon")p.unregister(fd)del fdmp[fd]else:print(data)

4 Twisted

  这是Twisted Matrix Laboratories 开发的一个框架,功能丰富而复杂,支持大多数主要的网络协议。框架Twisted是异步的,因此效率和可伸缩性都非常高。对很多自定义网络应用程序来说,使用Twisted来开发可能是最佳选择。

转载于:https://www.cnblogs.com/www-123456/p/10638868.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/425202.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Leetcode][第174题][JAVA][地下城游戏][DFS][动态规划]

【问题描述】[中等] 【解答思路】 1. 回溯(暴力)& 优化 超时,需要优化 public int calculateMinimumHP(int[][] dungeon) {if (dungeon null || dungeon.length 0 || dungeon[0].length 0) {return 0;}int rowLen dungeon.length;in…

第十期:快来了解这五种热门的开发技能

开发人员是热门的工作岗位之一,在Indeed网站的2019年最热门工作排行榜上名次靠前。随着企业对数字化转型项目的需求不断增加,对能够开发这些数字化应用软件的个人的需求随之而来。 开发人员是热门的工作岗位之一,在Indeed网站的2019年最热门工…

蓝桥杯 平方十位数

2017 国赛c/c B组填空题集合平方十位数由0~9这10个数字不重复、不遗漏,可以组成很多10位数字。这其中也有很多恰好是平方数(是某个数的平方)。比如:1026753849,就是其中最小的一个平方数。请你找出其中最大的一个平方数…

PHP常见面试题

1.mvc是什么?相互间有什么关系? 答:mvc是一种开发模式,主要分为三部分:m(model),也就是模型,负责数据的操作;v(view),也就是视图,负责前后台的显示;c(controller),也就是控制器,负责业务逻辑 客户端请求项目的控制器,如果执行过程中需要用到数据,控制器就会到模型中获取数据,…

第十一期:数据挖掘其实就是为了干这四种事?

数据挖掘主要侧重解决四类问题:分类、聚类、关联、预测。数据挖掘非常清晰的界定了它所能解决的几类问题。这是一个高度的归纳,数据挖掘的应用就是把这几类问题演绎的一个过程。 数据挖掘最重要的要素是分析人员的相关业务知识和思维模式。一般来说&…

[剑指offer]面试题第[49]题[Leetcode][第264题][JAVA][丑数][动态规划][堆]

【问题描述】[中等] 【解答思路】 1. 动态规划 时间复杂度&#xff1a;O(N) 空间复杂度&#xff1a;O(N) class Solution {public int nthUglyNumber(int n) {int a 0, b 0, c 0;int[] dp new int[n];dp[0] 1;for(int i 1; i < n; i) {int n2 dp[a] * 2, n3 dp[…

第十二期:常用的几种大数据架构剖析

常用的几种大数据架构剖析 随着大数据技术的发展&#xff0c;数据挖掘、数据探索等专有名词曝光度越来越高&#xff0c;但是在类似于Hadoop系列的大数据分析系统大行其道之前&#xff0c;数据分析工作已经经历了长足的发展&#xff0c;尤其是以BI系统为主的数据分析&#xff0…

【大数据】获取一篇新闻的全部信息

作业要求来自于&#xff1a;https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/2894 给定一篇新闻的链接newsUrl&#xff0c;获取该新闻的全部信息 标题、作者、发布单位、审核、来源 发布时间:转换成datetime类型 点击&#xff1a; newsUrlnewsId(使用正则表达式re)cl…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第14篇]什么是基于线性对的密码学

这是最新的一期密码学52件事.我们基于前几周介绍一种"对"的概念. 对的定义 给定三个循环群G1,G2,G3,它们的基为q,生成器分别为g1,g2,g3.我们说一个函数e:G1G2→G3是一个密码对如果下面的等式都成立. [双线性]∀A,B∈G1,C,D∈G2:e(AB,C)e(A,C)⋅e(B,C),同时e(A,CD)…

第十五期:真相了,中台到底“出路”还是“末路”?

从 2015 年开始&#xff0c;到 2019 年现在为止&#xff0c;各大公司都在吹捧中台理念。 从 2015 年开始&#xff0c;到 2019 年现在为止&#xff0c;各大公司都在吹捧中台理念。 仿佛中台是业务复杂性的救世主&#xff0c;是某些架构师和 PM 的新出路&#xff0c;各种割韭菜的…

蓝桥杯 2017 国赛B组C/C++【对局匹配】

题意就是给我们一串数 让我们尽可能地取 约束条件是a[i] 和a[i]k不能同时出现 所有元素之间相差k的元素都不能同时出现 让我们求所能取到的最大的数的和是多少分析&#xff1a; dp思路&#xff0c;这个和树形dp有点相似 就是枚举0~k 然后在每个这个元素上迭代加k 每个元素保存…

架构师成长之路:如何保证消息队列的高可用

问题一&#xff1a;描述一下 JVM 的内存区域    程序计数器&#xff08;PC&#xff0c;Program Counter Register&#xff09;。在 JVM 规范中&#xff0c;每个线程都有它自己的程序计数器&#xff0c;并且任何时间一个线程都只有一个方法在执行&#xff0c;也就是所谓的当…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第27篇]什么是对称密码加密的AEAD安全定义?

这是一系列博客文章中最新的一篇&#xff0c;该文章列举了“每个博士生在做密码学时应该知道的52件事”:一系列问题的汇编是为了让博士生们在第一年结束时知道些什么。这篇文章将从“安全定义和证明”一节开始&#xff0c;对认证加密进行简要概述。 AEAD Luke在最近的一篇文章…

dell的boot设置

1.开机后不久会有屏幕提示&#xff0c;然后按提示按F2就可以进入BIOS的界面了。也可以按F12后选择在菜单中选择"BIOS SETUP”进入。 2.设置BIOS时间:进入BIOS后&#xff0c;用左右箭头移动到“MAIN”选项,一般进入默认就是它&#xff0c;然后用上下箭头移动到System Time…

[转帖]Docker 清理占用的磁盘空间

Docker(二十七)-Docker 清理占用的磁盘空间 https://www.cnblogs.com/zhuochong/p/10076599.htmldocker system docker network一系列的docker 命令 感觉挺有裨益的 去年的时候还用过 一段时间不用 忘记的干干净净了. 1. docker system命令 docker system df命令&#xff0c;类…

2017蓝桥杯决赛-发现环 数据结构|搜索

问题描述小明的实验室有N台电脑&#xff0c;编号1~N。原本这N台电脑之间有N-1条数据链接相连&#xff0c;恰好构成一个树形网络。在树形网络上&#xff0c;任意两台电脑之间有唯一的路径相连。不过在最近一次维护网络时&#xff0c;管理员误操作使得某两台电脑之间增加了一条数…

第十七期:详解大数据处理中的Lambda架构和Kappa架构

在这张架构图中&#xff0c;大数据平台里面向用户的在线业务处理组件用褐色标示出来&#xff0c;这部分是属于互联网在线应用的部分&#xff0c;其他蓝色的部分属于大数据相关组件&#xff0c;使用开源大数据产品或者自己开发相关大数据组件。 典型互联网大数据平台架构 首先我…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第28篇]什么是公钥密码学的IND-CCA安全定义?

这是一系列博客文章中最新的一篇&#xff0c;该文章列举了“每个博士生在做密码学时应该知道的52件事”:一系列问题的汇编是为了让博士生们在第一年结束时知道些什么。讨论了用于公钥加密的IND-CCA安全性。 IND-CCA安全代表选择明文的不可伪造性。这样的安全方案的思想就是给定…

玩转oracle 11g(51):select t.*,t.rowid

select t.*,t.rowid from wii_device_master t; ‘ 点开解锁 复制ctrlc crtl v加入新的值 很简单&#xff0c;sql语句后面加上for update即可&#xff1a; 但是今天遇到一种情况&#xff0c;无法对该表进行修改&#xff0c;因为这样会锁表的 下面这样写比较好&#xff0c;也…

[小技巧][Markdown]上标 /下标 上下角标

标签写法效果上标2 10 上标2 10下标H2O下标H2O //上标 2<sup> 10 </sup> 2 ^10^ //下标 H<sub>2</sub>O H~2~O//上标 2 10 2 10 //下标 H2O H2O [总结] 1.上标 sup标签 &#xff1a; <sup> 内容 </sup> ^ : ^内容^2.下标 sub标…