我们公司有两个网络,一个用于访问内部网络资源,简称为内部网络,另一个网络用于访问外部互联网资源,简称外部网络。
平时大家工作中以内部网络为主,为了方便使用,内部网络也开放了外部互联网的资源访问。由于公司内几乎所有人日常工作都使用这个网络,所以网络策略限制了外部互联网下载速度到500KB左右。而外部网络则没有任何下载速度限制。
最近在做机器学习的实验时,遇到了令人头疼的网络下载速度问题。
做实验的机器是一台台式机,以有线的方式接入内部网络,被分配了固定的ip地址。机器访问内部资源倒是比较快,但是访问互联网就速度受限了。
由于机器学习数据集或者模型文件都很大,常常是好几十GB,用内部网络下载常常要好几个小时,严重影响了效率。
怎么办呢?在和公司IT人员沟通之后找到了一个简单的方案:买一个无线网卡插在台式机上面,让台式机支持双网络的访问。这样一来,平时可以与之前一样接入内部网络,一旦有大文件下载需求时,就切换到外网网络。
于是,我买了绿联的这个USB无线网卡。
根据产品说明,这个网卡可以支持Windows系统和Linux系统,可以满足我的台式机的Linux系统需求。
在收到网卡之后,怀着激动的心情,立即插在了机器上。然而,系统没有任何反应,居然并不能直接识别网卡!
接下来就是我一下午的在Linux系统中的无线网卡安装使用探索之旅。
在Linux系统中的无线网卡安装使用探索
根据官方文档安装驱动
首先,我通过产品介绍找到了绿联的使用文档:https://www.lulian.cn/download/60-cn.html
文档中有明确说明,不像在Windows系统中可以免驱直接使用,在Linux下需要先安装网卡驱动才能使用。
网卡驱动可以从网页内容中下载。于是我下载了驱动,并开始安装。
驱动安装包解压之后有两个文件夹,一个Windows一个Linux。其中Linux文件夹下面还有很多关于Android的目录,看起来这个设备还可以支持Android系统。
Linux目录中,有个名为install.sh
的文件。运行之,可以发现系统开始基于源代码进行编译,编译之后,会开始安装。期间会要求输入用户密码,提升至root权限。
源代码的依赖较少,编译安装倒是比较顺利。但是安装之后,还是没自动识别到网卡!这就头大了。
驱动问题分析
经过一番搜索,我发现几篇有用的中文内容(见后文链接部分)。虽然芯片型号不一样,但是安装方式是类似的。结合对install.sh
源代码的分析,我发现:
- 芯片驱动采用Linux内核模块实现
- 编译驱动代码之后将生成
8821cu.ko
文件 - 安装时,会将
8821cu.ko
拷贝到目录/lib/modules/4.15.0-200-generic/kernel/drivers/net/wireless/
中 - 使用命令
modprobe 8821cu.ko
将驱动动态插入到系统内核 - 安装完成之后,使用
lsmod | grep 8821
可以看到8821cu xxxx
的结果,说明驱动已经在内核得到支持
上面的安装过程没有出错,结合这里的分析,看起来整个安装是没问题的。既然驱动已经正常安装并可以正常工作,那为什么系统还是无法识别此网卡呢?
发现异常,联系厂家支持
我快速分析了一下当前的情况,看看能不能识别到什么异常。
在经过一系列检查之后,我发现这个网卡使用了Realtek瑞昱的RTL8811cu芯片,但是从官网下载的驱动中,目录名居然是8821cu!这难道就是问题?绿联的文档驱动链接放错了?
接着,为了59块钱,我联系了京东客服,从京东客服辗转电话联系到了绿联的技术支持人员。我给绿联的技术人员热心的说明了我发现的问题,然后他们将新的驱动及安装视频发送到了我的邮箱。
绿联的安装视频比较简单,看不出来跟我上面的操作有什么区别。发给我的新驱动文件,却依然是8821cu打头的目录!
这就头疼了,还是没解决问题!
接下来看来只能靠自己了。
开源社区的力量
根据我的理解,这款硬件主要功能应该来自于这款REALTEK芯片。就像手机上的芯片一样,它是整个设备最核心的东西。
现在的芯片集成度都非常高,比如,作为手机最重要的部件,手机芯片实际上完成了手机底层核心的大部分功能,如移动网络联网、wifi联网、蓝牙、CPU通用计算、GPU图形计算等等(类似电池、摄像头、屏幕、扬声器等是不涉及的,这些主要由手机厂商选择其他供应商的产品进行集成)。这款芯片应该也不例外。
绿联的位置,如同手机厂商一样,主要完成产品设计、集成工作。
如此一来,此芯片的驱动应该由REALTEK厂商提供才对。
于是,我尝试到REALTEK官方网站去找这款芯片的驱动。在找驱动的同时,也进行了一些搜索,还真有不少内容!
关键的内容来自这个开源项目。阅读其文档可以了解到:
- REALTEK没有为这款流行的8811芯片公开Linux驱动
- 8811驱动可以根据8821驱动做一些修改来适配
- 有人已经做了适配了
到这里,我大概弄清楚了,绿联文档中的或者发我的驱动应该都没问题。这个驱动应该可以同时支持8821芯片和8811芯片。
那为什么还是不对呢?
还需要设置USB设备的工作模式
首先,系统有没有识别到这个设备?这可以通过插拔设备观察结果。使用lsusb
命令可以看到当前的所有设备,在经过测试之后,我发现系统确实识别到了一个新设备:
根据中文文档中的内容,如果正常,使用ifconfig -a
应该能看到新的网络设备出现。但是现在还不行。
最后,在上面Github的文档中,我找到了一些新的线索。原来需要切换一下设备的模式!
按照文档说明,组织了一下命令sudo usb_modeswitch -KW -v xxxx -p xxxx
,执行之后,成功切换了网卡模式。运行ifconfig -a
终于可以看到网卡设备了!
有了网卡,后续的系统配置应该就不是难事了。
在命令行中配置无线网络
我查找了一些文档,主要可以借助几个工具实现在命令行中管理无线连接。
- 搜索无线网络:
iwlist IF_ID scanning
- 生成无线网络密码:
wpa_passphrase NET_ID >> /etc/wpa_supplicant/wpa_supplicant.conf
(需要提供wifi密码) - 根据密码配置连接无线网络:
wpa_supplicant -i IF_ID -c /etc/wpa_supplicant/wpa_supplicant.conf -D wext -B
- 验证是否连接成功:
iwconfig
(命令将显示连接到的网络ID,但是此时可能还没有分配到IP地址,无法上网) - 自动分配IP地址:
dhclient -v -r IF_ID
- 验证是否连接成功:
ifconfig
(命令将显示无线网络已经被分配了一个IP地址)
自动切换网络
到现在为止,我们有了两个可以访问互联网的网络连接了。如何切换两个网络呢?可以通过配置路由来实现。
我这里的场景比较简单,同一时间只需要一个接口工作就行,所以可以通过修改默认路由来实现。如果场景复杂一点,希望两个网络同时工作,可以类似的用route
命令指定不同的IP地址路由到不同的网络接口来实现。
最后我写了几个脚本以便自动化的切换网络,给大家参考:
1 | # connect-wifi |
1 | # disconnect-wifi |
1 | # route-wired |
1 | # route-wifi |
大功告成
一起来看看最终的效果:
之前的网络下载速度:
无线网络的下载速度: