技术解析

ubuntu18.04 中 speedtest 测速上传速度有误解决方法
0
2021-06-22 10:13:50
idczone

受影响范围

受影响范围从 python v3.6.0b1 开始,导致测速出问题的提交的 commit id 是 3c0d0baf2badfad7deb346d1043f7d83bb92691f。准确来说,是因为 urllib 更新后 speedtest 没有对相应功能做更新。

从系统受影响版本上来看,由于 ubuntu18.04 的包总是比较新,python3 的版本超过了 v3.6.0b1 ,而用 apt 安装的 speedtest,/usr/bin/speedtest 会要求使用 python3,所以会导致上传出问题。。

如果是 ubuntu16.04 ,python3 的版本是 3.5.2,所以没事。centos 一堆老包,应该也不会受影响。其他 linux 发行版没测试,可以自己的用 python3 --version 看看。

解决方法

可以直接用 python2 执行:

liuxu:~$ dpkg -L speedtest-cli
/usr/lib/python2.7/dist-packages/speedtest_cli.py
liuxu:~$ python2 /usr/lib/python2.7/dist-packages/speedtest_cli.py

可以直接使用我的 github,我已经修复这个问题了,也 pull request 到上游了,看他们用不用吧:

liuxu:speedtest$ wget -O speedtest-cli https://raw.githubusercontent.com/liuquanhao/speedtest-cli/master/speedtest.py
liuxu:speedtest$ chmod +x speedtest-cli

也可以自己修改,代码在Speedtest::upload()中。

原代码:

    ...
    requests.append(
        (
            build_request(self.best['url'], data, secure=self._secure),
            size
        )
    )

def producer(q, requests, request_count):
    for i, request in enumerate(requests[:request_count]):

修复后的代码,就添加了下 headers:

    ...
    headers = {'Content-length': size}
    requests.append(
        (
            build_request(self.best['url'], data, secure=self._secure, headers=headers),
            size
        )
    )

def producer(q, requests, request_count):
    for i, request in enumerate(requests[:request_count]):

错误原因

github 相关提交在这里:3c0d0baf2badfad7deb346d1043f7d83bb92691f

主要是因为 urllib.request.AbstractHTTPHandler::do_request_()添加了'Transfer-encoding: chunked'相关代码,如果没有设置Content-length,就会设置Transfer-encoding。一旦连接使用了 chunked,speedtest 上传线程的前 2 个一直阻塞到 timeout,导致只能统计到前 2 次的上传。解决这个问题,只需要按前面的在上传时给 request 设置好 Content-length 头即可。

相关详细啰嗦的一堆,可以看我的博客。顺便可以来个友链,要求类型为电影欣赏 /旅游摄影 /开发 /网络相关技术,超过 30 篇,月更新不低于 1 篇。


下载了你的版本,确实上传恢复正常了。感谢

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服