今天重写了 linux 开启热点的这篇文章,这里另开一篇写一些比较有意思的东西~

其实我在 Linux 电脑上开热点,主要还是需要把硬盘“挂载”到手机上,方便共享文件或者串流大文件视频音频等等。我的 Nexus 6P 并未 root,所以也没法用 NFS 挂载,只能用 ftp(不过现在速度也还好够用)。

但是之前 hostapd 没开 HT capabilities 的时候,传大文件就会发现速度很慢。于是搜索了一番,找到 Hostapd 上游官方配置文档 hostapd.conf,这是关于 ht_capab 的部分:

# ht_capab: HT capabilities (list of flags)# LDPC coding capability: [LDPC] = supported
# Supported channel width set: [HT40-] = both 20 MHz and 40 MHz with secondary
#    channel below the primary channel; [HT40+] = both 20 MHz and 40 MHz
...
#    freq        HT40-        HT40+
#    2.4 GHz        5-13        1-7 (1-9 in Europe/Japan)
#    5 GHz        40,48,56,64    36,44,52,60
...
# HT-greenfield: [GF] (disabled if not set)
# Short GI for 20 MHz: [SHORT-GI-20] (disabled if not set)
# Short GI for 40 MHz: [SHORT-GI-40] (disabled if not set)
...
#ht_capab=[HT40-][SHORT-GI-20][SHORT-GI-40]

没有加ht_capab选项之前,iw dev wlp8s0_ap info可以看到channel只有一个频道(只有一个指定的频道,自然是比较慢啦)。ht_capab选项加入之后,可以看到channel信息中多了带宽和中心频道的信息,这时候测下来速度就勉强说的过去了~ 20MHz 带宽显示理论速度有 65Mbps,实测速度在 32-40Mbps 之间(学校 wifi 太多了,干扰比较严重)

麻烦的是,我的笔记本网卡是单天线的,只能在一个频道上工作,所以开的热点一定要和连接的 wifi 频道一样,并且 HT 设置还和频道有关(参考上面配置文件里的说明)。之前在 hostapd 的 systemd 模块里写了一串超级长的布尔运算来干这个自动修改配置的事情,就是下面这一串,但这样实在不“优雅”,各种引号和转义难以读懂。

...
[Service]
ExecStartPre=/bin/sh -c " sed -ie '/channel/d' /etc/hostapd/hostapd.conf && [[ \"$(iw dev wlp8s0 link)\"a != \"Not connected.\"a ]] 2>/dev/null && echo \"channel=$(iw dev wlp8s0 info | grep channel | awk '{print $2}')\" >> /etc/hostapd/hostapd.conf || ( echo \"channel=6\" >> /etc/hostapd/hostapd.conf ) "
...

所以前两天另写了个 sh 改进下

#!/bin/bash
WIFI_STAT=`iw dev wlp8s0 link`
HOSTAPD_CONF="/etc/hostapd/hostapd.conf"
CHANNEL_CONN=`iw dev wlp8s0 info | grep channel | awk '{print $2}'`

# delete previous channel settings
sed -ie '/channel/d' $HOSTAPD_CONF
sed -ie '/ht_capab/d' $HOSTAPD_CONF

if [[ $WIFI_STAT == "Not connected." ]]; then
    echo "channel=1" >> $HOSTAPD_CONF;
    echo "ht_capab=[HT40+][SHORT-GI-20][SHORT-GI-40]" >> $HOSTAPD_CONF;

elif (( $CHANNEL_CONN >= 1 && $CHANNEL_CONN <= 7 )); then
    echo "channel=$CHANNEL_CONN" >> $HOSTAPD_CONF;
    echo "ht_capab=[HT40+][SHORT-GI-20][SHORT-GI-40]" >> $HOSTAPD_CONF;

elif (( $CHANNEL_CONN >= 5 && $CHANNEL_CONN <= 13 )); then
    echo "channel=$CHANNEL_CONN" >> $HOSTAPD_CONF;
    echo "ht_capab=[HT40-][SHORT-GI-20][SHORT-GI-40]" >> $HOSTAPD_CONF;
fi;

这样 hostapd systemd 模块ExecStartPre写 sh 文件的路径就好了。

然而就算开了 HT20 速度也并不快,我又尝试开启 HT40。hostapd 上游源码对 HT40 加入了限制,如果 hostapd 扫描到附近超过 30 个热点就会禁用 HT40,所以原版 hostapd 在这里明显开不了 HT40,学校宿舍的 2.4GHz 环境实在是太恶劣了~。很自然的想到了第三方 patch 版本,去除这个限制强制开启 HT40。我一开始搜索到的 patch 是给 OpenWrt 路由器用的,还准备拉下来研究下自己编译个 patch 版本。结果搜索一圈,发现有两个发行版的官方源已经合并了这个 patch —— OpenWrt 和 Arch Linux~(Arch Linux 真的是很激进的发行版呐😆,本来给路由器用的 patch 也用了)。也就是说,我现在用的 hostapd 已经合并了这个 patch~~ 虽然 Arch 官方 wiki 并没有这个 patch 的说明,不过在官方 commit 记录可以看到加入了noscanhostapd.conf加入noscan=1强制开启 HT40。

但是...实际测试下来并没有加快速度,反而会有频繁断开。我又查找了一轮下来,大概原因是这样的:多个热点之间发生频道竞争的问题不大,它们会自动协调分配,但是错误的设置会导致互相干扰,所以 HT 特性并不能随意开启,虽然可用带宽变大,但是占用更多频道意味着增大了干扰,反而可能导致信号变差。

写到这里,速度问题已经无解了,除非上 5GHz。然而电脑网卡不支持 5GHz 我也没办法😂

另外顺便提下,测速用的是 iperf3, cli 工具,既是服务端也是客户端。测速的时候电脑上运行服务端iperf3 -p 2333 -f K -F /dev/urandom -s保持监听。我把系统随机数池当成测速用文件,(因为装了熵收集工具,随机数产生速度还是非常可观的),如果用普通文件的话,还没等速度稳定下来就传完了。手机连接热点,Termux 也有 iperf3,运行iperf3 -p 2333 -f K -c 10.0.0.100 -t 100测速100秒。