今天在膜拜shadsocks代码的时候发现,大神的代码如此精美、
发生的情况基本如下:
1 初始化一个TCPHandler,当然他不是这么叫的。
2 初始化一个Eventloop。
3 将这个TCPHandler放入到EventLoop中。
4 之后 在TCPHandler下加入EventLOOP中的代码。
可以看到
self._eventloop.add(self._server_socket, eventloop.POLL_IN | eventloop.POLL_ERR, self) 最后是传入self,即将TCPHandler的引用传过去。
def add_to_loop(self, loop): if self._eventloop: raise Exception(‘already add to loop‘) if self._closed: raise Exception(‘already closed‘) self._eventloop = loop self._eventloop.add(self._server_socket, eventloop.POLL_IN | eventloop.POLL_ERR, self) self._eventloop.add_periodic(self.handle_periodic)
5 EventLoop是整个程序的驱动基础,他来处理socket轮询的问题。但 他并不处理socket的数据问题。 所以有这么个变量在里面:
self._fdmap = {} # (f, handler)
f 是 fileno()。 我们知道fileno()是会返回 stream status。 一般是指file descriptor,这里就是stream descriptor。 当然file也是stream处理。
什么意思呢,就是存储一个socket,对应一个handler。
6: 怎么调用这个回调函数呢。
for sock, fd, event in events: handler = self._fdmap.get(fd, None) if handler is not None: handler = handler[1] try: handler.handle_event(sock, fd, event) except (OSError, IOError) as e: shell.print_exception(e)
很清楚,在轮询这个socket的时候,依然用 产生 这个socket的 handler来处理。
这个设计很nice
这个回调函数说简单点就是 回头函数。
eg:callback_function()--->invoke callback_function.some_function(self) ---> some_function()-->invoke callbackfunction()[[[ 此时调用就需要使用传过来的self了]]]
懂了这个的话,就基本清楚整个shadowsocks的程序了。
时间: 2024-10-07 05:18:45