Python使用SocketServer模块编写基本服务器程序的教程

 更新时间:2016年07月12日 18:04:37   作者:duhaizhang  
SocketServer模块中集成了实现socket通信服务器功能所需的各种类和方法,这里我们就来看一下Python使用SocketServer模块编写基本服务器程序的教程:

SocketServer简化了网络服务器的编写。它有4个类:TCPServer,UDPServer,UnixStreamServer,UnixDatagramServer。这4个类是同步进行处理的,另外通过ForkingMixIn和ThreadingMixIn类来支持异步。

创建服务器的步骤。首先,你必须创建一个请求处理类,它是BaseRequestHandler的子类并重载其handle()方法。其次,你必须实例化一个服务器类,传入服务器的地址和请求处理程序类。最后,调用handle_request()(一般是调用其他事件循环或者使用select())或serve_forever()。

集成ThreadingMixIn类时需要处理异常关闭。daemon_threads指示服务器是否要等待线程终止,要是线程互相独立,必须要设置为True,默认是False。

无论用什么网络协议,服务器类有相同的外部方法和属性。

在Python3中,本模块为socketserver模块。在Python 2中,本模块为SocketServer模块。所以在用import导入时,要分情况导入,否则会报错。导入的代码如下:

try:
  import socketserver   #Python 3
except ImportError:
  import SocketServer   #Python 2

SocketSerror模块包括许多可以简化TCP、UDP、UNIX域套接字  服务器实现的类。

一、处理程序
要使用本模块,必须定义一个继承于基类BaseRequestHandler的处理程序类。BaseRequestHandler类的实例h可以实现以下方法:
1、h.handle()  调用该方法执行实际的请求操作。调用该函数可以不带任何参数,但是几个实例变量包含有用的值。h.request包含请求,h.client_address包含客户端地址,h.server包含调用处理程序的实例。对于TCP之类的数据流服务,h.request属性是套接字对象。对于数据报服务,它是包含收到数据的字节字符串。
2、h.setup()   该方法在handle()之前调用。默认情况下,它不执行任何操作。如果希望服务器实现更多连接设置(如建立SSL连接),可以在这里实现。
3、h.finish()   调用本方法可以在执行完handle()之后执行清除操作。默认情况下,它不执行任何操作。如果setup()和handle()方法都不生成异常,则无需调用该方法。
如果知道应用程序只能操纵面向数据流的连接(如TCP),那么应从StreamRequestHandler继承,而不是BaseRequestHandler。StreamRequestHandler类设置了两个属性,h.wfile是将数据写入客户端的类文件对象,h.rfile是从客户端读取数据的类文件对象。
如果要编写针对数据包操作的处理程序并将响应持续返回发送方,那么它应当从DatagramRequestHandler继承。它提供的类接口与StramRequestHandler相同。

二、服务器
要使用处理程序,必须将其插入到服务器对象。定义了四个基本的服务器类。
(1)TCPServer(address,handler)   支持使用IPv4的TCP协议的服务器,address是一个(host,port)元组。Handler是BaseRequestHandler或StreamRequestHandler类的子类的实例。
(2)UDPServer(address,handler)   支持使用IPv4的UDP协议的服务器,address和handler与TCPServer中类似。
(3)UnixStreamServer(address,handler)   使用UNIX域套接字实现面向数据流协议的服务器,继承自TCPServer。
(4)UnixDatagramServer(address,handler)  使用UNIX域套接字实现数据报协议的服务器,继承自UDPServer。
所有四个服务器类的实例都有以下方法和变量:
1、s.socket   用于传入请求的套接字对象。
2、s.sever_address  监听服务器的地址。如元组("127.0.0.1",80)
3、s.RequestHandlerClass   传递给服务器构造函数并由用户提供的请求处理程序类。
4、s.serve_forever()  处理无限的请求
5、s.shutdown()   停止serve_forever()循环
6、s.fileno()   返回服务器套接字的整数文件描述符。该方法可以有效地通过轮询操作(如select()函数)使用服务器实例。

三、定义自定义服务器
服务器往往需要特殊的配置来处理不同的网络地址族、超时期、并发和其他功能,可以通过继承上面四个基本服务器类来自行定义。
可以通过混合类获得更多服务器功能,这也是通过进程或线程分支添加并发行的方法。为了实现并发性,定义了以下类:
(1)ForkingMixIn         将UNIX进程分支添加到服务器的混合方法,使用该方法可以让服务器服务多个客户。
(2)ThreadingMixIn    修改服务器的混合类,可以使用线程服务多个客户端。
要向服务器添加这些功能,可以使用多重继承,其中首先列出混了类。
由于并发服务器很常用,为了定义它,SocketServer预定义了以下服务器类:
(1)ForkingUDPServer(address,handler)  
(2)ForkingTCPServer(address,handler)
(3)ThreadingUDPServer(address,handler)
(4)ThreadingTCPServer(address,handler)
上面有点乱,现总结以下:
SocketServer模块中的类主要有以下几个:
1、BaseServer    包含服务器的核心功能与混合类(mix-in)的钩子功能。这个类主要用于派生,不要直接生成这个类的类对象,可以考虑使用TCPServer和UDPServer类。
2、TCPServer    基本的网络同步TCP服务器
3、UDPServer    基本的网络同步UDP服务器
4、ForkingMixIn   实现了核心的进程化功能,用于与服务器类进行混合(mix-in),以提供一些异步特性。不要直接生成这个类的对象。
5、ThreadingMixIn   实现了核心的线程化功能,用于与服务器类进行混合(mix-in),以提供一些异步特性。不要直接生成这个类的对象。
6、ForkingTCPServer     ForkingMixIn与TCPServer的组合
7、ForkingUDPServer    ForkingMixIn与UDPServer的组合
8、BaseRequestHandler
9、StreamRequestHandler    TCP请求处理类的一个实现
10、DataStreamRequestHandler   UDP请求处理类的一个实现
现在繁杂的事务都已经封装到类中了,直接使用类即可。

四、实例
1.使用SocketServer模块编写的TCP服务器端代码:

#! /usr/bin/env python
#coding=utf-8
"""使用SocketServer来实现简单的TCP服务器"""
from SocketServer import (TCPServer,StreamRequestHandler as SRH)
from time import ctime
class MyRequestHandler(SRH):
  def handle(self):
    print "connected from ",self.client_address
    self.wfile.write("[%s] %s" %(ctime(),self.rfile.readline()))
tcpSer=TCPServer(("",10001),MyRequestHandler)
print "waiting for connection"
tcpSer.serve_forever()
相应的TCP客户端代码:
#! /usr/bin/env python
#coding=utf-8
from socket import *
BUFSIZE=1024
#每次都要创建新的连接
while True:
  tcpClient=socket(AF_INET,SOCK_STREAM)
  tcpClient.connect(("localhost",10001))
  data=raw_input(">")
  if not data:
    break
  tcpClient.send("%s\r\n" %data)
  data1=tcpClient.recv(BUFSIZE)
  if not data1:
    break
  print data1.strip()
  tcpClient.close()

2.异步服务器的实现

ThreadingMixIn的例子:

import socketimport threadingimport SocketServerclass 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):
  passdef 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__":
  # Port 0 means to select an arbitrary unused port
  HOST, PORT = "localhost", 0

  server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
  ip, port = server.server_address  # Start a thread with the server -- that thread will then start one
  # more thread for each request
  server_thread = threading.Thread(target=server.serve_forever)
  # Exit the server thread when the main thread terminates
  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()

执行结果:

$ python ThreadedTCPServer.py
Server loop running in thread: Thread-1
Received: Thread-2: Hello World 1
Received: Thread-3: Hello World 2
Received: Thread-4: Hello World 3

相关文章

  • pytorch教程resnet.py的实现文件源码分析

    pytorch教程resnet.py的实现文件源码分析

    torchvision.models这个包中包含alexnet、densenet、inception、resnet、squeezenet、vgg等常用的网络结构,并且提供了预训练模型,可以通过简单调用来读取网络结构和预训练模型
    2021-09-09
  • 浅谈Python中的bs4基础

    浅谈Python中的bs4基础

    今天小编就为大家分享一篇关于Python中的bs4基础,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-10-10
  • Win10 GPU运算环境搭建(CUDA10.0+Cudnn 7.6.5+pytroch1.2+tensorflow1.14.0)

    Win10 GPU运算环境搭建(CUDA10.0+Cudnn 7.6.5+pytroch1.2+tensorflow1.

    熟悉深度学习的人都知道,深度学习是需要训练的,本文主要介绍了Win10 GPU运算环境搭建,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • 解决Pycharm调用Turtle时 窗口一闪而过的问题

    解决Pycharm调用Turtle时 窗口一闪而过的问题

    今天小编就为大家分享一篇解决Pycharm调用Turtle时 窗口一闪而过的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-02-02
  • Python实现将目录中TXT合并成一个大TXT文件的方法

    Python实现将目录中TXT合并成一个大TXT文件的方法

    这篇文章主要介绍了Python实现将目录中TXT合并成一个大TXT文件的方法,涉及Python针对目录下文本文件的遍历、读取及写入等技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • python使用Scrapy库进行数据提取和处理的方法详解

    python使用Scrapy库进行数据提取和处理的方法详解

    在我们的初级教程中,我们介绍了如何使用Scrapy创建和运行一个简单的爬虫,在这篇文章中,我们将深入了解Scrapy的强大功能,学习如何使用Scrapy提取和处理数据
    2023-09-09
  • Java 超详细讲解核心类Spring JdbcTemplate

    Java 超详细讲解核心类Spring JdbcTemplate

    JdbcTemplate JdbcTemplate是Spring JDBC核心包(core)中的核心类,它可以通过配置文件、注解、Java 配置类等形式获取数据库的相关信息,实现了对JDBC开发过程中的驱动加载、连接的开启和关闭、SQL语句的创建与执行、异常处理、事务处理、数据类型转换等操作的封装
    2022-04-04
  • Python简单I/O操作示例

    Python简单I/O操作示例

    这篇文章主要介绍了Python简单I/O操作,结合实例形式分析了Python针对文件的I/O读写及cPickle模块相关使用操作技巧,需要的朋友可以参考下
    2019-03-03
  • Python3爬虫中关于Ajax分析方法的总结

    Python3爬虫中关于Ajax分析方法的总结

    在本篇文章里小编给大家整理的是一篇关于Python3爬虫中关于Ajax分析方法的总结,需要的朋友们可以学习下。
    2020-07-07
  • Python使用异步线程池如何实现异步TCP服务器交互

    Python使用异步线程池如何实现异步TCP服务器交互

    这篇文章主要介绍了Python使用异步线程池如何实现异步TCP服务器交互问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11

最新评论