且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Python 技术篇 - 修改源码解决中文主机名导致的flask、socket服务起不来问题: ‘utf-8‘ codec can‘t decode byte 0xc0 in position...

更新时间:2021-08-21 02:49:16

由于主机名为中文导致的 flask 服务起不来,报错如下:

File "D:\work\python3.9_64\lib\socket.py", line 791, in getfqdn

hostname, aliases, ipaddrs = gethostbyaddr(name)

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc0 in position 2: invalid start byte

最简单的解决方法是:

修改计算机名为英文,然后重启计算机。

修改源码解决问题请网下看。

计算机名查看:

Python 技术篇 - 修改源码解决中文主机名导致的flask、socket服务起不来问题: ‘utf-8‘ codec can‘t decode byte 0xc0 in position...

根据报错的位置查看文件为:

Python 技术篇 - 修改源码解决中文主机名导致的flask、socket服务起不来问题: ‘utf-8‘ codec can‘t decode byte 0xc0 in position...

首先 getfqdn() 这个方法是为了获取包含域名的计算机名,测试是用的英文计算机名。

>>> import socket
>>> socket.getfqdn("127.0.0.1")
'lanzao.xxx.com.cn'

Get fully qualified domain name from name.

An empty argument is interpreted as meaning the local host.

First the hostname returned by gethostbyaddr() is checked, then

possibly existing aliases. In case no FQDN is available, hostname

from gethostname() is returned.

译文:

从名称中获得完全合格的域名。

空参数被解释为表示本地主机。

首先检查gethostbyaddr()返回的主机名,然后

可能现有的别名。如果没有可用的FQDN,请输入主机名

从gethostname()返回。

用英文计算机名进行测试内部方法:

>>> socket.gethostbyaddr("127.0.0.1")
('lanzao.xxx.com.cn', [], ['127.0.0.1'])
>>> socket.gethostbyaddr("lanzao")
('lanzao.xxx.com.cn', [], ['fexx::a9xx:7fxx:15xx:5fxx'])
>>> socket.gethostname()
'lanzao'

中文情况下 gethostbyaddr() 报错,gethostname() 不会。

gethostbyaddr() 方法是封装在 __socket__.pyd 包里的。

如果要彻底修改就涉及反编译了。

我这里直接对现有方法进行了改动,如果是中文计算机名,这里直接返回计算机名就可以了。

本来没有域名的情况下返回的也是计算机名,只是针对这种中文的待域名的情况下,只能返回中文计算机名,这种场景比较少,而且如果我们的生产环境没有获取这种中文计算机名+域名的需求,这样改动几乎没有影响。

Python 技术篇 - 修改源码解决中文主机名导致的flask、socket服务起不来问题: ‘utf-8‘ codec can‘t decode byte 0xc0 in position...

相应代码如下:

def getfqdn(name=''):
    """Get fully qualified domain name from name.

    An empty argument is interpreted as meaning the local host.

    First the hostname returned by gethostbyaddr() is checked, then
    possibly existing aliases. In case no FQDN is available, hostname
    from gethostname() is returned.
    """
    try:
        name = name.strip()
        if not name or name == '0.0.0.0':
            name = gethostname()
        try:
            hostname, aliases, ipaddrs = gethostbyaddr(name)
        except error:
            pass
        else:
            aliases.insert(0, hostname)
            for name in aliases:
                if '.' in name:
                    break
            else:
                name = hostname
        return name
    except Exception as e:
        print(e)
        return gethostname()   # 仅返回计算机名,无域名

至此,问题解决,flask、socket 服务顺利起来,毫无影响。

喜欢的点个赞❤吧!