原文请见:http://www.cnblogs.com/wupeiqi/articles/5040823.html

这里就是自己简单整理一下:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
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()

 程序先运行server的一个实例,socket.server.ThreadingTCPServer的构造方法,

server继承ThreadingMixIn, TCPServer这两个类,构造方法只有TCPServer的类有并且继承其父类BaseServer的构造方法。

TCPSever的构造方法(这个构造方法会执行bind和listen):

    def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True):
"""Constructor. May be extended, do not override."""
BaseServer.__init__(self, server_address, RequestHandlerClass)
self.socket = socket.socket(self.address_family,
self.socket_type)
if bind_and_activate:
try:
self.server_bind()
self.server_activate()
except:
self.server_close()
raise

  BaseServer的构造方法:

    def __init__(self, server_address, RequestHandlerClass):
"""Constructor. May be extended, do not override."""
self.server_address = server_address
self.RequestHandlerClass = RequestHandlerClass
self.__is_shut_down = threading.Event()
self.__shutdown_request = False

  在BaseServer中的构造方法中MyServer类赋给了实例的属性RequestHandlerClass ,相当于server实例有了这个属性。server实例创建完成。

然后是执行server的server_forever方法,

接下来就是BaseServer的server_forever方法->BaseServer的_handle_request_noblock方法->ThreadingMixIn的process_request方法(TCPServer和ThreadingMixIn都有这个方法,但ThreadingMixIn优先级高所以是ThreadMixIn的这个方法)->ThreadingMixIn的process_request_thread方法(这时候是多线程中的一个线程的具体处理方法了)

    def process_request_thread(self, request, client_address):
"""Same as in BaseServer but as a thread. In addition, exception handling is done here. """
try:
self.finish_request(request, client_address)
self.shutdown_request(request)
except:
self.handle_error(request, client_address)
self.shutdown_request(request)

  ->BaseServer的finish_request方法(调用实例的这个方法,这个方法ThreadMixIn中没有BaseServer中有,这时候会执行RequestHandlerClass的构造方法也就是我们写的MyServer的构造方法,但是MyServer中没有需要MyServer的父类中查找)

    def finish_request(self, request, client_address):
"""Finish one request by instantiating RequestHandlerClass."""
self.RequestHandlerClass(request, client_address, self)

  ->BaseRequestHandler的构造方法

    def __init__(self, request, client_address, server):
self.request = request
self.client_address = client_address
self.server = server
self.setup()
try:
self.handle()
finally:
self.finish()

  这上面finish,setup都是空的,handle是MyServer中定义的,这几个方法都需要我们自定义,

->MyServer的handle方法

->TcpServer的shutdown_request方法

->TcpServer的close_request方法

    def close_request(self, request):
"""Called to clean up an individual request."""
request.close()

  这里request一直是client端的socket,到这里就关闭socket了算是完成了一次处理。

python socket server源码学习的更多相关文章

  1. 【Python】Webpy 源码学习

    那么webpy是什么呢? 阅读它的源码我们又能学到什么呢? 简单说webpy就是一个开源的web应用框架(官方首页:http://webpy.org/) 它的源代码非常整洁精干,学习它一方面可以让我们 ...

  2. Hadoop源码学习笔记(4) ——Socket到RPC调用

    Hadoop源码学习笔记(4) ——Socket到RPC调用 Hadoop是一个分布式程序,分布在多台机器上运行,事必会涉及到网络编程.那这里如何让网络编程变得简单.透明的呢? 网络编程中,首先我们要 ...

  3. .NET Core 2.1 源码学习:看 SocketsHttpHandler 如何在异步方法中连接 Socket

    在 .NET Core 2.1 中,System.Net.Sockets 的性能有了很大的提升,最好的证明是 Kestrel 与 HttpClient 都改为使用 System.Net.Sockets ...

  4. python源码学习(一)——python的总体架构

    python源码学习(一)——python的总体架构 学习环境: 系统:ubuntu 12.04 STLpython版本:2.7既然要学习python的源码,首先我们要在电脑上安装python并且下载 ...

  5. Seata Server 1.5.2 源码学习

    Seata 包括 Server端和Client端.Seata中有三种角色:TC.TM.RM,其中,Server端就是TC,TM和RM属Client端.Client端的源码学习上一篇已讲过,详见 < ...

  6. python 协程库gevent学习--gevent源码学习(二)

    在进行gevent源码学习一分析之后,我还对两个比较核心的问题抱有疑问: 1. gevent.Greenlet.join()以及他的list版本joinall()的原理和使用. 2. 关于在使用mon ...

  7. 转载-FileZilla Server源码分析(1)

    FileZilla Server源码分析(1) 分类: VC 2012-03-27 17:32 2363人阅读 评论(0) 收藏 举报 serversocketftp服务器usersockets工作 ...

  8. Netty源码学习系列之4-ServerBootstrap的bind方法

    前言 今天研究ServerBootstrap的bind方法,该方法可以说是netty的重中之重.核心中的核心.前两节的NioEventLoopGroup和ServerBootstrap的初始化就是为b ...

  9. MVC系列——MVC源码学习:打造自己的MVC框架(四:了解神奇的视图引擎)

    前言:通过之前的三篇介绍,我们基本上完成了从请求发出到路由匹配.再到控制器的激活,再到Action的执行这些个过程.今天还是趁热打铁,将我们的View也来完善下,也让整个系列相对完整,博主不希望烂尾. ...

随机推荐

  1. 动态设置 button的 name 的话 闪动的问题 解决

    其实 只要把  button设置成  custom 的  type 的话   就会 解决这个问题

  2. oracle分页查询sql

    select * from( select shopid,rownum rn from p_shopinfo where is_hot=1 and rownum <=6 order by sho ...

  3. Socket accept failed

    启动tomcat显示如下错误: java.net.SocketException: select failed at java.net.PlainSocketImpl.socketAccept(Nat ...

  4. configparser配置文件操作

    configparser 模块用于对配置操作  官方文档地址https://docs.python.org/3/library/configparser.html 导入configparser模块 i ...

  5. JavaScript语法结构

    一:字符集 1.区分大小写 JavaScript是区分大小写的语言 所有的标识符(identifier)都必须采取一致的大小写形式 但是Html并不区分大小写(尽管Xhtml区分) 2.空格.换行符和 ...

  6. 关于delphi点击webbrowser中任意一点的问题

    关于delphi点击webbrowser中任意一点的问题 有时候我们需要delphi载入webbrowser1打开网页的时候 需要点击某一个点的位置 可能是坐标 可能是按钮 可能是其他的控件应该如何来 ...

  7. python课程第一周重点记录

  8. IOS中无缓存的图片载入

    在IOS中,我们常用[UIImage imageNamed]方法获取图像,这种方法简便,容易理解.但是有个缺点,就是有缓存.这种方式 传人的图像的就是通过文件名方式文件名.如果,我们内存有限,我们就必 ...

  9. C#数据结构选择

    选择一个合适的数据结构会对程序的性能有着显著的提高 线性表和链表: 1.LinkedList<T>:适合于元素数组不固定,存在大量列表的头尾添加动作场合.其它可使用List<T> ...

  10. Winform主窗体设计

    主窗体顶部为菜单按钮,子窗体内嵌入Panel显示 界面如下: 第二步,主窗体离不开的几个方法 1,点击菜单功能,加载子窗体 private void btnOpenForm_Click(object ...