一、简介

  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. eclipse技巧-快捷键

    ctrl + 1,快速修复 ctrl + d, 快捷删除行 shift + Enter,快速移动光标到下一行 ctrl + F11,运行代码 alt + ↑/↓,快速移动行 ctrl + alt + ...

  2. Android开发第二阶段(6)

    今天:对sdcard的操作有了进一步的了解和深入,为程序可以自主扫描并添加sdcard的MP3格式文件 明天:最后的修正.

  3. VUE AXIOS 跨域问题

    背景: 后台跨域使用通配符:context.Response.Headers.Add("Access-Control-Allow-Origin", "*"); ...

  4. Android工程方法数超过64k,The number of method references in a .dex file cannot exceed 64K.

    最近将一个老的Eclipse项目转到Android Studio后,用gradle添加了几个依赖,项目可以make,但是一旦run就报错 Error:The number of method refe ...

  5. 第七周PSP(10.27-11.03)

    psp   进度条 项目 细则 总计 代码行数   0 随笔字数   0 知识点   无 累计曲线 饼图

  6. 基于opencv的小波变换代码和图像结果

    #include "stdafx.h" #include "WaveTransform.h" #include <math.h> #include ...

  7. 双主双写、只备份某些表且要在建表ID自增

    先展示下最终实现的配置 主1的配置(重要的,其他略) log-bin = mysql-bin #必须要有binlog auto_increment_offset = 1 #自增ID的初始值 auto_ ...

  8. oracle 数据库 命令

    SQL PLUS 命令: SELECT * FROM ALL_TABLES;系统里有权限的表SELECT * FROM DBA_TABLES; 系统表SELECT * FROM USER_TABLES ...

  9. 第100天:CSS3中animation动画详解

    CSS3属性中有关于制作动画的三个属性:Transform,Transition,Animation: 一.Animation定义动画 CSS3的Animation是由“keyframes”这个属性来 ...

  10. 【uoj#174】新年的破栈 贪心

    题目描述 给你一个长度为 $n$ 的序列和一个空的双端队列,每次进行3种操作种的一种: 1.将序列中编号最小的数加入到双端队列的队尾:2.从双端队列的队尾取出一个数:3.从双端队列的队头取出一个数. ...