一、简介

  SocketServer简化了网络服务器的编写。在进行socket创建时,使用SocketServer会大大减少创建的步骤,并且SocketServer使用了select它有5个类:BaseServer,TCPServer,UDPServer,UnixStreamServer,UnixDatagramServer。后4个类是同步进行处理的,另外通过ForkingMixIn和ThreadingMixIn类来支持异步。

  SocketServer的5个类的继承关系

  SocketServer内部使用 IO多路复用 以及 “多线程” 和 “多进程” ,从而实现并发处理多个客户端请求的Socket服务端。即:每个客户端请求连接到服务器时,Socket服务端都会在服务器是创建一个“线程”或者“进 程” 专门负责处理当前客户端的所有请求。

  

二、提供的类型

  一是Server类:BaseServer/TCPServer/UDPServer用来接收客户的请求。TCPServer处理TCP请求,UDPServer处理UDP请求。BaserServer是基类,不能直接使用。TCPServer继承自BaseServer,UDPServer继承自TCPServer。

  二是Handler类:BaseRequestHandler/DatagramRequestHandler/StreamRequestHandler用来处理每一个客户请求。一般用使用BaseRequestHandler就行,但StreamRequestHandler/DatagramRequestHandler提供了一些特别的功能,前者用来处理流式(TCP)请求,后者处理数据报(UDP)请求。Server每收到一个客户请求就会创建一个Handler类示例来处理该请求。默认情况下,TCPServer/UDPServer是单进程单线程的模型,依次处理每个客户请求,一个请求处理完毕才能接着处理下一个请求。

  三是MixIn类:ForkingMixIn/ThreadingMixIn用来为Server提供多进程/多线程并发处理能力的。ForkingMixIn是多进程模型,ThreadingMixin是多线程模型。这里特别巧妙的是,你只要创建一个类,同时继承Server类和MixIn类就能自动获得并发处理请求的能力。该模块本身就直接提供了这种类。

class ForkingUDPServer(ForkingMixIn, UDPServer): pass
class ForkingTCPServer(ForkingMixIn, TCPServer): pass class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass
class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass三

 

三、创建socketserver步骤

  • 必须先创建一个请求处理的类,并且这个类要继承BaseRequestHandle,并重写父类中的handle方法
  • 实例化一个server class,并且传递server ip 和刚创建的请求处理类给server class
  • 调用server class 对象的 handle_request() 或 server_forever()方法来开始处理请求
  • 关闭请求

  server.handle_request()   只处理一个请求

server.forever()      处理多个请求,一直执行

四、事例

  简单的接收客户端发送的信息,并将其转换成大写,再返回给客户端

  服务端: 

# -*- coding: UTF-8 -*-
import socketserver class MyTCPHandler(socketserver.BaseRequestHandler):
"""
The request handler class for our server. It is instantiated once per connection to the server, and must
override the handle() method to implement communication to the
client.
""" def handle(self):
while True: # 多次接收客户端信息
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
print("{} wrote:".format(self.client_address[0]))
print(self.data)
# just send back the same data, but upper-cased
self.request.sendall(self.data.upper()) if __name__ == "__main__":
HOST, PORT = "localhost", 9999 # Create the server, binding to localhost on port 9999
server = socketserver.TCPServer((HOST, PORT), MyTCPHandler) # Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
server.serve_forever()

  客户端:

# -*- coding: UTF-8 -*-

import socket

client = socket.socket()

client.connect(('localhost', 9999))

while True:

    msg = input('>>:').strip()
if not msg:
continue
else:
client.send(msg.encode('utf-8'))
upData = client.recv(1024)
print(upData.decode())

五、多线程处理

  到目前为止我们所有的c/s连接都同时只能处理一个客户端请求,多个客户端请求时,要等前面的客户端请求关闭后才能执行,包括上面的代码也是。如果想让socketserver并发起来, 必须选择使用以下一个多并发的类:

class socketserver.ForkingTCPServer

class socketserver.ForkingUDPServer

class socketserver.ThreadingTCPServer

class socketserver.ThreadingUDPServer

  只需要改变一个地方就可以了

server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)

  服务端:

import socketserver

class MyTCPHandler(socketserver.BaseRequestHandler):

    def handle(self):
while True:
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
print("{} wrote:".format(self.client_address[0]))
print(self.data)
# just send back the same data, but upper-cased
self.request.sendall(self.data.upper()) if __name__ == "__main__":
HOST, PORT = "localhost", 9999
server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)
server.serve_forever()

 

  

socketserver多线程处理的更多相关文章

  1. python_way day10 python和其他语言的作用域 、 python2.7多继承和3.5多继承的区别 、 socket 和 socketserver源码(支持并发处理socket,多进程,多线程)

    python_way day10 1.python的作用域和其他语言的作用域 2.python2.7多继承和3.5多继承的区别 3.socket和socketserver源码(并发处理socket) ...

  2. Socketserver 笔记

    引入Socketserver的背景: 我们之前使用socket编程的时候,Server端创建一个连接循环(建立连接)+一个通信循环(基于一次连接建立通信循环),(这里的黏包问题我们的实现方式是:我们在 ...

  3. gevent协程、select IO多路复用、socketserver模块 改造多用户FTP程序例子

    原多线程版FTP程序:http://www.cnblogs.com/linzetong/p/8290378.html 只需要在原来的代码基础上稍作修改: 一.gevent协程版本 1. 导入geven ...

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

    Python SocketServer使用介绍 1.简介: SocketServer是python的一个网络服务器框架,可以减少开发人员编写网络服务器程序的工作量. SocketServer总共有4个 ...

  5. socketserver tcp黏包

    socket (套接字) tcp(黏包现象原因) 传输中由于内核区缓冲机制(等待时间,文件大小),会在 发送端 缓冲区合并连续send的数据,也会出现在 接收端 缓冲区合并recv的数据给指定port ...

  6. 认识socketserver

    1.服务端 # 如果socket起一个tcp服务,在同一个时间只能和一个客户端通信 # 如果socketserver起一个服务,在同一个时间就可以和多个客户端通信了 # socketserver # ...

  7. Python(七)Socket编程、IO多路复用、SocketServer

    本章内容: Socket IO多路复用(select) SocketServer 模块(ThreadingTCPServer源码剖析) Socket socket通常也称作"套接字" ...

  8. 开发socketserver 以及定制开发自己的FTP服务器

    socket server 示例 #服务端程序 import socketserver class TcpHandler(socketserver.BaseRequestHandler): def h ...

  9. SocketServer

    SocketServer是基于socket写成的一个更强大的模块. SocketServer简化了网络服务器的编写.它有4个类:TCPServer,UDPServer,UnixStreamServer ...

随机推荐

  1. 在Emacs 23里字体的调整(转自ChinaUnix.net)

    首先,在Emacs中,通过菜单Options --> Set Default Font,设置好你喜欢的字体. 然后,把光标放到你所在的字体上,用命令M-x describe-font来查看你当前 ...

  2. 2.openldap安装

    1.安装步骤如下 获取软件包 安装软件包(rpm或者源码编译) 生产openldap配置文件及数据库文件 配置 添加目录树条目 加载slapd进程 验证 2.所需安装包说明 openldap,open ...

  3. ECharts模块化使用5分钟上手

    什么是EChats? 一句话: 一个数据可视化(图表)Javascript框架,详细?移步这里,类似(推荐)的有 HighCharts,其他? 嗯,先看看吧-- 快速上手: 模块化单文件引入(推荐). ...

  4. c# WPS DLL及其调用

    1.dll分享(含xsl及docx的dll) 链接:https://pan.baidu.com/s/1c1ImV14OndmvIb4W-_WL2A 密码:d2rx 2.方法: 1.先在类的前面(类外面 ...

  5. Alpha冲刺——第八天

    Alpha第八天 听说 031502543 周龙荣(队长) 031502615 李家鹏 031502632 伍晨薇 031502637 张柽 031502639 郑秦 1.前言 任务分配是VV.ZQ. ...

  6. iOS- 全方位解析.crash文件崩溃报告

    1.前言 想来每个iOS攻城狮,都免不了要接触.crash文件 那么什么是.crash文件? iOS app的所有崩溃记录都会记录在设备上,所以对于和我一样没有集成让用户发送崩溃报告功能的iOS开发者 ...

  7. ElasticSearch API 简要介绍

    调用其API会返回很多信息,例如集群的信息,节点的信息等 检查集群的状态----Restful API说明 1:检查集群状态信息 2:管理集群 3:执行 增删改查 命令 4:执行高级命令 Restfu ...

  8. xpath的学习

    xpath的作用就是两个字“定位”,运用各种方法进行快速准确的定位,推荐两个非常有用的的firefox工具:firebug和xpath checker   定位 1.依靠自己属性,文本定位 //td[ ...

  9. 【c】线性表

    数据对象集:线性表是N(>=0)个元素构成的有序序列,a1,a2,a3.....a(N-1),aN,a(N+1) 线性表上的基本操作有: ⑴ 线性表初始化:Init_List(L)初始条件:表L ...

  10. linux mysql表名大小写

    1.用ROOT登录,修改/etc/my.cnf 2.在[mysqld]下加入一行:lower_case_table_names=1 0:区分大小写,1:不区分大小写 3.重新启动数据库即可