新手实现的 Python web 框架的代码在 win7 运行报错, Ubuntu 正常运行,求助大佬 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
taoing

新手实现的 Python web 框架的代码在 win7 运行报错, Ubuntu 正常运行,求助大佬

  •  
  •   taoing 2018 年 5 月 21 日 3338 次点击
    这是一个创建于 2892 天前的主题,其中的信息可能已经有所发展或是发生改变。

    服务器代码:

    import socket from multiprocessing import Process import re class HTTPServer(object): def __init__(self, application): self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.app = application def bind(self, port): print('port:',port) self.server_socket.bind(('', port)) def start(self): self.server_socket.listen(128) print('HTTP server is running...') while True: conn_socket, client_addr = self.server_socket.accept() print('connection from %s : %s' % client_addr) # 创建新进程处理客户端连接 p = Process(target = self.handle_request, args = (conn_socket,)) p.start() conn_socket.close() def start_response(self, status, headers): server_headers = [ ('Server', 'MyWebServer 1.0') ] server_headers = headers + server_headers # 构造响应首部行 response_headers = 'HTTP/1.1 ' + status + '\r\n' for header in server_headers: response_headers = response_headers + '%s:%s' % header + '\r\n' self.response_headers = response_headers def handle_request(self, conn_socket): '''处理客户端请求''' env = {} request_data = conn_socket.recv(2048).decode('utf-8') print('request from client:') print(request_data) '''解析请求返回响应''' # 请求行 reuqestmethodline = request_data.split('\r\n')[0] # 请求方法 requestmethod = reuqestmethodline.split(' ', 1)[0] # 请求资源 requestpath = re.match(r'\w+\s+(/[a-zA-Z0-9\_\.]*)',reuqestmethodline).group(1) env['Method'] = requestmethod env['PATH_INFO'] = requestpath # 返回响应体 response_body = self.app(env, self.start_response) respOnse= self.response_headers + '\r\n' + response_body print('response from server:') print(response) conn_socket.send(response.encode('utf-8')) conn_socket.close() 

    web 框架代码:

    import time from mywebserver import HTTPServer class Application(object): # 框架的核心部分 def __init__(self, urls): self.urls = urls def __call__(self, env, start_response): path = env.get('PATH_INFO', '/') for url, handler in self.urls: if path == url: response_body = handler(env, start_response) return response_body # 请求路径不存在,返回 404 响应码 status = '404 Not Found' headers = [('Content-Type', 'text/html')] start_response(status, headers) response_body = 'The file not found!' return response_body def ctime(env, start_response): status ='200 OK' headers = [('Content-Type', 'text/html')] start_response(status, headers) return time.ctime() def hello(env, start_response): status = '200 OK' headers = [('Content-Type', 'text/html')] start_response(status, headers) return 'Hello, World!' urls = [ ('/', hello), ('/ctime', ctime), ('/hello', hello) ] app = Application(urls) http_server = HTTPServer(app) http_server.bind(8000) http_server.start() 

    在 win7 python3.5.2 上运行报错:

    λ python mywebframe.py port: 8000 HTTP server is running... connection from 127.0.0.1 : 50094 connection from 127.0.0.1 : 50095 port: 8000 Traceback (most recent call last): File "<string>", line 1, in <module> File "C:\Users\taomian\AppData\Local\Programs\Python\Python35\lib\multiprocessing\spawn.py", line 106, in spawn_main exitcode = _main(fd) File "C:\Users\taomian\AppData\Local\Programs\Python\Python35\lib\multiprocessing\spawn.py", line 115, in _main prepare(preparation_data) File "C:\Users\taomian\AppData\Local\Programs\Python\Python35\lib\multiprocessing\spawn.py", line 226, in prepare _fixup_main_from_path(data['init_main_from_path']) File "C:\Users\taomian\AppData\Local\Programs\Python\Python35\lib\multiprocessing\spawn.py", line 278, in _fixup_main_from_path run_name="__mp_main__") File "C:\Users\taomian\AppData\Local\Programs\Python\Python35\lib\runpy.py", line 254, in run_path pkg_name=pkg_name, script_name=fname) File "C:\Users\taomian\AppData\Local\Programs\Python\Python35\lib\runpy.py", line 96, in _run_module_code mod_name, mod_spec, pkg_name, script_name) File "C:\Users\taomian\AppData\Local\Programs\Python\Python35\lib\runpy.py", line 85, in _run_code exec(code, run_globals) File "D:\Documents\python\code\2.2 wsgi_server\mywebframe.py", line 40, in <module> port: 8000 http_server.bind(8000) Traceback (most recent call last): File "D:\Documents\python\code\2.2 wsgi_server\mywebserver.py", line 11, in bind File "<string>", line 1, in <module> File "C:\Users\taomian\AppData\Local\Programs\Python\Python35\lib\multiprocessing\spawn.py", line 106, in spawn_main self.server_socket.bind(('', port)) OSError: [WinError 10048] 通常每个套接字地址(协议 /网络地址 /端口)只允许使用一次。 

    在 ubuntu 上 python3.5.2 正常运行:

    allen@ubuntu:~/test/code$ python3 mywebframe.py port: 8000 HTTP server is running... connection from 127.0.0.1 : 45618 request from client: GET / HTTP/1.1 Host: 127.0.0.1:8000 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-GB,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive Upgrade-Insecure-Requests: 1 response from server: HTTP/1.1 200 OK Content-Type:text/html Server:MyWebServer 1.0 Hello, World! connection from 127.0.0.1 : 45620 request from client: GET /favicon.ico HTTP/1.1 Host: 127.0.0.1:8000 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-GB,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive response from server: HTTP/1.1 404 Not Found Content-Type:text/html Server:MyWebServer 1.0 The file not found! 
    12 条回复    2018-05-21 23:45:15 +08:00
    taoing
        1
    taoing  
    OP
       2018 年 5 月 21 日
    在 win7 上看报错提示,我理解是端口 8000 被绑定了两次导致出错,不知道为什么会出现这种情况,想请教大佬可以给我解答。
    ycfung
        2
    ycfung  
       2018 年 5 月 21 日 via Android
    你这代码贴得太可怕了…
    wwqgtxx
        3
    wwqgtxx  
       2018 年 5 月 21 日
    在 windows 下不要用“创建新进程处理客户端连接”这种方式,会出各种诡异的问题,应该使用“新线程”
    wwqgtxx
        4
    wwqgtxx  
       2018 年 5 月 21 日
    另外这三行代码
    http_server = HTTPServer(app)
    http_server.bind(8000)
    http_server.start()
    应该包裹在
    if __name__ == '__main__':
    中,否则容易出现重复 start你的 http_server 的情况
    taoing
        5
    taoing  
    OP
       2018 年 5 月 21 日
    @wwqgtxx 好,我试试用线程看看
    DevNet
        6
    DevNet  
       2018 年 5 月 21 日 via Android
    可能是前一次运行已经占用了这个端口,然后一直没释放? kill 试试,
    或者管理员权限问题?
    wwqgtxx
        7
    wwqgtxx  
       2018 年 5 月 21 日
    根本原因只在于 windows 不支持 fork 模式,他的 process 是重新起一个新的 Python.exe 实现的,所以会再次 import 一次你的 mywebframe.py,而不过你没有把启动代码包裹在 if __name__ == '__main__': 中就会导致这一段代码再一次在子进程中被执行
    taoing
        8
    taoing  
    OP
       2018 年 5 月 21 日
    @wwqgtxx 谢谢你的解答,原来系统间有差异,然后试了 if __name__ == '__main__':就没有报错了
    iConnect
        9
    iConnect  
       2018 年 5 月 21 日 via Android
    如果你生产环境是 Ubuntu,就不用管 win 上报错了,我们经理都要求所有人环境统一,减少系统差异带来额外的 bug
    taoing
        10
    taoing  
    OP
       2018 年 5 月 21 日
    @iConnect 我是个新手在学,只好在自己电脑上试
    so1n
        11
    so1n  
       2018 年 5 月 21 日 via Android
    用 linux 吧,win 不能 fork 也没有 epoll 事件循环
    lidongyx
        12
    lidongyx  
       2018 年 5 月 21 日 via iPhone
    学技术就不要在 windows 环境下折腾了,你折腾出来的这点经验都是浪费时间,因为生产实践中还是要用 linux 的,用虚拟机或者开发板、云服务器、双系统吧
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5668 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 69ms UTC 06:52 PVG 14:52 LAX 23:52 JFK 02:52
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86