为了实现TCPServer的功能,定义一个类用于继承TCPServer并实现handle_stream方法。HttpServer就是一个很好的例子。

13.1 构造函数

def __init__(self, io_loop=None, ssl_options=None, max_buffer_size=None,
read_chunk_size=None):
self.io_loop = io_loop
self.ssl_options = ssl_options
self._sockets = {} # fd -> socket object
self._pending_sockets = []
self._started = False
self.max_buffer_size = max_buffer_size
self.read_chunk_size = read_chunk_size # Verify the SSL options. Otherwise we don't get errors until clients
# connect. This doesn't verify that the keys are legitimate, but
# the SSL module doesn't do that until there is a connected socket
# which seems like too much work
if self.ssl_options is not None and isinstance(self.ssl_options, dict):
# Only certfile is required: it can contain both keys
if 'certfile' not in self.ssl_options:
raise KeyError('missing key "certfile" in ssl_options') if not os.path.exists(self.ssl_options['certfile']):
raise ValueError('certfile "%s" does not exist' %
self.ssl_options['certfile'])
if ('keyfile' in self.ssl_options and
not os.path.exists(self.ssl_options['keyfile'])):
raise ValueError('keyfile "%s" does not exist' %
self.ssl_options['keyfile'])

     实现流程如下:

(1) 设置属性。

(2) 判断是否支持SLL,如果支持,判断证书文件以及秘钥文件是否存在。

13.2 监听 listen

          开启指定端口的接收连接。

          为了监听多个端口时,这个方法可能会被调用多次。这个方法会立即起作用,不需要调用TCPServer.start方法。但是,还是有必要启动IOLoop。

def listen(self, port, address=""):
"""Starts accepting connections on the given port. This method may be called more than once to listen on multiple ports.
`listen` takes effect immediately; it is not necessary to call
`TCPServer.start` afterwards. It is, however, necessary to start
the `.IOLoop`.
"""
sockets = bind_sockets(port, address=address)
self.add_sockets(sockets)

          调用bind_sockets方法来获得sockets集合对象。调用add_sockets方法循环处理每一个sockets对象,主要注册socket建立连接后的处理回调函数。

13.3 添加sockets (add_sockets)

def add_sockets(self, sockets):
"""Makes this server start accepting connections on the given sockets. The ``sockets`` parameter is a list of socket objects such as
those returned by `~tornado.netutil.bind_sockets`.
`add_sockets` is typically used in combination with that
method and `tornado.process.fork_processes` to provide greater
control over the initialization of a multi-process server.
"""
if self.io_loop is None:
self.io_loop = IOLoop.current() for sock in sockets:
self._sockets[sock.fileno()] = sock
add_accept_handler(sock, self._handle_connection,
io_loop=self.io_loop)

         针对每一个socket, 注册socket建立连接后的处理回调函数,回调函数为内部方法_handle_connection。

13.4 关闭服务器(stop)

def stop(self):
"""Stops listening for new connections. Requests currently in progress may still continue after the
server is stopped.
"""
for fd, sock in self._sockets.items():
self.io_loop.remove_handler(fd)
sock.close()

         关闭服务器,停止监新的请求连接。在服务器关闭之后,当前正在处理的请求会继续执行。

        执行逻辑就是,对服务器中所有的sockets对象,调用两个方法,一个是移除io_loop中的处理回调函数,一个是关闭socket.

 

13.5 socket的建立连接后的回调函数 _handle_connection

           socket处理请求时,这个方法是回调函数,用来处理请求流。如果请求是SSL请求,则初始化SSLIOStream类,如果不是SSL请求,则初始化IOStream类。初始化Stream之后,调用handle_stream方法来处理stream.handler_stream方法一般由TCPServer的子类实现,比如HttpServer就有具体的实现。

Tornado 学习笔记13 TCPServer的更多相关文章

  1. tornado 学习笔记1 引言

    从事软件开发这行业也快5年啦,其实从事的工作也不完全是软件开发,软件开发只是我工作中的一部分.其中包括课题研究.信息化方案设计.软件开发.信息系统监理.项目管理等工作,比较杂乱.开发的软件比较多,但是 ...

  2. Ext.Net学习笔记13:Ext.Net GridPanel Sorter用法

    Ext.Net学习笔记13:Ext.Net GridPanel Sorter用法 这篇笔记将介绍如何使用Ext.Net GridPanel 中使用Sorter. 默认情况下,Ext.Net GridP ...

  3. SQL反模式学习笔记13 使用索引

    目标:优化性能 改善性能最好的技术就是在数据库中合理地使用索引.  索引也是数据结构,它能使数据库将指定列中的某个值快速定位在相应的行. 反模式:无规划的使用索引 1.不使用索引或索引不足 2.使用了 ...

  4. Tornado学习笔记(一) helloword/多进程/启动参数

    前言 当你觉得你过得很舒服的时候,你肯定没有在进步.所以我想学习新的东西,然后选择了Tornado.因为我觉得Tornado更匹配目前的我的综合素质. Tornado学习笔记系列主要参考<int ...

  5. golang学习笔记13 Golang 类型转换整理 go语言string、int、int64、float64、complex 互相转换

    golang学习笔记13 Golang 类型转换整理 go语言string.int.int64.float64.complex 互相转换 #string到intint,err:=strconv.Ato ...

  6. springmvc学习笔记(13)-springmvc注解开发之集合类型參数绑定

    springmvc学习笔记(13)-springmvc注解开发之集合类型參数绑定 标签: springmvc springmvc学习笔记13-springmvc注解开发之集合类型參数绑定 数组绑定 需 ...

  7. Python3+Selenium3+webdriver学习笔记13(js操作应用:弹出框无效如何处理)

    #!/usr/bin/env python# -*- coding:utf-8 -*-'''Selenium3+webdriver学习笔记13(js操作应用:弹出框无效如何处理)'''from sel ...

  8. 并发编程学习笔记(13)----ConcurrentLinkedQueue(非阻塞队列)和BlockingQueue(阻塞队列)原理

    · 在并发编程中,我们有时候会需要使用到线程安全的队列,而在Java中如果我们需要实现队列可以有两种方式,一种是阻塞式队列.另一种是非阻塞式的队列,阻塞式队列采用锁来实现,而非阻塞式队列则是采用cas ...

  9. python 学习笔记 13 -- 经常使用的时间模块之time

    Python 没有包括相应日期和时间的内置类型.只是提供了3个相应的模块,能够採用多种表示管理日期和时间值: *    time 模块由底层C库提供与时间相关的函数.它包括一些函数用于获取时钟时间和处 ...

随机推荐

  1. redis教程(整理中)

    一.redis简介 1.Redis:键值对类型的内存数据库:应用于高并发和实时请求的场景: 2.Redis常用数据类型: (1) string(基本数据类型)     (2)hash 注:hash中的 ...

  2. iOS 关于修饰代理用weak还是assign

    对于weak:指明该对象并不负责保持delegate这个对象,delegate这个对象的销毁由外部控制. 对于strong:该对象强引用delegate,外界不能销毁delegate对象,会导致循环引 ...

  3. C和指针 第五章 逻辑位移与算术位移

    对于操作数的左位移都是相同的,右边空出来的位置用0补齐. 但是对于右位移,对于有符号和无符号数是不一样的,最高位的1有两种处理方式.逻辑位移和算术位移. 逻辑位移:右移入位用0补齐 算术位移:右移入位 ...

  4. Two Sum Leetcode Java

    Given an array of integers, return indices of the two numbers such that they add up to a specific ta ...

  5. error 502 in ngin php5-fpm

    unix:/var/run/php5-fpm.sock failed (11: Resource temporarily unavailable) http://stackoverflow.com/q ...

  6. Unity3D代码旋转

    subGameObject.transform.Rotate (,,,Space.Self); 一行代码

  7. FluentValidation

    git :https://github.com/JeremySkinner/FluentValidation Example using FluentValidation; public class ...

  8. bootstrap 笔记

    导航条: div.navbar.navbar-default > ul.nav.navbar 无非两层: 父div: navbar {相对位置.最低高度50px.下部margin:20px.透明 ...

  9. java12

    1:List的子类(掌握) (1)List的子类特点 ArrayList: 底层数据结构是数组,查询快,增删慢 线程不安全,效率高 Vector: 底层数据结构是数组,查询快,增删慢 线程安全,效率低 ...

  10. selenium 总结篇,常见方法和页面元素的操作

    今天,总结一下selenium怎么操作web页面常见的元素. 主要有: 上传 alter dialog prompt dialog confirm dialog select list radio b ...