当前位置: 首页 > article >正文

Python学习笔记14:网络编程

网络编程

几个网络模块

  1. 模块socket
# 简单的服务器
import socket 
s = socket.socket() 

host = socket.gethostname() 
port = 1234 
s.bind((host, port))

s.listen(5)
while True: 
    c, addr = s.accept() 
    print('Got connection from', addr) 
    c.send('Thank you for connecting')
    c.close()

# 简单的客户端
import socket 
s = socket.socket() 

host = socket.gethostname() 
port = 1234 

s.connect((host, port))
print(s.recv(1024))

  1. 模块urllib和urllib2

打开远程文件:urlopen

>>> from urllib.request import urlopen 
>>> webpage = urlopen('http://www.python.org')

>>> import re 
>>> text = webpage.read() 
>>> m = re.search(b'<a href="([^"]+)" .*?>about</a>', text, re.IGNORECASE) 
>>> m.group(1) 
'/about/'

获取远程文件:urlretrieve

>>> urlretrieve('http://www.python.org', 'C:\\python_webpage.html')

清空这样的临时文件:urlcleanup

  1. 其他模块

标准库中一些与网络相关的模块

模块描述
asynchat包含补充asyncore的功能(参见第24章)
asyncore异步套接字处理程序(参见第24章)
cgi基本的CGI支持(参见第15章)
CookieCookie对象操作,主要用于服务器
cookielib客户端Cookie支持
email电子邮件(包括MIME)支持
ftplibFTP客户端模块
gopherlibGopher客户端模块
httplibHTTP 客户端模块
imaplibIMAP4客户端模块
mailbox读取多种邮箱格式
mailcap通过mailcap文件访问MIME配置
mhlib访问MH邮箱
nntplibNNTP客户端模块(参见第23章)
poplibPOP客户端模块
robotparser解析Web服务器robot文件
SimpleXMLRPCServer一个简单的XML-RPC服务器(参见第27章)
smtpdSMTP服务器模块
smtplibSMTP客户端模块
telnetlibTelnet客户端模块
urlparse用于解读URL
xmlrpclibXML-RPC客户端支持(参见第27章)

SocketServer

  • 4个基本服务器:TCPServer(支持TCP套接字流)、UDPServer(支持UDP数据报套接字)以及更难懂的UnixStreamServerUnixDatagramServer。
  • 请求处理器:基本请求处理程序类BaseRequestHandler将所有操作都放在一个方法中——服务器调用的方法handle。这个方法可通过属性self.request来访问客户端套接字。可使用StreamRequestHandler类,它包含另外两个属性:self.rfile(用于读取)和self.wfile(用于写入)。
# 基于SocketServer的极简服务器
from socketserver import TCPServer, StreamRequestHandler 
class Handler(StreamRequestHandler): 
    def handle(self): 
    addr = self.request.getpeername() 
    print('Got connection from', addr) 
    self.wfile.write('Thank you for connecting') 

server = TCPServer(('', 1234), Handler) 
server.serve_forever()

多个连接

  • 分叉(forking) 占用的资源较多,且在客户端很多时可伸缩性不佳(但只要客户端数量适中,分叉在现代UNIX和Linux系统中的效率很高。如果系统有多个CPU,效率就更高了)
  • 线程化 可能带来同步问题
  • 异步I/O
  1. 使用 SocketServer 实现分叉和线程化
# 分叉服务器
from socketserver import TCPServer, ForkingMixIn, StreamRequestHandler 

class Server(ForkingMixIn, TCPServer): pass 

class Handler(StreamRequestHandler): 
    def handle(self): 
    addr = self.request.getpeername() 
     print('Got connection from', addr) 
    self.wfile.write('Thank you for connecting') 

server = Server(('', 1234), Handler) 
server.serve_forever()

# 线程化服务器
from socketserver import TCPServer, ThreadingMixIn, StreamRequestHandler 

class Server(ThreadingMixIn, TCPServer): pass 

class Handler(StreamRequestHandler): 
    def handle(self): 
    addr = self.request.getpeername() 
    print('Got connection from', addr) 
    self.wfile.write('Thank you for connecting') 

server = Server(('', 1234), Handler) 
server.serve_forever()

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

当服务器与客户端通信时,来自客户端的数据可能时断时续

  • 分叉和线程化:一个进程(线程)等待数据时,其他进程(线程)可继续处理其客户端。
  • 异步I/O:只处理当前正在通信的客户端。你甚至无需不断监听,只需监听后将客户端加入队列即可。
# 使用select的简单服务器
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: 
            c, addr = s.accept() 
            print('Got connection from', addr) 
            inputs.append(c) 
    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的简单服务器
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: # 没有数据 --连接已关闭
                print(fdmap[fd].getpeername(), 'disconnected') 
                p.unregister(fd)
                del fdmap[fd] 
            else: 
                print(data)

Twisted

基于事件:要编写简单的服务器,只需实现处理如下情形的事件处理程序:客户端发起连接,有数据到来,客户端断开连接(以及众多其他的事件)。专用类可在基本类的基础上定义更细致的事件,如包装“数据到来”事件,收集换行符之前的所有数据再分派“数据行到来”事件。

# 使用Twisted创建的简单服务器
from twisted.internet import reactor 
from twisted.internet.protocol import Protocol, Factory 

class SimpleLogger(Protocol): 
     def connectionMade(self): 
        print('Got 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(1234, factory) 
reactor.run()

PS:你不能使用事件处理策略来向客户端发送数据。这种工作是使用对象self.transport完成的,它包含一个write方法。这个对象还有一个client属性,其中包含客户端的地址(主机名和端口)。

小结

套接字和模块socket:套接字是让程序(进程)能够通信的信息通道,这种通信可能需要通过网络进行。模块socket让你能够在较低的层面访问客户端套接字和服务器套接字。服
务器套接字在指定的地址处监听客户端连接,而客户端套接字直接连接到服务器。

urllib和urllib2:这些模块让你能够从各种服务器读取和下载数据,为此你只需提供指向数据源的URL即可。模块urllib是一种比较简单的实现,而urllib2功能强大、可扩展
性极强。这两个模块都通过诸如urlopen等函数来完成工作。

框架SocketServer:这个框架位于标准库中,包含一系列同步服务器基类,让你能够轻松地编写服务器。它还支持使用CGI的简单Web(HTTP)服务器。如果要同时处理多个连
接,必须使用支持分叉或线程化的混合类。

select和poll:这两个函数让你能够在一组连接中找出为读取和写入准备就绪的连接。这意味着你能够以循环的方式依次为多个连接提供服务,从而营造出同时处理多个连接的
假象。另外,相比于线程化或分叉,虽然使用这两个函数编写的代码要复杂些,但解决
方案的可伸缩性和效率要高得多。

Twisted:这是Twisted Matrix Laboratories开发的一个框架,功能丰富而复杂,支持大多数主要的网络协议。虽然这个框架很大且其中使用的一些成例看起来宛如天书,但其基本用法简单而直观。框架Twisted也是异步的,因此效率和可伸缩性都非常高。对很多自定
义网络应用程序来说,使用Twisted来开发很可能是最佳的选择。


http://www.kler.cn/a/267.html

相关文章:

  • rk3568 上Qt5.12.12迁移问题解决
  • 基于单片机的肺功能MVV简单测算
  • 单片机-串转并-74HC595芯片
  • 电子应用设计方案86:智能 AI背景墙系统设计
  • Cursor连接腾讯云Cloud Studio开发环境
  • 第15章 汇编语言--- 数组与指针
  • <Linux开发> linux应用开发-之-socket通信开发例程
  • C++面经总结1
  • 游戏蓝牙耳机哪款比较好?游戏党推荐四款好用的低延迟蓝牙耳机
  • 有什么外观漂亮的蓝牙耳机?高颜值真无线蓝牙耳机推荐
  • 蓝桥杯第五天刷题
  • Promise链式调用
  • 现在的00后,实在是太卷了
  • 【再谈动态规划】
  • 【数据库】MySQL 解读事务的意义及原则
  • Jetpack太香了,让开发效率提升了不少
  • 谁说程序员不懂了浪费,女神节安排
  • 面试官问我按钮级别权限怎么控制,我说v-if,面试官说再见
  • linux下coredump文件产生及分析
  • 真1分钟搞懂缓存穿透、缓存击穿、缓存雪崩
  • 我从功能测试到python接口自动化测试涨到22k,谁知道我经历了什么......
  • 彻底搞懂nodejs事件循环
  • ChatGPT告诉你:项目管理能干到60岁吗?
  • 对于从事芯片行业的人来说,有哪些知识是需要储备的?
  • MySQL数据同步到 Redis 缓存的几种方法
  • python学习——【第四弹】