if bind_and_activate: try: self.server_bind() self.server_activate() except: self.server_close() raise
step 4.1
1 2 3 4 5 6 7 8 9 10
defserver_bind(self): """Called by constructor to bind the socket. May be overridden. """ if self.allow_reuse_address: self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.socket.bind(self.server_address) self.server_address = self.socket.getsockname()
defserve_forever(self, poll_interval=0.5): """Handle one request at a time until shutdown. Polls for shutdown every poll_interval seconds. Ignores self.timeout. If you need to do periodic tasks, do them in another thread. """ self.__is_shut_down.clear() try: # XXX: Consider using another file descriptor or connecting to the # socket to wake this up instead of polling. Polling reduces our # responsiveness to a shutdown request and wastes cpu at all other # times. with _ServerSelector() as selector: selector.register(self, selectors.EVENT_READ)
def_handle_request_noblock(self): """Handle one request, without blocking. I assume that selector.select() has returned that the socket is readable before this function was called, so there should be no risk of blocking in get_request(). """ try: request, client_address = self.get_request() # 获取到客户端连接对象socket,和客户端地址 except OSError: return if self.verify_request(request, client_address): try: self.process_request(request, client_address) except: self.handle_error(request, client_address) self.shutdown_request(request)
step 5.3
1
request, client_address = self.get_request()
根据类图查找,在TCPServer类中
1 2 3 4 5 6 7
defget_request(self): """Get the request and client address from the socket. May be overridden. """ return self.socket.accept()
defprocess_request(self, request, client_address): """Start a new thread to process the request.""" t = threading.Thread(target = self.process_request_thread, args = (request, client_address)) t.daemon = self.daemon_threads t.start()
在这个方法中,使用了多线程去执行self.process_request_thread方法
1 2
t = threading.Thread(target = self.process_request_thread, args = (request, client_address))
使用了self调用,还是要从头查找
step 7
在ThreadingMixIn类中找到
1 2 3 4 5 6 7 8 9 10 11 12
defprocess_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)
这个方法应该是用来接收客户端发来的请求以及给客户端发送消息
step 8
1
self.finish_request(request, client_address)
根据类图,在BaseServer中找到
1 2 3
deffinish_request(self, request, client_address): """Finish one request by instantiating RequestHandlerClass.""" self.RequestHandlerClass(request, client_address, self)
for s in rList: # 判断socket对象如果是服务端的socket对象的话 if s == sk: conn, address = s.accept() # conn也是一个socket对象 # 当服务端socket接收到客户的请求后,会分配一个新的socket对象专门用来和这个客户端进行连接通信
for s in rList: # 判断socket对象如果是服务端的socket对象的话 if s == sk: conn, address = s.accept() # conn也是一个socket对象 # 当服务端socket接收到客户的请求后,会分配一个新的socket对象专门用来和这个客户端进行连接通信
for s in rList: # 判断socket对象如果是服务端的socket对象的话 if s == sk: conn, address = s.accept() # conn也是一个socket对象 # 当服务端socket接收到客户的请求后,会分配一个新的socket对象专门用来和这个客户端进行连接通信
# 遍历rList(建立连接和接收数据) for s in rList: # 判断socket对象如果是服务端的socket对象的话 if s == sk: conn, address = s.accept() # conn也是一个socket对象 # 当服务端socket接收到客户的请求后,会分配一个新的socket对象专门用来和这个客户端进行连接通信
# 遍历rList(建立连接和接收数据) for s in rList: # 判断socket对象如果是服务端的socket对象的话 if s == sk: conn, address = s.accept() # conn也是一个socket对象 # 当服务端socket接收到客户的请求后,会分配一个新的socket对象专门用来和这个客户端进行连接通信
l = [x + 1for x in range(10) if x > 5] print("display list --->", l) print("first element --->", l[0])
print("---" * 5)
ll = [lambda :x for x in range(10) if x > 5] print("display list --->", ll)
ret = ll[0]() print("first element --->", ret)
结果是:
1 2 3 4 5
display list ---> [7, 8, 9, 10] first element ---> 7 --------------- display list ---> [<function <listcomp>.<lambda> at 0x101b7b730>, <function <listcomp>.<lambda> at 0x101b7b7b8>, <function <listcomp>.<lambda> at 0x101b7b840>, <function <listcomp>.<lambda> at 0x101b7b8c8>] first element ---> 9
lllll = [] for x in range(10): if x > 5: deffunc(i = x): return i lllll.append(func) print(lllll) print(lllll[0]()) print(lllll[1]()) print(lllll[2]()) print(lllll[3]())
------------ [<function func at 0x101b7b620>, <function func at 0x101b7b6a8>, <function func at 0x101b7b730>, <function func at 0x101b7b7b8>] 6 7 8 9
"""Base class for request handler classes. This class is instantiated for each request to be handled. The constructor sets the instance variables request, client_address and server, and then calls the handle() method. To implement a specific service, all you need to do is to derive a class which defines a handle() method. The handle() method can find the request as self.request, the client address as self.client_address, and the server (in case it needs access to per-server information) as self.server. Since a separate instance is created for each request, the handle() method can define arbitrary other instance variariables. """
# III. Server <--- Client # 接收客户端发送的确认开始传输的命令 feedback = str(conn.recv(1024), encoding='utf-8') if feedback == "confirm": # IV. Server ---> Client # 开始向客户端传输数据 conn.send(send_data)