python应⽤系列教程——python使⽤SocketServer实现⽹络服务器,soc。。。
全栈⼯程师开发⼿册 (作者:栾鹏)
python使⽤SocketServer实现⽹络服务器
SocketServer简化了⽹络服务器的编写。在进⾏socket创建时,使⽤SocketServer会⼤⼤减少创建的步骤,并且SocketServer使⽤了select它有4个类:TCPServer,UDPServer,UnixStreamServer,UnixDatagramServer。这4个类是同步进⾏处理的,另外通过ForkingMixIn和ThreadingMixIn类来⽀持异步。
使⽤SocketServer的步骤简介
1. 创建服务器的步骤。⾸先,你必须创建⼀个请求处理类,它是BaseRequestHandler的⼦类并重载其handle()⽅法。
电源模块2. 实例化⼀个服务器类,传⼊服务器的地址和请求处理程序类。
3. 最后,调⽤handle_request()(⼀般是调⽤其他事件循环或者使⽤select())或serve_forever()。
集成ThreadingMixIn类时需要处理异常关闭。daemon_threads指⽰服务器是否要等待线程终⽌,要是线程互相独⽴,必须要设置为True,默认是False。
⽆论⽤什么⽹络协议,服务器类有相同的外部⽅法和属性。
测试案例
服务器端为⼀个时间戳服务器,在接收到客户端发来的数据后,⾃动回复。
客户端,等待⽤户输⼊,回车后向服务器发送⽤户输⼊的内容。
分别在python2.7和python3.6下测试。在启动时需要先启动服务器端,在启动客户端。
python2.7下
服务器端代码为
#coding:utf-8
import SocketServer
django中文版from time import ctime
print("=====================SocketServer TCP服务器=====================");
HOST = '' #主机号为空⽩表⽰可以使⽤任何可⽤的地址。
PORT = 21567 #端⼝号
ADDR = (HOST, PORT)
class MyRequestHandler(SocketServer.StreamRequestHandler): #StreamRequestHandler实现TCP/UDP服务器的服务处理器
def handle(self): #重写接收响应函数
print('...connect from:', self.client_address)
data = adline().strip()
print(data)
self.wfile.write('[%s] %s' % (ctime(), data))
tcpSerSock = SocketServer.TCPServer(ADDR, MyRequestHandler)
print('等待连接...')
tcpSerSock.serve_forever()
客户端代码为
windows上传文件到linuxHOST = '127.0.0.1' #本机测试
PORT = 21567
BUFSIZ = 1024
python在线编辑器python3ADDR = (HOST, PORT)
while True:
tcpCliSock = socket(AF_INET, SOCK_STREAM) #创建客户端套接字
data = raw_input('> ') #接收⽤户输⼊
if not data: #如果⽤户输⼊为空,直接回车就会发送"",""就是代表false
break
tcpCliSock.send(data+'\n') #客户端发送消息,必须发送字节数组
data = v(BUFSIZ) #接收回应消息,接收到的是字节数组
if not data: #如果接收服务器信息失败,或响应消息为空
break
print(data) #打印回应消息
tcpCliSock.close() #关闭客户端socket
python3.6下
SocketServer模块在python3中已经更名为socketserver。
服务器端代码为
#coding:utf-8
import socketserver
from time import ctime
print("=====================SocketServer TCP服务器=====================");
HOST = '' #主机号为空⽩表⽰可以使⽤任何可⽤的地址。
PORT = 21567 #端⼝号
ADDR = (HOST, PORT)
class MyRequestHandler(socketserver.StreamRequestHandler): #StreamRequestHandler实现TCP/UDP服务器的服务处理器 def handle(self): #重写接收响应函数
print('连接到:', self.client_address)
data = adline().strip()
print(data)
self.wfile.write(bytes('[%s] %s' % (ctime(), data.decode('utf-8')),'utf-8'))
tcpSerSock = socketserver.TCPServer(ADDR, MyRequestHandler)
print('等待连接...')
tcpSerSock.serve_forever()
客户端代码为
HOST = '127.0.0.1' #本机测试
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)
while True:
tcpCliSock = socket(AF_INET, SOCK_STREAM) #创建客户端套接字
data = input('> ') #接收⽤户输⼊
if not data: #如果⽤户输⼊为空,直接回车就会发送"",""就是代表false
break
tcpCliSock.send(bytes(data+'\n','utf-8')) #客户端发送消息,必须发送字节数组
buffer = v(BUFSIZ) #接收回应消息,接收到的是字节数组
if not buffer: #如果接收服务器信息失败,或响应消息为空
break
print(str(buffer,'utf-8')) #打印回应消息
tcpCliSock.close() #关闭客户端socket
服务器类型
5种类型:BaseServer,TCPServer,UnixStreamServer,UDPServer,UnixDatagramServer。 注意:BaseServer不直接对外服务。
服务器对象
·class SocketServer.BaseServer:这是模块中的所有服务器对象的超类。它定义了接⼝,如下所述,但是⼤多数的⽅法不实现,在⼦类中进⾏细化。
·BaseServer.fileno():返回服务器监听套接字的整数⽂件描述符。通常⽤来传递给select.select(), 以允许⼀个进程监视多个服务器。
·BaseServer.handle_request():处理单个请求。处理顺序:get_request(), verify_request(), process_request()。如果⽤户提供handle()⽅法抛出异常,将调⽤服务器的handle_error()⽅法。如果self.timeout内没有请求收到, 将调⽤handle_timeout()并返回handle_request()。
·BaseServer.serve_forever(poll_interval=0.5): 处理请求,直到⼀个明确的shutdown()请求。每poll_interval秒轮询⼀次shutdown。忽略self.timeout。如果你需要做周期性的任务,建议放置在其他线程。
·BaseServer.shutdown():告诉serve_forever()循环停⽌并等待其停⽌。python2.6版本。
·BaseServer.address_family: 地址家族,⽐如socket.AF_INET和socket.AF_UNIX。
·BaseServer.RequestHandlerClass:⽤户提供的请求处理类,这个类为每个请求创建实例。
·BaseServer.server_address:服务器侦听的地址。格式根据协议家族地址的各不相同,请参阅socket模块的⽂档。
·BaseServer.socketSocket:服务器上侦听传⼊的请求socket对象的服务器。
服务器类⽀持下⾯的类变量:
·BaseServer.allow_reuse_address:服务器是否允许地址的重⽤。默认为false ,并且可在⼦类中更改。
·quest_queue_size
请求队列的⼤⼩。如果单个请求需要很长的时间来处理,服务器忙时请求被放置到队列中,最多可以放request_queue_size个。⼀旦队列已满,来⾃客户端的请求将得到 “Connection denied”错误。默认值通常为5 ,但可以被⼦类覆盖。
·
BaseServer.socket_type:服务器使⽤的套接字类型; socket.SOCK_STREAM和socket.SOCK_DGRAM等。
·BaseServer.timeout:超时时间,以秒为单位,或 None表⽰没有超时。如果handle_request()在timeout内没有收到请求,将调⽤handle_timeout()。
下⾯⽅法可以被⼦类重载,它们对服务器对象的外部⽤户没有影响。
·BaseServer.finish_request():实际处理RequestHandlerClass发起的请求并调⽤其handle()⽅法。 常⽤。
·_request():接受socket请求,并返回⼆元组包含要⽤于与客户端通信的新socket对象,以及客户端的地址。
·BaseServer.handle_error(request, client_address):如果RequestHandlerClass的handle()⽅法抛出异常时调⽤。默认操作是打印traceback到标准输出,并继续处理其他请求。
·BaseServer.handle_timeout():超时处理。默认对于forking服务器是收集退出的⼦进程状态,threading服务器则什么都不做。
·
BaseServer.process_request(request, client_address) :调⽤finish_request()创建RequestHandlerClass的实例。如果需要,此功能可以创建新的进程或线程来处理请求,ForkingMixIn和ThreadingMixIn类做到这点。常⽤。
c语言socket报文不全·BaseServer.server_activate():通过服务器的构造函数来激活服务器。默认的⾏为只是监听服务器套接字。可重载。
·BaseServer.server_bind():通过服务器的构造函数中调⽤绑定socket到所需的地址。可重载。
·BaseServer.verify_request(request, client_address):返回⼀个布尔值,如果该值为True ,则该请求将被处理,反之请求将被拒绝。此功能可以重写来实现对服务器的访问控制。默认的实现始终返回True。client_address可以限定客户端,⽐如只处理指定ip区间的请求。 常⽤。帝国cms搭建试玩网站
请求处理器
处理器接收数据并决定如何操作。它负责在socket层之上实现协议(i.e., HTTP, XML-RPC, or AMQP),读取数据,处理并写反应。可以重载的⽅法如下:
·setup(): 准备请求处理. 默认什么都不做,StreamRequestHandler中会创建⽂件类似的对象以读写socket.
·handle(): 处理请求。解析传⼊的请求,处理数据,并发送响应。默认什么都不做。常⽤变量:
·finish(): 环境清理。默认什么都不做,如果setup产⽣异常,不会执⾏finish。
通常只需要重载handle。quest的类型和数据报或流的服务不同。对于流服务,quest是socket 对象;对于数据报服
务,quest是字符串和socket 。可以在⼦类StreamRequestHandler或DatagramRequestHandler中重载,重写setup()和
finish() ,并提供self.rfile和self.wfile属性。 self.rfile和self.wfile可以读取或写⼊,以获得请求数据或将数据返回到客户端。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论