使用Python SocketServer快速实现多线程网络服务器

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()

时间: 2024-10-21 22:24:25

使用Python SocketServer快速实现多线程网络服务器的相关文章

基于Python的urllib2模块的多线程网络爬虫程序

1 m Queue import Queue 2 from gzip import GzipFile 3 from StringIO import StringIO 4 import time 5 import socket 6 class ContentEncodingProcessor(urllib2.BaseHandler): 7 """A handler to add gzip capabilities to urllib2 requests ""

linux网络编程----->高并发--->多线程并发服务器

做网络服务的时候并发服务端程序的编写必不可少.前端客户端应用程序是否稳定一部分取决于客户端自身,而更多的取决于服务器是否相应时间够迅速,够稳定. 常见的linux并发服务器模型: 多进程并发服务器 多线程并发服务器 select多路I/O转接服务器 poll多路I/O转接服务器 epool多路I/O转接服务器. 本次主要讨论多线程并发服务器模型: 使用多线程模型开发服务时需要考虑以下问题 1.  调整进程内最大文件描述符上限. 2.  线程如有共享数据, 考虑线程同步. 3.  服务于客户端线程

python自然语言处理1——从网络抓取数据

python自然语言处理1--从网络抓取数据 写在前面 本节学习python2.7 BeautifulSoup库从网络抽取数据的技术,检验之简而言之就是爬虫技术.网络编程是一门复杂的技术,在需要基础的地方,文中给出的链接地址,都是很好的教程,可以参考,我在这里不在重复发明轮子.本节的主旨在于: 帮助快速掌握基本爬虫技术,形成一条主线,能为自己的实验构造基础数据.掌握爬虫技术后,可以从网络抓取符合特定需求的数据供分析,这里学习的爬虫技术适用于数据挖掘.自然语言处理等需要从外部挖掘数据的学科. 1.

python 学习笔记day10-python多线程,forking,xinetd服务

xinetd服务器 配置xinetd服务 什么是xinetd xinetd可以统一管理很多服务进程,它能够: - 绑定.侦听和接受来对自服务器每个端口的请求 - 有客户访问时,调用相应的服务器程序相应 - 节约了系统内存资源 - 同时响应多个客户端的连接请求 Windows系统没有该功能 多数UNIX系统使用的是inetd实现相同的功能 配置文件解析 选项名称 说明 flags 如果只指定NAMEINARGS,那么它就使参数和inetd一样的传递 type 如果服务不在/etc/services

python SocketServer

SocketServer是标准库中一个高级别的模块,用于简化网络客户与服务器的实现.模块中,已经实现了一些可供使用的类. 在Python3中,本模块为socketserver模块.在Python 2中,本模块为SocketServer模块.所以在用import导入时,要分情况导入,否则会报错.导入的代码如下: ? 1 2 3 4 try:     import socketserver      #Python 3 except ImportError:     import SocketSer

Python标准库08 多线程与同步 (threading包)

Python主要通过标准库中的threading包来实现多线程.在当今网络时代,每个服务器都会接收到大量的请求.服务器可以利用多线程的方式来处理这些请求,以提高对网络端口的读写效率.Python是一种网络服务器的后台工作语言 (比如豆瓣网),所以多线程也就很自然被Python语言支持. (关于多线程的原理和C实现方法,请参考我之前写的Linux多线程与同步,要了解race condition, mutex和condition variable的概念) 多线程售票以及同步 我们使用Python来实

Python——socketserver

在Python 2.x中, socketserver模块名为SocketServer.该模块可以简化创建服务器的过程. 该模块有四个比较主要的类型,其中常用的是 TCPServer 和 UDPServer. 1. TCPServer 2. UnixStreamServer,类似于TCPServer提供面向数据流的套接字连接,但是旨在UNIX平台上可用: 3. UDPServer 4. UnixDatagramServer,类似于UDPServer提供面向数据报的套接字连接,但是旨在UNIX平台上

crawler4j:轻量级多线程网络爬虫

crawler4j是Java实现的开源网络爬虫.提供了简单易用的接口,可以在几分钟内创建一个多线程网络爬虫. 安装 使用Maven 使用最新版本的crawler4j,在pom.xml中添加如下片段: XHTML 1 2 3 4 5 <dependency> <groupId>edu.uci.ics</groupId> <artifactId>crawler4j</artifactId> <version>4.1</version

Python3-socketserver模块-网络服务器框架

Python3中的socketserver模块简化了编写网络服务器的任务 在实际的开发中,特别是多并发的情况下,socket模块显然对我们的用处不大,因为如果你要通过socket模块来实现并发的socket通信,简直太麻烦了,socketserver模块则是Python提供给你的现成的接口,你只需要编写少量的代码,就可以实现你的需求 首先,您必须通过对BaseRequestHandler类进行子类化并覆盖其handle()方法来创建请求处理程序类:此方法将处理传入请求.其次,您必须实例化一个服务