使用Python SocketServer快速实现多线程网络服务器
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了使用Python SocketServer快速实现多线程网络服务器,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4630字,纯文字阅读大概需要7分钟。
内容图文
Python SocketServer 使用介绍
1 、简介:
SocketServer 是 python 的一个网络服务器框架,可以减少开发人员编写网络服务器程序的工作量。
SocketServer 总共有 4 个 server 基类。
TCPServer :负责处理 TCP 协议。
UDPServer :负责处理 UDP 协议。
UnixStreamServer :只适用于类 unix 平台,不常用。
UnixDatagramServer :只适用于类 unix 平台,不常用。
这 4 个类会同步处理每一个 request ,也就是说只有当前的 request 处理完才会处理下一个 request ,这种方式显然很不合理,如果当前的 request 处理过慢的话就会导致“堵塞”。正确的处理方式应该是开辟新的进程或线程去处理不同的 request ,通过混合继承 ForkingMixIn 或 ThreadingMixIn 类即可解决此问题。
2 、创建 SocketServer
使用 SocketServer 创建一个网络服务程序只需要几个简单的步骤:
( 1 )、创建处理 request 的类,创建方法为:继承 BaseRequestHandler 类,并重载 handle() 方法。该方法将被回调用做处理当前接收到的 request 。
注意:一般的做法是直接继承 StreamRequestHandler 或者 DatagramRequestHandler 。比如:
class MyTCPHandler(SocketServer.StreamRequestHandler):
( 2 )、实例化一个 server 基类(比如 TCPServer )的对象,并发服务器地址和处理 request 的类作为参数传入。
( 3 )、使用 server 基类对象调用 handle_request() 或 serve_forever() 方法,即可处理一个或多个 request 。
( 4 )、如果需要创建多进程或多线程的服务器程序,则可以通过混合继承 ForkingMixIn 或 ThreadingMixIn 类来实现,比如:
class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass // 创建一个多线程的 TCP 服务器。
注意: ThreadingMixIn 必须要放在 TCPServer 前面。
3 、 server 类方法说明:
( 1 )、 class SocketServer.BaseServer
这是所有类的超类,只定义接口,大部分均在子类中实现。
( 2 )、 BaseServer.handle_request()
该方法用于处理单一的 request 。按顺序调用 get_request(), verify_request() 和 process_request().
( 3 )、 BaseServer.serve_forever(poll_interval=0.5)
循环轮询处理 request
( 4 )、 BaseServer.address_family
协议簇信息,比如 socket.AF_INET and socket.AF_UNIX
( 5 )、 BaseServer.RequestHandlerClass
开发者自定义的用于处理 request 的类,每个 request 都会对应实例化一个 request handle 类进行处理。
( 6 )、 BaseServer.server_address
服务器要监听的地址和端口的二元组,比如 (0.0.0.0,8080)
( 7 )、 BaseServer.finish_request()
实例化开发者自定义 request handle 类,然后调用 handle() 方法处理当前的 request 。
( 8 )、
4 、 request handler 类方法说明:
由用户自定义并传入 SocketServer ,由 server 类实例化来处理当前的 request 。需要注意的是: Request handler 类必须要复写 handle() 方法 ,其它方法也可以复写,但不做强制。
( 1 )、 RequestHandler.handle()
开发者必须在此方法里面实现对当前 request 的所有处理,在该方法里面有几个实例化的属性可以直接使用: self.request 代表当前的 request 对象, self.client_address 代表客户端地址, self.server 代表服务器对象。对于 TCP 链接, self.request 是当前 request 的 socket 。 self.rfile 和 self.wfile 可分别用于读取客户端数据和向客户端返回数据。
5 、样例代码:
5.1 、创建 TCP 类型的 SocketServer :
import SocketServer
class MyTCPHandler(SocketServer.BaseRequestHandler): # 定义 request handler 类,从 BaseRequestHandler 类继承
def handle(self): # 复写 handle() 方法,注意:该方法必须复写,用于处理当前的 request
self.data = self.request.recv(1024).strip() #self.request 是和客户端连接的套接字,可直接使用
print "{} wrote:".format(self.client_address[0])
print self.data
self.request.sendall(self.data.upper())
class MyTCPHandler(SocketServer.StreamRequestHandler): # 定义 request handler 类,从 StreamRequestHandler 类继承
def handle(self):
self.data = self.rfile.readline().strip() #self.rfile/self.wfile 是文件格式类型的 socket ,相当于对原始 socket 的封装,让读写网络数据向读写文件一样容易
print "{} wrote:".format(self.client_address[0])
print self.data
self.wfile.write(self.data.upper())
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler) # 传入监听地址、端口号和 request handler 类
server.serve_forever() # 启动监听处理 request
5.2 、创建 UDP 类型的 SocketServer :
import SocketServer
class MyUDPHandler(SocketServer.BaseRequestHandler):
def handle(self):
data = self.request[0].strip()
socket = self.request[1]
print "{} wrote:".format(self.client_address[0])
print data
socket.sendto(data.upper(), self.client_address)
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
server = SocketServer.UDPServer((HOST, PORT), MyUDPHandler)
server.serve_forever()
5.3 、创建多线程类型的 TCP SocketServer :
import socket
import threading
import SocketServer
class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
def handle(self):
data = self.request.recv(1024)
cur_thread = threading.current_thread()
response = "{}: {}".format(cur_thread.name, data)
self.request.sendall(response)
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):# 继承 ThreadingMixIn 表示使用多线程处理 request ,注意这两个类的继承顺序不能变
pass
def client(ip, port, message):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, port))
try:
sock.sendall(message)
response = sock.recv(1024)
print "Received: {}".format(response)
finally:
sock.close()
if __name__ == "__main__":
HOST, PORT = "localhost", 0
server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
ip, port = server.server_address
server_thread = threading.Thread(target=server.serve_forever)
server_thread.daemon = True
server_thread.start()
print "Server loop running in thread:", server_thread.name
client(ip, port, "Hello World 1")
client(ip, port, "Hello World 2")
client(ip, port, "Hello World 3")
server.shutdown()
原文:http://www.cnblogs.com/fishou/p/4175732.html
内容总结
以上是互联网集市为您收集整理的使用Python SocketServer快速实现多线程网络服务器全部内容,希望文章能够帮你解决使用Python SocketServer快速实现多线程网络服务器所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。