socketserver(多连接)

  正如前面的socket模块部分看到的一样,写一个简单套接字服务器不是很难,如果想实现超出继承的应用,最好寻求一些帮助,socketserver模块是标准库中很多服务器框架的基础,这些服务器架构包括BaseHTTPServer、SimpleHTTPServer、CGIHTTPServer、SimpleXMLRPCServer、DocXMLRPCServer,所有的这些服务器框架都为基础服务器增加了特定功能;

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

ThreadingTCPServer(多线程,真并发

ThreadingTCPServer实现的Soket服务器内部会为每个client创建一个 “线程”,该线程用来和客户端进行交互。

使用ThreadingTCPServer:

  • 创建一个继承自 SocketServer.BaseRequestHandler 的类
  • 类中必须定义一个名称为 handle 的方法
  • 启动ThreadingTCPServer

用socketserver对ssh程序做修改,实现多用户同时操作互不影响

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 #-Author-Lian
 4
 5 #scoketserver
 6
 7 import socketserver,os
 8
 9 class Myserver(socketserver.BaseRequestHandler):
10     def handle(self):
11         while True:
12             conn = self.request
13            # conn,add = server.accept()
14             while True:
15                 print("开始收")
16                 client_data = conn.recv(1024)
17                 client_data = client_data.decode("utf-8")
18                 if client_data == "exit":           #收到exit 退出
19                     break
20                 send_data = os.popen(client_data).read()    #执行命令结果,要发送的数据
21                 send_data = send_data.encode("utf-8")       #转换为bytes类型
22
23                 length = str(len(send_data))              #统计发送数据的长度
24                 conn.sendall(length.encode("utf-8"))      #长度以bytes类型发送过去
25
26                 return_value = conn.recv(1024)
27                 return_value = return_value.decode("utf-8")
28
29                 if return_value == "start":
30                     if not send_data:            # 如果执行结果为空,表示命令不存在
31                         conn.sendall((client_data +"命令不存在").encode("utf-8"))
32                     else:
33                       conn.sendall(send_data)
34             conn.close()
35
36 if __name__ == ‘__main__‘:
37     server = socketserver.ThreadingTCPServer(("127.0.0.1",8888),Myserver)
38     server.serve_forever()
39
40 ssh 服务端多用户同时连接

ssh 服务端多用户同时连接

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 #-Author-Lian
 4
 5 #ssh client
 6
 7 import socket
 8
 9 ip_port = ("127.0.0.1",8888)
10 client = socket.socket()
11 client.connect(ip_port)
12
13 while True:
14     cmd = input("->>").strip()
15     if not cmd:                 #空字符 重新输入
16         continue
17     client.sendall(cmd.encode("utf-8"))     #要执行的命令发送过去
18     if cmd == "exit":           #如果为exit 退出连接
19         break
20
21     length = client.recv(1024)     #数据长度
22     length = length.decode("utf-8")
23     length = int(length)            #长度转换为int
24
25     client.sendall("start".encode("utf-8"))     #发送字节start
26
27     sum_data = ""                   #初始汇总的数据
28     while length >= 0:              #循环收数据
29         server_data = client.recv(1024)
30         length -=1024
31         sum_data +=server_data.decode("utf-8")
32     print(sum_data)                 #打印最终的执行数据
33
34 client.close()
35
36 ssh 客户端多用户同时连接

ssh 客户端多用户同时连接

ThreadingTCPServer源码剖析

内部调用流程为:

  • 启动服务端程序
  • 执行 TCPServer.__init__ 方法,创建服务端Socket对象并绑定 IP 和 端口
  • 执行 BaseServer.__init__ 方法,将自定义的继承自SocketServer.BaseRequestHandler 的类 MyRequestHandle赋值给 self.RequestHandlerClass
  • 执行 BaseServer.server_forever 方法,While 循环一直监听是否有客户端请求到达 ...
  • 当客户端连接到达服务器
  • 执行 ThreadingMixIn.process_request 方法,创建一个 “线程” 用来处理请求
  • 执行 ThreadingMixIn.process_request_thread 方法
  • 执行 BaseServer.finish_request 方法,执行 self.RequestHandlerClass()  即:执行 自定义 MyRequestHandler 的构造方法(自动调用基类BaseRequestHandler的构造方法,在该构造方法中又会调用 MyRequestHandler的handle方法)

对源码进行精简做一个程序:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

import socket

import threading

import select

def process(request, client_address):

    print request,client_address

    conn = request

    conn.sendall(‘欢迎致电 10086,请输入1xxx,0转人工服务.‘)

    flag = True

    while flag:

        data = conn.recv(1024)

        if data == ‘exit‘:

            flag = False

        elif data == ‘0‘:

            conn.sendall(‘通过可能会被录音.balabala一大推‘)

        else:

            conn.sendall(‘请重新输入.‘)

sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

sk.bind((‘127.0.0.1‘,8002))

sk.listen(5)

while True:

    r, w, e = select.select([sk,],[],[],1)

    print ‘looping‘

    if sk in r:

        print ‘get request‘

        request, client_address = sk.accept()

        = threading.Thread(target=process, args=(request, client_address))

        t.daemon = False

        t.start()

sk.close()

如精简代码可以看出,SocketServer的ThreadingTCPServer之所以可以同时处理请求得益于 select 和 Threading 两个东西,其实本质上就是在服务器端为每一个客户端创建一个线程,当前线程用来处理对应客户端的请求,所以,可以支持同时n个客户端链接(长连接)

 

时间: 2024-08-03 02:42:15

socketserver(多连接)的相关文章

socketserver 并发连接

socketserver.TCPServer Example server side 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import socketserver class MyTCPHandler(socketserver.BaseRequestHandler):     """     The request handler class for our ser

python2.0_s12_day9_协程&Gevent协程

Python之路,Day9 - 异步IO\数据库\队列\缓存 本节内容 Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 协程 1.协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是协程:协程是一种用户态的轻量级线程.(操作系统跟不知道它存在),那你指定协程的实现原理是什么吗? 我们来聊聊协程的实现原理: 首先我们知道多个线程在一个单核CPU上进行并发,它的操作过程是,操作系统能调动的最小单位是线程,当操作系统触发多个线

网络---29 socketserver模块并发 连接合法性

一.socketserver模块 ②服务端 ③客户端 二.连接合法性       ①os.urandom(n) 一种bytes类型的随机生成n个字节字符串的方法 而且每次生成的值都不相同.再加上md5等加密的处理 就能够成内容不同长度相同的字符串了. ②hmac ③ 可见使用hmac和普通hash算法非常类似. hmac输出的长度和原始哈希算法的长度一致. 需要注意传入的key和message都是bytes类型, str类型需要首先编码为bytes. 原文地址:https://www.cnblo

自动化运维Python系列之IO多路复用、SocketServer源码分析

IO多路复用 IO多路复用是指:通过一种机制,可以监视多个描述符,一旦某个系统描述符就绪(一般是读就绪或者写就绪)能够通知程序进行相应的读写操作 实例化例子就是在SocketServer模块中,客户端和服务端建立好连接,此时服务端通过监听conn这条链路,一旦客户端发送了数据,conn链路状态就发生变化,服务端就知道有数据要接收... Linux系统中同时存在select.pull.epoll三种IO多路复用机制 windows中只有select机制 1)select select本质上是通过设

socketserver源码解析和协程版socketserver

来,贴上一段代码让你仰慕一下欧socketserver的魅力,看欧怎么完美实现多并发的魅力 client import socket ip_port = ('127.0.0.1',8009) sk = socket.socket() sk.connect(ip_port) sk.settimeout(5) while True: data = sk.recv(1024) print('receive:',data.decode()) inp = input('please input:') sk

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

本章内容: Socket IO多路复用(select) SocketServer 模块(ThreadingTCPServer源码剖析) Socket socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. 功能: sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0) 参数一:地址簇 socket.AF_INET IPv4(默认)

python开发学习-day08(socket高级、socketserver、进程、线程)

s12-20160305-day08 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* BLOCKS =============================================================================*/ p, blockquote, ul, ol, dl, table, pre { margin

python SocketServer

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

Kafka SocketServer源代码分析

Kafka SocketServer源代码分析 标签: kafka 本文将详细分析Kafka SocketServer的相关源码. 总体设计 Kafka SocketServer是基于Java NIO来开发的,采用了Reactor的模式,其中包含了1个Acceptor负责接受客户端请求,N个Processor负责读写数据,M个Handler来处理业务逻辑.在Acceptor和Processor,Processor和Handler之间都有队列来缓冲请求. kafka.network.Accepto