最近帮另外一个课题组的项目实现了如题的一个小功能。
情况是这样,某垃圾场有一套相关数据的采集装置,两台工控机接着传感器,数据表汇总在现场的一台SQL Server服务器上,机器只有局域网没接入公网,采集程序由别的软件公司完成,但是我能拿到数据库的全部控制权。这边项目是一个WebGIS,数据库是PostgreSQL,他们想把现场数据库中一张表的部分数据实时更新到自己的这个数据库中。
因为之前手里有台气象站是利用RS232串口和DTU设备完成的远程数据实时传输,他们项目的老师想让我们也按照类似的方法实现他们想要的功能。考虑到原来的程序本来就不走串口通信传输数据以及其他的一些原因,重新设计了下面的方案。
1、 买了一个EDGE的Modem用于现场那台服务器的互联网接入,设备找的厦门本地一家企业叫四信通信的,产品、包装、销售和服务都很靠谱,拨号试了一下,速度凑合了。
2、为了能在SQL Server端把PostgreSQL的服务器添加成链接服务器,在装SQL Server的服务器上装了PostgreSQL的官方ODBC驱动叫psqlodbc,对应我这边PostgreSQL的版本是8.3。其他还有一些类似的驱动,比如呼声很高、对链接服务器支持更好的OLEDB驱动PGNP (PostgreSQL Native OLEDB Provider),但是用的商业付费许可,虽然我没找到许可上哪儿有说付费对时间和功能上有什么限制,想想还是没有用,并且后面发现psqlodbc完成我要的一些基本功能也没啥问题。
3、添加链接服务器。不同的驱动有不用的接口,具体添加的参数以及对链接服务器数据库表的访问语句也有差异。使用psqlodbc的时候参考的是这篇,http://eddiecjc.blogspot.com/2009/05/set-up-postgresql-as-linked-server-in.html。自己写了一个更加完善的sql脚本。
DECLARE @LINKED_SERVER_NAME VARCHAR(MAX)
DECLARE @DATA_SOURCE VARCHAR(MAX)
DECLARE @PORT VARCHAR(MAX)
DECLARE @DATABASE VARCHAR(MAX)
DECLARE @USER VARCHAR(MAX)
DECLARE @PASSWD VARCHAR(MAX)
DECLARE @CNN_STR VARCHAR(MAX)
– Info
SET @LINKED_SERVER_NAME = N‘postgresql_dump’
SET @DATA_SOURCE = N‘***.***.***.***’
SET @PORT = N‘5432′
SET @DATABASE = N‘dump’
SET @USER = N‘******’
SET @PASSWD = N‘******’
SET @CNN_STR = N‘Driver=PostgreSQL ANSI;uid=postgres;Server=’ + @DATA_SOURCE + ‘;Port=’ + @PORT + ‘;database=’ + [...]
对我来说,ssh tunnel就是用来那啥的。ssh连接有个最大问题就是没有断线重连机制,在win下面有以myentunnel为代表的软件来看着它所调用plink.exe来建立的ssh连接是否正常,断线就重新调用一下。
Linux也有类似的东西,Gnome下面有个Gnome SHH Tunnel Manager,简称gstm的能实现,缺点是密码不能保存,每次都要自己输入,且依赖图形界面。KDE下面也有一个,名字很有喜感,叫kstm,就是KDE SSH Tunnel Manager,另外还有一个,忘名字了,暂时找不到,但是遗憾的是没有Xfce SSH Tunnel Manager这个神物。
上网一搜,有类似的方案,主要都是来源于这篇文章,对我来说这个方案并不能完全满足我的需求,第一我不想在桌面上专门开个终端(因为expect是需要与屏幕显示交互的,因此不能后台运行),第二他只是发送字符防止超时断开连接,强壮性不够,下面是改进过的脚本。
Bash语言: 感谢代码发芽网
01 #!/usr/bin/expect
02
03 set timeout 60
04
05 while (1) {
06 spawn /usr/bin/ssh -D 7070 -g ****@*****.****
07 expect {
08 “*(yes/no)?” {
09 send “yes\r\n”
10 expect “*password:” send “****\r\n”
11 }
12 “*password:” {
13 send “****\r\n”
14 }
15 }
16 interact { timeout send “\r\n” }
17 wait
18 [...]
昨天下午下了课,老板给打电话来说帮师兄研究一下如何实现这样如题的功能,具体情境是拿C#用ArcEngine做二次开发的时候,他要开四个MapControl控件,分别显示大气、土壤等等的信息,在每个地图容器里面拖拽放大的时候,其他容器里面的地图联动,鼠标也要在四个窗口里面同步显示。
好的,分成三步来做。以两个MapControl联动为例,做窗口上放了两个ArcGIS Engine MapControl控件,分别命名Map1和Map2。
先实现地图联动,每当地图位置、比例尺发生变化的时候,会触发MapControl的OnExtentUpdated事件,在Map1的响应函数里面写:
Map2.Extent = (IEnvelope)e.newEnvelope;
Map2同理,这样就好了。之前有试过Map2.Extent = Map1.Extent.Envelope的用法,但是联动的时候慢半拍。
接着实现同步操作状态,即鼠标进入MapControl控件的时候,保持一致的漫游、放大、缩小等功能。再放两个ArcGIS Engine ToolBarControl控件,分别命名Bar1和Bar2,添加好漫游、放大、缩小、全图四个按钮,并绑定对应的MapControl控件。
实现的原理是当按下一个ToolBar上按钮的时候,让别的ToolBar的该按钮也处于按下状态。在ToolBar的OnItemClick事件里面写,这里有一点要注意的是ToolBar里面的全图按钮算Command不算Tool(AO里面的强行不合理分类,Command是按下就弹起的按钮,Tool是按下后保持状态的。),在代码里面利用e.index把他排除在同步操作的状态以外。关键代码如下
Bar2.CurrentTool = Bar2.GetItem(e.index).Command as ITool;
Bar1同理,这样效果就出来了。前面几次操作在显示上略有点小问题,我归结到AE的Bug里面,多点几次基本就是无缝同步了,最后出成品的时候,隐藏到其他的ToolBar就好了。
鼠标这个功能比较麻烦,我试过用PicureBox装在个鼠标图片然后用位置控制的方法,但是PictrueBox本身不透明,效果不好,况且暂时也不需要也没必要实现同时弹出右键菜单,跟师兄沟通了一下决定改用在其他地图容器里面画一个大的十字丝来作为鼠标的定位显示,这个功能用NewLineFeedbackClass来实现。
首先做定义两个接口。
private IDisplayFeedback pDisplayFeedback1 = null;
private IScreenDisplay pScreenDisplay1 = null;
在窗体的构造函数里面添加初始化的代码。
pDisplayFeedback1 = new NewLineFeedbackClass();
pScreenDisplay1 = Map1.ActiveView.ScreenDisplay;
pDisplayFeedback1.Display = pScreenDisplay1;
在Map2的OnMouseMove事件里面写响应代码。
((INewLineFeedback)pDisplayFeedback1).Stop(); //结束之前的绘制,DisplayFeedback在执行Start()方法之后开始画,Stop()之后就清掉了。
//下面是画十字丝的,因为没有NewMultiLineFeedbackClass,这个十字丝只能一笔画成,所以就只能在显示区域外面多画了一点。
((INewLineFeedback)pDisplayFeedback1).Start(Map1.ActiveView.ScreenDisplay.
DisplayTransformation.ToMapPoint(0, e.y));
((INewLineFeedback)pDisplayFeedback1).AddPoint(Map1.ActiveView.ScreenDisplay.
DisplayTransformation.ToMapPoint(Map1.Width + 1, e.y));
((INewLineFeedback)pDisplayFeedback1).AddPoint(Map1.ActiveView.ScreenDisplay.
DisplayTransformation.ToMapPoint(Map1.Width + 1, -1));
((INewLineFeedback)pDisplayFeedback1).AddPoint(Map1.ActiveView.ScreenDisplay.
DisplayTransformation.ToMapPoint(e.x, -1));
((INewLineFeedback)pDisplayFeedback1).AddPoint(Map1.ActiveView.ScreenDisplay.
DisplayTransformation.ToMapPoint(e.x, Map1.Height));
这样就在当鼠标在Map2上时,Map1上会同步打一个十字丝。画出来的是默认宽度为1的黑色线,正好符合我的要求。也可以自定义线形,关键代码如下,加在初始化代码里面。
IRgbColor fcolor = new RgbColorClass();
fcolor.RGB = 0;
ISimpleLineSymbol pSymbol = (ISimpleLineSymbol)pDisplayFeedback1.Symbol;
pSymbol.Color = fcolor;
pSymbol.Width = 1;
pSymbol.Style = esriSimpleLineStyle.esriSLSSolid;
//放在这句之前 pDisplayFeedback1.Display = [...]
先说维基小说站,看这里,叫做讲故事,源于本科学校的一位学长,原型在这里有个小记录。
这个站采用的是DokuWiki,这套系统是php的程序,不需要数据库的支持,基于纯文本来存储数据,插件和皮肤资源都比较齐全,非常适合做个人知识整理系统,这里拿来做维基小说的程序也还是挺不错的。关于其他的维基程序,这里的WikiMatrix列出了多,总能挑到一款的。
维基站比较简单,媒体库的程序就大费了一番周折了。最早的想法就是做一个相册,考察了一系列程序如下。
pixelpost,主题和插件资源最丰富,但是后台界面用户管理弱一点,不支持从url上传图片。
4images,后台功能相当强大,就是主题资源平平,多数很难看。
coppermine,航母级的,功能相当全面,适合做个社区图片分享站点,只是个人用太浪费了。
mg2,非常简洁,不需要数据库支持,不支持多用户,主题资源缺乏。
plogger,很简洁,插件和主题资源来源于社区,比较零散,不过原装的几个主题挺不错了,功能也只能算强强够用,没有多用户支持。
zenphoto,这家似乎跟wordpress有些渊源,主题和插件资源不算特别少也不算特别多,后台的用户体验不错,支持用户权限管理,不过对中文支持不太好。
gallery,DreamHost提供了这家的一键安装,使用体验跟上面4images差不多,还支持网页链接批量上传,就是主题太少太难看了。
yapig等等,特点忘了。。。
考察到最后用的是zenphoto,然后发现它支持上传mp3、flv等等,以及播放列表、密码保护、防盗链等等,所以打算拿它来做个媒体库好了,传送门在这里。
明天就要回学校了,这两天闲来无聊,趁着刚买了个带电源的usb hub,就又折腾了一点DD-WRT。
DD-WRT是一个基于Linux的路由器固件,历史大概是这样的,说很久很久以前,一家叫思科公司在自己的一款叫做WRT54G的无线路由上使用了基于Linux的固件,然后就因为GPL授权的问题被迫公开了这套固件的源代码,此后就有一干大牛根据这些源代码搞出来DD-WRT这个第三方固件,后来又有了直接从内核开始单干的OpenWRT(没去了解Tomato是啥情况)。现在的DD-WRT(v23以后的版本)其实已经是基于OpenWRT全部重写的了。//以上很混乱,详细历史八卦参见各种wiki和blog。
DD-WRT的特点是能让你在廉价的无线路由设备上面实现很多高端路由才有的功能,比如多种无线模式、信号功率调整、QoS、VPN甚至把路由当做Samba、FTP、HTTP服务器,BT电驴脱机下载机等等。
也不是所有的路由都能刷DD-WRT的固件,这里有个设备列表。经典的设备有上面提到的WRT54G,不过这个东西已经相当古老了,现在买到的大多是些洋垃圾电路板拿回来翻新的,新型号全新的也有,略贵。我是大半年前从恩山wifi论坛的淘宝店入手这样的一台洋垃圾,贝尔金7231-4p。为了能够更好的跑DD-WRT,恩山老大改造了一下,ROM升级到4M(原配是2M,只能刷个最精简版的固件,什么都玩不了。),内存升级到64M,加装两根天线,又多焊了个USB的接口(只是usb1.1,我的目的就是玩一玩,当文件服务器的话这个速度有点寒碜)。
之所以选这款,一来是经过改造,4M的ROM和usb接口使得这款路由的可扩展性大大增强,二来这款路由够强壮,如果刷固件砖掉的话,恢复起来比一般机器要方便很多(对于我这种有这方面心理阴影的人来说,这个功能太棒了)。
拿到手第一步先是重新刷固件,关于版本的选择这里有,然后根据提示去官方站点下载版本。因为一直在开发,会不断有各种新版本的rls编译出来供下载,也有很多种分支,我没去尝鲜,就选了Eko编译出来的固件”dd-wrt.v24-9517_VINT_mini_usb.bin”。其中VINT是支持47xx系列的博通芯片的,对应还有针对5352芯片的NEWD和NEWD-2,刷得不对就变砖,详情这里有。
mini版的固件关于无线路由方面的功能设置在web管理页面上都是有的,当时琢磨了小半个下午基本摸熟了,只有ipv6的功能一直没机会试(本来以为去科技学院宿舍能有v6给我折腾的,结果人品不好被住到国防大学,只能作罢。)。
有意思的就是那个usb接口了,首先这个usb口供电不是很足,u盘和移动硬盘不能保证稳定运行,我用了个带外接电源的usb hub搞定。挂载u盘比较简单,这里有方法。//顺便提一下,关于DD-WRT没有找到什么特别合适的教程,看wiki多琢磨才是王道。
然后就是第三方软件了,dd-wrt使用的一个东西叫做optware,因为一般他们是安装在/opt下面的,这点真幽默。optware相当于一个linux的运行环境,挂载完毕之后/opt下面有自己的/bin、/lib等等,安装软件使用/opt/bin/ipkg install ***的方式,当然只有optware软件源里面软件,其他软件就要自己编译了。optware也有好几种,dd-wrt自己维护了一个版本,openwrt也有一个,华硕也有一个,叫oleg optware,他们都是可以使用的,就是性能和各自源内的软件略有不同而已,可以同时装若干个,不用都放在/opt下面的。或者用基于BCM47xx平台的Debian,看这里,挂载进去之后chroot,就是个Debian了,想怎么整就怎么整了,Debian环境下支持的软件相较于optware更为完整和全面(前者300M后者也就10M左右)。
其他具体怎么整,恩山wifi论坛里面基本都能挖掘到了。//恩,不要认为我这是广告。
完了,就剩最后一句了,24小时之后我就从保暖内衣+羊毛衫+大棉袄的组合变成内衣+睡衣的组合了。
Ubuntu的那个NetworkManager其实挺好的,只是前段时间常驻办公室,在那边只能用有线上网,还要修改MAC,手工指定IP,本来在/etc/network/interfaces里面加上规则是很轻松的事情,可是NetworkManager让这件事情比在windows下还要麻烦,于是一怒之下我就把他干掉了,而且还加了可爱的参数purge。
但是无线我就不会配了,回宿舍上网的两个解决方案是进windows和用有线。回家之后路由器扔在客厅,没法用有线了,咬咬牙,折腾了小半个下午,解决了无线的配置问题。
我的Wi-Fi信号是这样,802.11g,SSID广播,WPA2 Personal加密模式,WPA加密算法用TKIP,30位数字特殊符号大小写的密钥,客户端由DHCP分配IP。笔记本无线网卡是Inter 5100 AGN,操作系统是Ubuntu 9.10。
原理大概是这样,/etc/network/interfaces里面无线网卡配置的写法跟有线差不多,只是多需要了一个叫wpa_supplicant的程序,它的作用是对数据流进行加密,因此要在网卡up的时候启动它,在网卡down的时候关掉他。
具体的做法如下,首先iwconifg看一下无线网卡叫啥,我这块卡是能被系统认出来并驱动的,名字叫wlan0。
然后给wpa_supplicant写个配置文件,放在/etc/wpa_supplicant下面好了,管他叫wpa_supplicant.conf好了,如下。
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=root
network={
ssid=”……” #ssid的名字,如果ssid不是广播的话,在下面加一条scan_ssid=1。
key_mgmt=WPA-PSK
psk=”……” #引号里面明文写密钥
proto=RSN #据说WPA1是写WPA的,WPA2是写这个的。
pairwise=TKIP
}
明文写密钥比较变态,用wpa_passphrase ssid ‘psk’来生成一个加密的psk,效果如下。
# wpa_passphrase tplink ‘qwer!@#123′
network={
ssid=”tplink”
#psk=”qwer!@#123″
psk=8f7ccd4d208572d85eefadf6d80b66f27515a9de8f79743148cefb2c6785e0f5
}
根据输出重新替换回去就好。
接着在/etc/network/interfaces里面写
auto wlan0
iface wlan0 inet dhcp
wireless-ssid “……”
pre-up wpa_supplicant -B -Dwext -iwlan0 -c/etc/wpa_supplicant/wpa_supplicant.conf
post-down killall -q wpa_supplicant
pre-up就是在网卡up之执行一下wpa_supplicant -B -Dwext -iwlan0 -c/etc/wpa_supplicant/wpa_supplicant.conf,在后台启动一个wpa_supplicant的进程,这样post-down的意思也就明了了。
然后就是/etc/init.d/networking restart了,如果启动不成功的话,在确认没有低级错误的情况下,基本就是网卡的驱动问题了,man wpa_supplicant了解更多,然后就是wpa_supplicant.conf里面的参数了,找找还有别的调整调整,调到满意为止。
主力参考了这篇 http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch13_:_Linux_Wireless_Networking,其他也google了一些,没有太多参考价值,参悟了wpa_supplicant的作用就明白了。
这两天买了台入门级的VPS,厂家是RAMHOST,详细的清单这里有,他们家的VPS都是OpenVZ上的虚拟机,带个极其简单的web控制面板,可以预装若干种Linux系统,开通了/dev/net/tun和iptables SNAT/DNAT,能搭建支持转发的OpenVPN服务。各种型号唯一不同的是内存硬盘和流量,我挑了个倒数第二的micro plan,128M内存,10G空间,150G流量,每月4.99刀,季付。
购买挺简单,先注册帐号,选择机器,然后Payal付钱,等待审核一段时间,开通后他们家给我发了封邮件,整个过程相当简洁。邮件里面有web控制面板的链接,用之前的帐号密码登录,能够看到VPS的IP和VPS所在HOST的IP。预装的系统是Debian 5,我就没动他,保持原样。
然后就是SSH到HOST,用户名和密码都是vz,进去之后根据提示用账号密码登录就能获得root的环境了。这样总归是挺麻烦的,还是先把ssh装上吧,aptitude轻松加愉快。顺手adduser再加上普通权限用户若干,给一个加上sudo的权限(原始安装的deb包相当少,sudo都是要额外装的。),其他的作为SSH Tunnel的帐号,就不给了。
这里默认是开启SSH的TCP Forward的,因此干到这里,用来起SSH Tunnel的帐号已经都配置好了,其实这样有不少安全隐患的,但是没心思仔细改参数,现这样得了。宿舍网络太破,速度不快,比Dreamhost的帐号速度略慢。
买低端VPS主要目的还是爬爬墙,目前来说用的SSH Tunnel + FireFox + FoxyProxy + MyEtunnel (windows) or Gnome SSH Tunnel Manager (Linux)的组合还是很方便的,不过还是折腾折腾VPN,多条路子好办事。
他们家机器已经明说了只能OpenVPN,因此不能尝试PPTP模式的VPN了,虽然大家都说OpenVPN更好一点,但我还是觉得PPTP这种记个用户名和密码就能满街跑的要比随身带着配置文件和证书密钥的要方便。
以前没配过OpenVPN,花了我老多精力,总结靠谱精简流程如下。
装软件 aptitude install openvpn lzop,装完后,证书制作工具在 /usr/share/doc/openvpn/examples/easy-rsa/2.0 下面,cd进去,执行如下。
. ./vars #设置一些变量 这里是.空格./vars,不然设置不了变量
./clean-all #清理一下之前生成的、扔在同级keys目录下的证书
./build-ca #建立ca证书
./build-key-server server #生成服务器端的证书和密钥,名字自选
./build-key client1 #生成客户端的证书和密钥,名字自选,可以做若干个
./build-dh #生成Diffie Hellman参数,非对称加密传递密钥用
完了之后所有有用的东西都在keys文件夹下面了,也包括很多没用的,了解一点原理的就知道哪些有用哪些没用了。下一步是建立配置文件。
我想要的效果是这样的,分发若干个客户端的证书和配置文件,每个客户端连过来之后分配固定的IP地址,所有客户的流量全部走VPN所在的服务器。
服务器端的配置文件server.conf这么写
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
server 10.8.0.0 255.255.255.0 #服务器的IP
ifconfig-pool-persist ipp.txt
client-config-dir ccd #同级ccd目录下创建跟客户端用户同名文件,给客户端指定ip,内容写 ifconfig-push 10.8.0.5(号称这里要是4*n+1,不知道为啥) 10.8.0.6
route 10.8.1.0 [...]
最近看文献码字有点强迫症了,提笔便简述一下背景,这里不免俗,某在某地有一台虚拟机,系统是win 2k3,有管理员账号,教科网国内外公网全通,不计流量,v4为私有地址,同时有一个固定的v6地址,新买的域名支持AAAA记录的绑定。
首先是绑域名。之前已经向某老师申请绑定了一个edu.cn的域名,这次绑自己的,直接添加了一个二级域名的AAAA记录,等了一段时间之后 ping -6 发现已经能解析了。
然后是配置web服务。我的目的是一个端口拿出来做代理服务器,自用+小范围传播,另一个开放80端口,跑一些网站。IIS据说是支持v6的,apache是肯定支持v6的,只是官方编译打包的apache都不支持,需要自己拿源码下来加参数自己编译。所幸发现了XAMPP中的Apache组件现在直接是支持ipv6的,因为还直接带了php、mysql,都是我需要的,于是省心直接下了整个包下来装上。
装完要改一改配置文件,httpd.conf和php.ini,很多默认参数不好。
接着发现一个问题,监听80端口和另外一个端口搭建不同的虚拟服务器没有问题,但是不能做到***端口允许代理,***不允许代理,这可不好,80端口太容易被扫到了。折腾了很久没有解决问题,后来经过提示,httpd.conf里面管80端口服务的配置,然后又写了一个proxy_httpd.conf文件,设置监听***端口,然后进到命令行,写命令形如 httpd.exe -f proxy_httpd.con,实现了启动两个apache实例,最终我要的效果完成了。
服务器这块儿整个的搭建算完成了,下一步的打算是把这个博客备份到过去,开一个v6的镜像。
入手如标题的设备若干,目标是实现通过脚本编程自动拍照。折腾了快两周了,略有进展,过程如下。
1. 在WindowsXP以上的系统该物件能够免驱安装,使用正常,老盖自家的东西么。在Linux下,该物件是UVC驱动兼容产品,2.6.22以上的内核已经集成了该驱动,因此在Debian Lenny下面能够自动识别出来。因此,驱动关过了。
2. 以下都是在Linux下奋战的,想法是寻找能够打开设备拍照的命令行工具,然后根据我的需要写shell设计一下逻辑。
3. luvcview能打开设备,并显示视频。缺点是只能手工点窗口上的按钮实现截图,命令行无可用参数控制。//抛弃
4. uvccapture与该设备不兼容,表现在ioctrl命令出错。
5. fswebcam依旧不可用,表现在提示从设备传入的数据不是标准MJPG/JPEG格式。
6. xawtv不可用,camE不可用。
7. 几乎所有的尝试全部失败,于是想着看有没有简单可用的库。找到了python video4linux2以及libfg,但是均不可用。
8. 于是我发现似乎是由于NX6000对UVC标准中某个接口没有做实现导致所有基于v4l2的应用程序不可用,但是luvcview又是个例外,种种折腾之后暂且挂起。大致看来fswebcam应该是最能符合我需求的,可惜不兼容,但是现在也不能换设备了。
9. 发现VideoCaputre,不过人家是基于Win32平台的Python扩展,同时还需要PIL库的支持,跑到32位XP下面试了一下,简单方便,非常的Pythonic,就是功能太少,对比度等等参数不可调,不过勉强能用了。
10. 整个折腾于是告一段落。