Django企业开发实战--by胡阳,学习记录1127

标题2.2.3 多线程版的 Web Server

1、书中讲解了引入新的参数“import time以及time.sleep()”的例子,实际应用性并不强,除非有特定的处理界面需要指定时长,以及客户端只能同时一个人访问的限制,因此接着讲到了第2点,也就是多线程Web Server

2、多线程的源代码如下所示,但遇到了新的问题,按照书中所示,#25行会和#46会有冲突,**如果将setblocking置为“0”的非阻塞模式,会报错“BlockingIOError: [WinError 10035] 无法立即完成一个非阻止性套接字操作。”**可以直接将setblocking置为“1”的阻塞模式,绕过此问题,但不是很清楚具体原因,找了很多答案,总结起来就是“设置了non-block模式后, recv如果无法接受到数据, 就会报异常”。这一点希望能够有蟒友点拨一下,对初学者来讲并不是很好理解。

3、手敲这段代码的时候依旧遇到了敲错字符的问题,期初以为是环境的问题,因为放到IDE里面运行并不报错,但无法进入访问界面。后来全部删除重新手敲,问题解决。得到的经验是,永远不要怀疑书中有低级错误,如果自己实践出来和书中讲的不一致,肯定是自己的问题。实在找不到原因,可以选择重头来过,手敲花不了10分钟。

4、另外放2张socket原理图解(copy from:https://blog.csdn.net/weixin_39634961/article/details/80236161),以便自己随时温习。

import errno
import socket
import threading
import time

EOL1 = b'\n\n'
EOL2 = b'\n\r\n'
body = '''Hello, world! 

from the5fire 《Django企业开发实战》

- from {thread_name}''' response_params = [ 'HTTP/1.0 200 OK', 'Date: Sun, 27 may 2018 01:01:01 GMT', 'Content-Type: text/plain; charset=utf-8', 'Content-Length: {length}\r\n', body, ] response = '\r\n'.join(response_params) def handle_connection(conn,addr): print(conn,addr) time.sleep(60) request = b"" while EOL1 not in request and EOL2 not in request: request += conn.recv(1024) # 注意在设置为非阻塞模式时这里会有报错,建议自己探索一下问题来源。 print(request) current_thread = threading.currentThread() content_length = len(body.format(thread_name=current_thread.name).encode()) print(current_thread.name) conn.send(response.format(thread_name=current_thread.name, length=content_length).encode()) conn.close() def main(): # socket.AF_INET 用于服务器与服务器之间的网络通信 # socket.SOCK_STREAM 基于TCP的流式socket通信 serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 设置端口可复用,保证我们每次Ctrl C之后,快速再次重启 serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) serversocket.bind(('127.0.0.1', 8000)) # 可参考:https://stackoverflow.com/questions/2444459/python-sock-listen serversocket.listen(10) print('http://127.0.0.1:8000') serversocket.setblocking(1) # 设置socket为非阻塞模式 try: i = 0 while True: try: conn, address = serversocket.accept() except socket.error as e: if e.args[0] != errno.EAGAIN: raise continue i += 1 print(i) t = threading.Thread(target=handle_connection, args=(conn, address), name='thread-%s' % i) t.start() finally: serversocket.close() if __name__ == '__main__': main()

Django企业开发实战--by胡阳,学习记录1127_第1张图片Django企业开发实战--by胡阳,学习记录1127_第2张图片

你可能感兴趣的:(Django)