使用Python根据网速自动切换网关

公司里装了两条不同的宽带,根据使用的情况,比如拨VPN,或者使用人数过多,网速不行了就要切换下。每次手动去切换很不方便,而且网速也很难判断。这里分享下如何用Python检测网速,然后自动切换网关。

参考原文:How to Change Windows Gateway by Broadband Speed in Python

作者:Xiao Ling

翻译:yushulx

使用speedtest-cli测试网速

相信很多人都用过speedtest.net来测试网络速度,speedtest-cli是一个Python开源项目。通过链接speedtest.net来检测上传速度和下载速度。

安装

pip install speedtest-cli

或者

easy_install speedtest-cli

测试网速

安装之后就可以通过命令行来测试下网速:

speedtest-cli --bytes

根据log我们大概可以推测下这个程序的工作步骤:

  1. 从speedtest.net读取配置文件。
  2. 获得一个server列表。
  3. 找到最近的server作为最优选择用来测试速度。

这种最优方式适合检测网络的最大下载速度。而我现在需要的是根据网络访问速度切换网关,比如我需要经常访问国外某个网站,这个最大下载速度就没有意义了。要检测速度,我可以随意设置一些这个网站上的图片资源作为测试数据,而并不需要使用speedtest.net。

自定义函数用于检测网速

通过学习源码,我们可以自己重写一个网速测试函数。找到 {Python Installation Directory}\Lib\site-packages\speedtest_cli.py,根据speedtest()创建的函数很简单:

def testSpeed(urls):
    speedtest_cli.shutdown_event = threading.Event()
    signal.signal(signal.SIGINT, speedtest_cli.ctrl_c)
 
    print "Start to test download speed: "
    dlspeed = speedtest_cli.downloadSpeed(urls)
    dlspeed = (dlspeed / 1000 / 1000)
    print(‘Download: %0.2f M%s/s‘ % (dlspeed, ‘B‘))
 
    return dlspeed

原始代码是先找到最佳服务器,然后从上面获取URL资源。这里只需要随便设置我需要的资源:

urls = ["http://www.dynamsoft.com/assets/images/logo-index-dwt.png", 
"http://www.dynamsoft.com/assets/images/logo-index-dnt.png", 
"http://www.dynamsoft.com/assets/images/logo-index-ips.png", 
"http://www.codepool.biz/wp-content/uploads/2015/06/django_dwt.png", 
"http://www.codepool.biz/wp-content/uploads/2015/07/drag_element.png"]

看看源码中的下载速度是如何计算的?

def downloadSpeed(files, quiet=False):
    """Function to launch FileGetter threads and calculate download speeds"""
 
    start = timeit.default_timer()
 
    def producer(q, files):
        for file in files:
            thread = FileGetter(file, start)
            thread.start()
            q.put(thread, True)
            if not quiet and not shutdown_event.isSet():
                sys.stdout.write(‘.‘)
                sys.stdout.flush()
 
    finished = []
 
    def consumer(q, total_files):
        while len(finished) < total_files:
            thread = q.get(True)
            while thread.isAlive():
                thread.join(timeout=0.1)
            finished.append(sum(thread.result))
            del thread
 
    q = Queue(6)
    prod_thread = threading.Thread(target=producer, args=(q, files))
    cons_thread = threading.Thread(target=consumer, args=(q, len(files)))
    start = timeit.default_timer()
    prod_thread.start()
    cons_thread.start()
    while prod_thread.isAlive():
        prod_thread.join(timeout=0.1)
    while cons_thread.isAlive():
        cons_thread.join(timeout=0.1)
    return (sum(finished) / (timeit.default_timer() - start))
  1. 在线程中读取读取图片资源。
  2. 把线程放入阻塞的队列中。
  3. 从队列中把线程的结果一个个读取出来。
  4. speed = total file sizes / total time cost

查询网络适配器设置,并设置网关

如何用Python设置网关?在StackOverflow上可以找到解答。推荐的方法是使用WMI (Windows Management Instrumentation)。

安装

WMI
Python for Windows Extensions

Win32网络适配器设置

很多人的电脑上会看到很多的网络适配器,比如无线网卡的,虚拟网卡的,以太网卡的等等。每个适配器都有很多属性,看下微软的定义Win32_NetworkAdapterConfiguration class::

[Provider("CIMWin32")]class Win32_NetworkAdapterConfiguration : CIM_Setting
{
  boolean  ArpAlwaysSourceRoute;
  boolean  ArpUseEtherSNAP;
  string   Caption;
  string   DatabasePath;
  boolean  DeadGWDetectEnabled;
  string   DefaultIPGateway[];
  uint8    DefaultTOS;
  uint8    DefaultTTL;
  string   Description;
  boolean  DHCPEnabled;
  datetime DHCPLeaseExpires;
  datetime DHCPLeaseObtained;
  string   DHCPServer;
  string   DNSDomain;
  string   DNSDomainSuffixSearchOrder[];
  boolean  DNSEnabledForWINSResolution;
  string   DNSHostName;
  string   DNSServerSearchOrder[];
  boolean  DomainDNSRegistrationEnabled;
  uint32   ForwardBufferMemory;
  boolean  FullDNSRegistrationEnabled;
  uint16   GatewayCostMetric[];
  uint8    IGMPLevel;
  uint32   Index;
  uint32   InterfaceIndex;
  string   IPAddress[];
  uint32   IPConnectionMetric;
  boolean  IPEnabled;
  boolean  IPFilterSecurityEnabled;
  boolean  IPPortSecurityEnabled;
  string   IPSecPermitIPProtocols[];
  string   IPSecPermitTCPPorts[];
  string   IPSecPermitUDPPorts[];
  string   IPSubnet[];
  boolean  IPUseZeroBroadcast;
  string   IPXAddress;
  boolean  IPXEnabled;
  uint32   IPXFrameType[];
  uint32   IPXMediaType;
  string   IPXNetworkNumber[];
  string   IPXVirtualNetNumber;
  uint32   KeepAliveInterval;
  uint32   KeepAliveTime;
  string   MACAddress;
  uint32   MTU;
  uint32   NumForwardPackets;
  boolean  PMTUBHDetectEnabled;
  boolean  PMTUDiscoveryEnabled;
  string   ServiceName;
  string   SettingID;
  uint32   TcpipNetbiosOptions;
  uint32   TcpMaxConnectRetransmissions;
  uint32   TcpMaxDataRetransmissions;
  uint32   TcpNumConnections;
  boolean  TcpUseRFC1122UrgentPointer;
  uint16   TcpWindowSize;
  boolean  WINSEnableLMHostsLookup;
  string   WINSHostLookupFile;
  string   WINSPrimaryServer;
  string   WINSScopeID;
  string   WINSSecondaryServer;
};

找到了某个特定属性所对应的值,我们就可以很容易找到目标适配器了。我是这样查找的:

  1. 右键目标网络适配器。
  2. 选择配置。
  3. 点击详细。
  4. 看一下属性列表及对应的值。

最后选择了设备描述Realtek PCIe GBE Family Controller。

用Python查询Windows IP和网关

wmiObj = wmi.WMI()
sql = "select IPAddress,DefaultIPGateway from Win32_NetworkAdapterConfiguration where Description=\"Realtek PCIe GBE Family Controller\" and IPEnabled=TRUE"
configurations = wmiObj.query(sql)

设置Windows网关

configurations = wmiObj.Win32_NetworkAdapterConfiguration(Description="Realtek PCIe GBE Family Controller", IPEnabled=True)
configuration = configurations[0]
ret = configuration.SetGateways(DefaultIPGateway=[gateway])

请注意脚本必须用管理员权限来执行,不然设置会失败。记得查看返回值。

for gateway in gateways:
        settingReturn = setGateway(wmiObj, gateway)
 
        if (settingReturn[0] != 0):
            print "Setting failed"
            return
 
        print "Set gateway: " + gateway
        dlspeed = testSpeed(urls)
        option = (gateway, dlspeed)
        print "Network option: " + str(option)
 
        if (option[1] > bestChoice[1]):
            bestChoice = option

把Python脚本转换成可执行EXE

如何把Python程序分发给别人使用如果他们并没有安装Python程序以及依赖库?使用Py2exe 可以很容易把Python脚本转换成exe文件。

安装

Py2exe

转换Python脚本

新建setup.py:

from distutils.core import setup
import py2exe
setup(console=[‘network.py‘])

执行下面的命令:

python setup.py py2exe

目录中会生成一个dist 文件夹:

记得执行程序的时候必须要用管理员权限。

源码

https://github.com/yushulx/switch-windows-gateway

时间: 2024-08-04 12:35:18

使用Python根据网速自动切换网关的相关文章

Linux使用shell自动切换网关

编写名为auto_change_gw.sh的脚本,用来自动切换主机网关,相关说明如下: 1)有2个可用的网关地址,分别是主网关192.168.10.254和备用网关192.168.10.253,当前使用的默认网关是192.168.10.254: 2)若当前使用的网关地址192.168.10.254出现问题,自动把网关地址切换为192.168.10.253: 3)当网关地址192.168.10.254能正常工作后,当前主机再把网关地址切换到192.168.10.254. 讲下思路: 1.先用whi

python协程io自动切换--gevent

1.gevent执行 import gevent def func1(): print('func1 start') gevent.sleep(2) print('func1 end') def func2(): print('func2 start') gevent.sleep(1) print('func2 end') def func3(): print('func3 start') gevent.sleep(0) print('func3 end') if __name__=='__ma

Python也可以抢网速,我下了十部电影,室友才一部

我们就用几个小例子来展示一下编程能给我们的工作生活带来怎样意想不到的便利.希望通过适当的引导,大家能体会编程的爽,乐在其中,享受编码的乐趣. 学习Python中有不明白推荐加入交流裙                                            号:735934841                                            群里有志同道合的小伙伴,互帮互助,                                           

测试网站页面网速的Python脚本

一.测试网站页面网速脚本 [[email protected] ~]# cat check_url.py #!/usr/bin/python # coding: UTF-8 import StringIO,pycurl,sys,os,time class idctest: def __init__(self): self.contents = '' def body_callback(self,buf): self.contents = self.contents + buf def test_

适合国内网速的CDH5安装

0.集群规划 说明:由于CDH可以方便的动态添加删除主机,动态改变主机上的服务,所以后面再对各机器上跑得服务进行分配. 共三台机器 操作系统: centos6.5 机器名:work01.work02.work03 work03运行Cloudera Manager 1.关闭防火墙 和 SELinux    说明:如果不关闭,集群间通信可能会出问题,造成服务不能正常启动.生产环境如果要做为在线服务还是需要. 1.1 关闭防火墙: service iptables stop (临时关闭) chkcon

4G最快网速相当于30M宽带

在4G年内发牌已成定局的背景下,各运营商都在加快布局,北京移动近期就推出了4G友好用户体验活动.4G的信号覆盖情况怎样?4G业务的下载速度到底有多快?带着消费者最为关心的问题,近日记者在多个地点对北京移动的4G终端进行了一番体验. 京华时报记者古晓宇 □体验任务之终端 三种终端可供使用 目前,北京移动对外提供的4G体验终端有三种,分别是4G上网卡(与3G上网卡相似,通过USB插在电脑上使用).MiFi(将4G网络信号转换成手机.iPad.笔记本电脑都通用的WiFi信号)和CPE(4G无线网关,与

提高网速的21个技巧

提高网速的21个技巧 1.去掉无关的选项 在Windows XP中,双击"控制面板"中的"文件夹选项",再单击"查看"标签,然后将鼠标指针滚动至窗口的最下方,可以看到有一个"自动搜索网络文件夹和打印机"项,默认是选中的,将它去掉.这样,当我们打印时,Wi ndows XP不会自作主张去寻找http://局域网上的打印机并安装驱动程序,以防止不经意将机密文档打到别的部门打印机上而自己却还找不到.同时,将此项去掉后,当我们通过&q

[无线路由] “免费”斐讯K2路由器刷OpenWRT(实战MWAN多宽带网速叠加)

(阿财首发于什么值得买)斐讯K2可以算是一个非常另类的跨界数码产品,其产品完全的醉翁之意不在酒.最多值99元的 MT7260硬件架构和用料,售价399元,金额激活K码后自动转入合作理财P2P平台,等待一个月可以全额返还路由器金额的"免费"模式,让阿财的小 伙伴们在群里讨论差不多大半个月. 心痒痒又怕上了贼船,因为阿财的家中实际上有2条宽带 --线路一.联通20M双绞线PPPoE宽带入户:线路二.广西广电网络8M广电宽带,由数字电视机顶盒接出.两条宽带原来没有支持DualWAN的路由 器

使用Linux命令行测试网速

使用Linux命令行测试网速http://www.linuxde.net/2014/01/15561.html 当发现上网速度变慢时,人们通常会先首先测试自己的电脑到网络服务提供商(通常被称为"最后一公里")的网络连接速度.在可用于测试宽带速度的网站中,Speedtest.net也许是使用最广泛的. Speedtest.net的工作原理并不复杂:它在你的浏览器中加载JavaScript代码并自动检测离你最近的Speedtest.net服务器,然后向服务器发送HTTP GET and P