TreadingTCPServer

Posted daemon-xinetd

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TreadingTCPServer相关的知识,希望对你有一定的参考价值。

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

1、TreadingTCPServer基础

使用TreadingTCPServer:

  创建一个继承socketserver.BaseRequestHandler的类

  类中必须定义一个名称为handle的方法

  启动TreadingTCPServer

import SocketServer

class MyServer(SocketServer.BaseRequestHandler):

    def handle(self):
        # print self.request,self.client_address,self.server
        conn = self.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(\'请重新输入.\')


if __name__ == \'__main__\':
    server = SocketServer.ThreadingTCPServer((\'127.0.0.1\',8009),MyServer)
    server.serve_forever()
View Code


 

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
    inp = raw_input(\'please input:\')
    sk.sendall(inp)
    if inp == \'exit\':
        break

sk.close()
View Code

2、TreadingTCPServer源码剖析

TreadingTCPServer的类图关系如下:

内部调用流程为:

  1、启动服务端程序

  2、执行TCPServer.__init__方法,创建服务端socket对象并绑定IP和端口

  3、执行BaseServer.__init__方法,将自定义的继承自socketserver.BaseRequestHandler的类赋值给self.RequestHandlerClass

  4、执行BaseServer.server_forever方法,while循环一直监听是否有客户端请求到达

  5、当客户端链接到达服务器

  6、执行ThreadingMixIn.process_request方法,创建一个线程用来处理请求

  7、执行TreadingMixIn.process_request_thread方法

  8、执行BaseServer.finish_request方法,执行self.RequestHandleClass(),即:执行自定义MyRequestHandle的构造方法(自动调用基类BaseRequestHandler的构造方法,在该构造方法中会调用MyRequestHandler的handle方法)

 

源码精简:

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()
        t = threading.Thread(target=process, args=(request, client_address))
        t.daemon = False
        t.start()

sk.close()
View Code

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

 

以上是关于TreadingTCPServer的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段——CSS选择器

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段6——CSS选择器

VSCode自定义代码片段——声明函数