《Python程序设计第11章-网络编程课件.pptx》由会员分享,可在线阅读,更多相关《Python程序设计第11章-网络编程课件.pptx(63页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、2023/1/1第第11章章 网络编程网络编程主 讲 人:目录目录2023/1/121.网络编程2.因特网应用层客户端3.Python网络编程实例2023/1/11.网络编程本节将简要介绍使用套接字进行网络编程的知识。在此之前,将介绍一些有关网络编程的背景信息,以及套接字如何应用于Python之中,然后展示如何使用Python的相关网络编程模块来创建网络应用程序。2023/1/11.1客户端/服务器架构什么是客户端服务器架构?1.网络编程2023/1/11.2套接字1.网络编程分为两种类型:基于文件(AF_UNIX)的和面向网络的(AF_INET)主机-端口对:合法的端口号范围为065535。
2、其中,小于1024的端口号为系统保留端口。HOST=127.0.0.1PORT=8888BUFSIZ=1024ADDR=(HOST,PORT)2023/1/11.2.1面向连接的套接字(TCP)1.网络编程 服务器端程序创建套接字(socket)。将套接字绑定到一个本地地址和端口上(bind)。将套接字设为监听模式,准备接受客户请求(listen)。等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)。用返回的套接字和客户端进行通信(send/recv)。返回,等待另一客户的请求。关闭套接字。2023/1/11.2.1面向连接的套接字(TCP)1.网
3、络编程客户端程序创建套接字(socket)。向服务器发出连接请求(connect)。和服务器端进行通信(send/recv)。关闭套接字。2023/1/11.2.2面向无连接的套接字(UDP)1.网络编程 服务器端程序服务器端程序创建套接字(socket)。将套接字绑定到一个本地地址和端口上(bind)。等待接收数据(recvfrom)。关闭套接字。客户端程序客户端程序创建套接字(socket)。向服务器发送数据(sendto)。关闭套接字。2023/1/11.3.1Python中socket模块函数1.网络编程(1)服)服务器端器端(server)创建socket对象。调用socket构造函
4、数。如:socket=socket.socket(family,type)将socket绑定到指定地址。这是通过socket对象的bind方法来实现的:socket.bind(address)2023/1/11.网络编程(1)服)服务器端器端(server)使用socket套接字的listen方法接收连接请求:socket.listen(backlog)服务器套接字通过socket的accept方法等待客户请求一个连接。connection,address=socket.accept()1.3.1Python中socket模块函数2023/1/11.网络编程(1)服)服务器端器端(server
5、)处理阶段,服务器和客户端通过send和recv方法通信(传输数据)传输结束,服务器调用socket的close方法关闭连接。1.3.1Python中socket模块函数2023/1/11.网络编程(2)客客户端(端(client)创建一个socket以连接服务器:socket=socket.socket(family,type)使用socket的connect方法连接服务器。对于AF_INET家族,连接格式如下:socket.connect(host,port)1.3.1Python中socket模块函数2023/1/11.网络编程(2)客客户端(端(client)处理阶段,客户和服务器将通
6、过send方法和recv方法通信。传输结束,客户通过调用socket的close方法关闭连接。1.3.1Python中socket模块函数2023/1/11.3.2套接字对象内置方法1.网络编程名名 称称描描 述述服务器套接字方法服务器套接字方法s.bind()将地址(主机名、端口号对)绑定到套接字上s.listen()设置并启动TCP监听器s.accept()被动接受TCP客户端连接,一直等待直到连接到达(阻塞)客户端套接字方法客户端套接字方法s.connect()主动发起TCP服务器连接s.connect_ex()connect()的扩展版本,此时会以错误码的形式返回问题,而不是抛出一个异
7、常普通的套接字方法普通的套接字方法s.recv()接受TCP消息s.recv_into()接受TCP消息到指定的缓冲区s.send()发送TCP消息s.sendall()完整地发送TCP消息s.recvfrom()接受UDP消息s.recvfrom_into()接受UDP消息到指定的缓冲区s.sendto()发送UDP消息s.close()关闭套接字2023/1/11.3.3创建TCP服务器1.网络编程伪代码:ss=socket()ss.bind()ss.listen()inf_loop:cs=ss.accept()comm_loop:cs.recv()/cs.send()cs.close()
8、ss.close()1.3.3创建TCP服务器1.网络编程1#!/usr/bin/envpython23fromsocketimport*4fromtimeimportctime56HOST=7PORT=88888BUFSIZ=10249ADDR=(HOST,PORT)1011tcpSerSock=socket(AF_INET,SOCK_STREAM)12tcpSerSock.bind(ADDR)13tcpSerSock.listen(5)1415whileTrue:16print(waitingforconnection.)17tcpCliSock,addr=tcpSerSock.accep
9、t()18print(.connectedfrom:,addr)1920whileTrue:21data=tcpCliSock.recv(BUFSIZ)22ifnotdata:23break24print(data)25tcpCliSock.send(%s%s%(ctime(),data)2627tcpCliSock.close()28tcpSerSock.close()2023/1/11.3.4创建TCP客户端1.网络编程伪代码:cs=socket()sc.connect()comm_loop:cs.send()/cs.recv()cs.close()2023/1/11.3.4创建TCP客户
10、端1.网络编程1#!/usr/bin/envpython23fromsocketimport*45HOST=127.0.0.16PORT=88887BUFSIZ=10248ADDR=(HOST,PORT)910tcpCliSock=socket(AF_INET,SOCK_STREAM)11tcpCliSock.connect(ADDR)1213whileTrue:14data=input()15ifnotdata:16break17tcpCliSock.send(data)18data=tcpCliSock.recv(BUFSIZ)19ifnotdata:20break21print(data
11、)2223tcpCliSock.close()2023/1/11.3.4运行结果1.网络编程现在,我们给出客户端对应的输入和输出,它以一个未带输入数据的简单Return(或Enter)键结束。$python/usr/tcpClie.pyhelloThuSep115:35:452016hellohowareyouThuSep115:36:092016howareyou2023/1/11.3.4运行结果1.网络编程服务器的输出主要是诊断性的。$python/usr/tcpServ.pywaitingforconnection.(.connectedfrom:,(127.0.0.1,48426)he
12、llohowareyouwaitingforconnection.2023/1/11.3.5创建UDP服务器1.网络编程UDP服务器不需要TCP服务器那么多的设置,因为它不是面向连接的。除了等待传入的连接以外,几乎不需要其他工作。ss.=socket()ss.bind()inf_loop:cs=ss.recvfrom()/ss.sendto()ss.close()2023/1/11.3.5创建UDP服务器1.网络编程1#!/usr/bin/envpython23fromsocketimport*4fromtimeimport*56HOST=7PORT=88888BUFSIZ=10249ADDR
13、=(HOST,PORT)1011udpSerSock=socket(AF_INET,SOCK_DGRAM)12udpSerSock.bind(ADDR)1314whileTrue:15print(waitingformessage.)16data,addr=udpSerSock.recvfrom(BUFSIZ)17ifnotdata:18break19print(data)20udpSerSock.sendto(%s%s%(ctime(),data),addr)21print(.receivedfromandreturnedto:,addr)2223udpSerSock.close()2023
14、/1/11.3.6创建UDP客户端1.网络编程在本节中所强调的4个客户端中,UDP客户端的代码是最短的。它的伪代码如下所示:cs=socket()somm_loop:cs.sendto/cs.recvfrom()cs.close()一旦创建了套接字对象,就进入了对话循环之中,在这里我们与服务器交换消息。最后,当通信结束时,就会关闭套接字。2023/1/11.3.6创建UDP客户端1.网络编程1#!/usr/bin/envpython23fromsocketimport*45HOST=localhost6PORT=88887BUFSIZ=10248ADDR=(HOST,PORT)910udpCl
15、iSock=socket(AF_INET,SOCK_DGRAM)1112whileTrue:13data=input()14ifnotdata:15break16udpCliSock.sendto(data,ADDR)17data,ADDR=udpCliSock.recvfrom(BUFSIZ)18ifnotdata:19break20print(data)2122udpCliSock.close()2023/1/11.3.6运行结果1.网络编程$python/usr/tsUclnt.pyHelloThuSep117:45:362016HelloWorldThuSep117:45:502016
16、World服务器的输出主要是诊断性的:$python/usr/tsUserv.pywaitingformessage.receivedfromandreturnedto:(127.0.0.1,48375)waitingformessage.2023/1/11.3.7socket模块属性1.网络编程属性名称属性名称描描 述述数据属性数据属性AF_UNIX、AF_INET、AF_INET6、AF_NETLINK、AF_TIPCPython中支持的套接字地址家族SO_STREAM、SO_DGRAM套接字类型(TCP=流,UDP=数据包)has_ipv6指示是否支持IPv6的布尔标记异常异常error
17、套接字相关错误herror主机和地址相关错误gaierror地址相关错误timeout超时时间函数函数socket()以给定的地址家族、套接字类型和协议类型(可选)创建一个套接字对象socketpair()以给定的地址家族、套接字类型和协议类型(可选)创建一对套接字对象create_connection()常规函数,它接收一个地址(主机名,端口号)对,返回套接字对象fromfd()以一个打开的文件描述符创建一个套接字对象ssl()通过套接字启动一个安全套接字层连接;不执行证书验证2023/1/11.4socketserver模块1.网络编程socketserver是标准库中的一个高级模块,它的
18、目标是简化很多样板代码,它们是创建网络客户端和服务器客户端所必需的代码。2023/1/11.4socketserver模块1.网络编程创建socketserverTCP服务器(1)socketserverTCP服务器示例首先导入服务器类,然后定义与之前相同的主机常量。其次是请求处理程序类,最后启动它。更多的细节请查看下面的代码。2023/1/11.4socketserver模块1.网络编程1#!/usr/bin/envpython23fromsocketserverimport(TCPServerasTCP,StreamRequestHandlerasSRH)4fromtimeimportct
19、ime56HOST=7PORT=88888ADDR=(HOST,PORT)910classMyRequestHandler(SRH):11defhandle(self):12print(.connectedfrom:,self.client_address)13self.wfile.write(%s%s%(ctime(),self.rfile.readline()1415tcpServ=TCP(ADDR,MyRequestHandler)16print(waitingforconnection.)17tcpServ.serve_forever()2023/1/11.4socketserver模
20、块1.网络编程创建socketserverTCP客户端如下示例所示,这里的客户端很自然地非常像最初的客户端,比服务器像得多,但必须稍微调整它以使其与新服务器很好地配合工作。1.4socketserver模块1.网络编程1#!/usr/bin/envpython23fromsocketimport*45HOST=127.0.0.16PORT=88887BUFSIZ=10248ADDR=(HOST,PORT)910whileTrue:11tcpCliSock=socket(AF_INET,SOCK_STREAM)12tcpCliSock.connect(ADDR)13data=input()14i
21、fnotdata:15break16tcpCliSock.send(%s%data)17data=tcpCliSock.recv(BUFSIZ)18ifnotdata:19break20print(data.strip()21tcpCliSock.close()2023/1/11.4socketserver模块1.网络编程执行行结果果:这里是里是socketserverTCP客客户端的端的输出出。$python/usr/tsTclntSS.pyapplicationThuSep118:32:452016applicationflashThuSep118:33:502016flash这是服是服务
22、器的器的输出出。$python/usr/tsTservSS.pywaitingforconnection.connectedfrom:(127.0.0.1,51245).connectedfrom:(127.0.0.1,51246)目录目录2023/1/121.网络编程2.因特网应用层客户端3.Python网络编程实例2023/1/12.因特网应用层客户端前一节介绍了使用套接字的底层网络通信协议。这种类型的网络是当今因特网中大部分客户端/服务器协议的核心。这些网络协议分别用于文件传输(FTP、SCP等)、阅读新闻组(NNTP)、发送电子邮件(SMTP)和从服务器上下载电子邮件(POP3、IMA
23、P)等。协议的工作方式与前一节介绍的客户端/服务器的例子相似。唯一的区别在于现在使用TCP/IP这样底层的协议来创建新的、有专门用途的协议,以此来实现刚刚介绍的高层服务。2023/1/12.因特网应用层客户端2.1.1文件文件传输因特网协议传输因特网协议因特网中最常见的事情就是传输文件。文件传输每时每刻都在发生。有很多协议可以用于在因特网上传输文件,最流行的包括文件传输协议(FTP)、UNIX到UNIX复制协议(UUCP)、用于Web的超文本传输协议(HTTP)。另外,还有(UNIX下的)远程文件复制命令rcp(以及更安全、更灵活的scp和rsync)。2023/1/12.因特网应用层客户端2
24、.1.2文件传输协议其工作流程如下。(1)客户端连接远程主机上的FTP服务器。(2)客户端输入用户名和密码(或“anonymous”和电子邮件地址)。(3)客户端进行各种文件传输和信息查询操作。(4)客户端从远程FTP服务器退出,结束传输。2023/1/12.因特网应用层客户端2.1.2文件传输协议在底层,FTP只使用TCP,而不使用UDP。另外,可以将FTP看作客户端/服务器编程中的特殊情况。因为这里的客户端和服务器都使用两个套接字通信:一个是控制和命令端口(21号端口),另一个是数据端口(有时是20号端口),如下图所示。2023/1/12.因特网应用层客户端2.1.2文件传输协议FTP有两
25、种模式主动和被动。只有在主动模式下服务器才使用数据端口。在服务器把20号端口设置为数据端口后,它“主动”连接客户端的数据端口;而在被动模式下,服务器只是告诉客户端随机的数据端口号,客户端必须主动建立数据连接。在这种模式下,FTP服务器在建立数据连接时是“被动”的。2023/1/12.因特网应用层客户端2.1.3ftplib.FTP类的方法在一般的FTP事务中,要使用到的指令有login()、cwd()、dir()、pwd()、stor*()、retr*()和quit()。下表列出了最常用的方法,这个表中列出的方法涵盖了Python中进行FTP客户端编程所需的API,其他没有列出的方法并不是必需
26、的,因为其他方法要么提供辅助或管理功能,要么提供给这些API使用。2.因特网应用层客户端2.1.3ftplib.FTP类的方法方方 法法描描 述述login(user=anonymous,passwd=,acct=)登录FTP服务器,所有参数都是可选的pwd()获得当前工作目录cwd(path)把当前工作目录设置为path所示的路径dir(path,cb)显示path目录里的内容,可选的参数cb是一个回调函数,会传递给retrlines()方法nlst(path,)与dir()类似,但返回一个文件名列表,而不是显示这些文件名retrlines(cmd,cb)给定FTP命令(如“STORfile
27、name”),用来下载文本文件。可选的回调函数cb用于处理文件的每一行rename(old,new)把远程文件old重命名为newdelete(path)删除位于path的远程文件mkd(directory)创建远程目录rmd(directory)删除远程目录quit()关闭连接并退出2023/1/12.因特网应用层客户端2.1.4FTP客户端程序示例下面的程序是将某台Linux服务器上的600多万个数据文件移到另一台Linux服务器,所有文件的文件名遵循一定的规范,程序成功自动移动了所有文件。2023/1/12.因特网应用层客户端2.1.4FTP客户端程序示例下面的程序是将某台Linux服务
28、器上的600多万个数据文件移到另一台Linux服务器,所有文件的文件名遵循一定的规范,程序成功自动移动了所有文件。见书上(P264、P265)2023/1/12.因特网应用层客户端2.1.5FTP的其他内容以下是一些典型的FTP客户端类型。命令行客户端程序:使用一些FTP客户端程序(如/bin/ftp或NcFTP)进行FTP传输,用户可以在命令行中交互执行FTP传输。GUI客户端程序:与命令行客户端程序相似,但它是一个GUI程 序,如 WS_FTP、Filezilla、CuteFTP、Fetch、SmartFTP。2023/1/12.因特网应用层客户端2.1.5FTP的其他内容Web浏览器:除
29、了使用HTTP之外,大多数Web浏览器(也称为客户端)可以进行FTP传输。URL/URI的第一部分就用来表示所使用的协议,如“http:/blahblah”。这就告诉浏览器要使用HTTP作为与指定网站传输数据的协议。用过修改协议部分,就可以发送使用FTP的请求,如“ftp:/blahblah”,这与使用HTTP的网页URL很像。自定义应用程序:自己编写的用于FTP文件传输的程序。这些是用于特殊目的的应用程序,一般这种程序不允许用户与服务器交互。2023/1/12.因特网应用层客户端2.2.1网络新闻Usenet新闻系统是一个全球存档的“电子公告档”。系统中各种主题的新闻组一应俱全,从诗歌到政治
30、,从自然语言学到计算机语言,从软件到硬件,从种植到烹饪,招聘/应聘,音乐等。新闻组可以面向全球,也可以只面向某个特定区域。整个系统是一个由大量计算机组成的庞大的全球网络,计算机之间共享Usenet上的帖子。如果某个用户发了一个帖子到本地的Usenet计算机上,这个帖子会被传播到其他相连的计算机上,再由这些计算机传到与它们相连的计算机上,直到这个帖子传播到了全世界,每个人都收到这个帖子为止。帖子在Usenet上的存活时间是有限的,这个时间可以由Usenet系统管理员来指定,也可以为帖子指定一个过期的日期/时间。2023/1/12.因特网应用层客户端2.2.2网络新闻传输协议用户使用网络新闻传输协
31、议(NNTP)在新闻组中下载或发表帖子。该协议由BrainKantor(加州大学圣地亚哥分校)和PhilLapsley(加州大学伯克利分校)创建并记录在RFC977中,于1986年2月公布。其后在2000年10月公布的RFC2980中对该协议进行了更新。作为客户端/服务器架构的另一个例子,NNTP与FTP的操作方式相似,但更简单。在FTP中,登录、传输数据和控制需要使用不同的端口,而NNTP只使用一个标准端口119来通信。用户向服务器发送一个请求,服务器就做出相应的响应,如下图所示。2023/1/12.因特网应用层客户端2.2.2网络新闻传输协议2023/1/12.因特网应用层客户端2.2.3
32、Python和NNTP由于以前已经有了Python和FTP的经验,读者也许可以猜到,有一个nntplib库和一个需要实例化的nntplib.NNTP类。与FTP一样,所要做的就是导入这个Python模块,然后调用相应的方法。先大致看一下这个协议。(1)连接到服务器。(2)登录(根据需要)。(3)发出服务请求。(4)退出。是不是有点熟悉?是的,这与FTP协议极其相似。唯一的区别是根据NNTP服务器配置的不同,登录这一步是可选的。2023/1/12.因特网应用层客户端2.2.3Python和NNTP下面是一段Python伪代码。frommmtplibimportNNTPn=NNTP(your.nn
33、tp.server)r,c,f,l,g=n.group(comp.lang.python)n.quit()一般来说,登录后需要调用group()方法来选择一个感兴趣的新闻组。该方法返回服务器的回复、文章的数量、第一篇和最后一篇文章的ID、新闻组的名称。有了这些信息后,就可以做一些其他操作,如从头到尾浏览文章、下载整个帖子(文章的标题和内容),或者发表一篇文章等。在展示真实的例子之前,先介绍一下nntplib.NNTP类的一些常用方法。2.因特网应用层客户端2.2.4nntplib.NNTP类方法方方 法法描描 述述group(name)选择一个组的名字,返回一个元祖(rsp,ct,fst,ls
34、t,group),分别表示服务器响应信息、文章数量、第一个和最后一个文章的编号、组名,所有数据都是字符串(返回的group与传进去的name应该是相同的)xhdr(hdr,artrg,ofile)返回文章范围artrg(“头-尾”的格式)内文章hdr头的列表,或把数据输出到文件ofile中body(id,ofile)根据id获取文章正文,id可以是消息的ID,也可以是文章编号(以字符串形式表示),返回一个元组(rsp,anum,mid,data),分别表示服务器响应信息、文章编号(以字符串形式表示)、消息ID、文章所有行的列表,或把数据输出到文件ofile中head(id)与body()类似,
35、返回相同的元组,只是返回的行列表中只包括文章的标题article(id)同样与body()类似,返回相同的元组,只是返回的行列表中同时包括文章标题和正文stat(id)让文章的“指针”指向id(即前面的消息ID或文章编号)。返回一个与body()相同的元组(rsp,anum,mid),但不包括文章的数据next()用法和stat()类似,把文章指针移到下一篇文章,返回与stat()相似的元组last()用法和stat()类似,把文章指针移到最后一篇文章,返回与stat()相似的元组post(ufile)上传ufile文件对象里的内容(使用ufile.readline()),并发布到当前新闻组中
36、quit()关闭连接并退出2023/1/12.因特网应用层客户端2.2.4nntplib.NNTP类方法NNTP客户端程序示例(1)NNTP客户端程序下面为NNTP从“web.aioe.org”获取新闻的一个简单例子。#!/usr/bin/envpythonfromnntplibimport*s=NNTP(web.aioe.org)(resp,count,first,last,name)=s.group(comp.lang.python)(resp,subs)=s.xhdr(subject,(str(first)+-+str(last)forsubjectinsubs-10:print(sub
37、ject)number=input(Whicharticledoyouwanttoread?)(reply,num,id,list)=s.body(str(number)forlineinlist:2023/1/12.因特网应用层客户端2.2.4nntplib.NNTP类方法(2)运行结果Python 3.5.2(v3.5.2:4def2a2901a5,Jun 25 2016,22:01:18)MSC v.1900 32 bit(Intel)onwin32Typecopyright,creditsorlicense()formoreinformation.RESTART:C:UsersAdmi
38、nistratorAppDataLocalProgramsPythonPython35-32nntp.py(179456,Re:manuallysortingimages?)(179457,Re:Extend unicodedata with a name/pattern/regex search for character entityreferences?)(179458,Re:Whydoesntmyfinaliserrunhere?)(179459,Re:Extend unicodedata with a name/pattern/regex search for character e
39、ntityreferences?)(179460,Re:manuallysortingimages?)(179461,Re:Whydoesntmyfinaliserrunhere?)(179462,Re:Whydoesntmyfinaliserrunhere?)(179463,Re:Extend unicodedata with a name/pattern/regex search for character entityreferences?)(179464,Re:manuallysortingimages?)(179465,Re:Whydoesntmyfinaliserrunhere?)Whicharticledoyouwanttoread?2023/1/12.因特网应用层客户端2.2.5NNTP的其他内容关于NNTP的更多内容,可阅读NNTP协议定义/规范(RFC977),参见http:/tools.ietf.org/html/rfc977和http:/