Python web 框架在 win7 运行报错,Ubuntu 正常运行,求助大佬

服务器代码:

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](/user/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!


Python web 框架在 win7 运行报错,Ubuntu 正常运行,求助大佬

13 回复

在 win7 上看报错提示,我理解是端口 8000 被绑定了两次导致出错,不知道为什么会出现这种情况,想请教大佬可以给我解答。


这个问题很常见,通常是Windows和Linux环境差异导致的,比如路径、编码、依赖库或系统服务。

先看报错信息,大概率是这几个地方有问题:

  1. 路径分隔符:Windows用\,Linux用/。用os.path.join()pathlib来处理路径最省心。
  2. 文件编码:特别是项目里有非ASCII字符的文件名或内容时,在Python文件开头加# -*- coding: utf-8 -*-,读写文件时明确指定encoding='utf-8'
  3. 依赖库版本或系统库:有些库在Windows上需要额外的二进制包,比如mysqlclient可能不如pymysql好装。用pip check看看依赖冲突,或者试试pip install --upgrade更新所有包。
  4. 环境变量:比如数据库连接字符串在系统环境变量里设置的不同。检查os.environ或者用.env文件统一管理。

最直接的办法是把完整的报错信息贴出来,这样能更快定位问题。通常就是环境配置的事儿,仔细对比两边环境就能解决。

你这代码贴得太可怕了…

在 windows 下不要用“创建新进程处理客户端连接”这种方式,会出各种诡异的问题,应该使用“新线程”

另外这三行代码
http_server = HTTPServer(app)
http_server.bind(8000)
http_server.start()
应该包裹在
if name == ‘main’:
中,否则容易出现重复 start 你的 http_server 的情况

好,我试试用线程看看

可能是前一次运行已经占用了这个端口,然后一直没释放? kill 试试,
或者管理员权限问题?

根本原因只在于 windows 不支持 fork 模式,他的 process 是重新起一个新的 Python.exe 实现的,所以会再次 import 一次你的 mywebframe.py,而不过你没有把启动代码包裹在 if name == ‘main’: 中就会导致这一段代码再一次在子进程中被执行

谢谢你的解答,原来系统间有差异,然后试了 if name == ‘main’:就没有报错了

如果你生产环境是 Ubuntu,就不用管 win 上报错了,我们经理都要求所有人环境统一,减少系统差异带来额外的 bug

我是个新手在学,只好在自己电脑上试

用 linux 吧,win 不能 fork 也没有 epoll 事件循环

学技术就不要在 windows 环境下折腾了,你折腾出来的这点经验都是浪费时间,因为生产实践中还是要用 linux 的,用虚拟机或者开发板、云服务器、双系统吧

回到顶部