2006年9月20日
决定把blog搬到baidu去,baidu的速度和空间容量都不错,就是不知道怎么把原来写的东西移过去。
新地址:http://hi.baidu.com/antzhi
服务器换了程序后手机上的Client出问题了,每次连接后只能播放第一个frame,今天抽了点时间检查程序,发现问题出在服务器在每一frame后加了个\r\n,手机上的程序在getHeader时没考虑到,加了几行代码搞定。
花生壳的IP地址和实际公网的地址不一致问题一直没得到解决,询问客服也没有解决的办法,通过观察,我发现不是每次拨号都会出现IP不一致的情况,说明我的ISP只在一定范围内安装了NAT转发的设备,自己写了个脚本,比较花生壳和wan ip,如果不一致,就从新拨号分配一个新IP,运行了半个月,效果蛮好,可惜了我花100元升级专业用户.
--------------------------------
#!/bin
# wan.sh
#get wan ip from TP-LINK route
wanip=`wget --user=admin --password=admin -q -O - http://192.168.2.1/userRpm/StatusRpm.htm |\
grep "00-50-FC-77-C9-06" |\
awk -F, '{print $3}' | tr -d ' "'`
echo "$wanip"
----------------------------------------------
#!/bin/sh
# fixip.sh
#fix vicp ip
export PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/phlinux"
disUrl='http://192.168.2.1/userRpm/StatusRpm.htm?Disconnect=断%20开&wan=1'
conUrl='http://192.168.2.1/userRpm/StatusRpm.htm?Connect=连%20接&wan=1'
wg='wget -q --user=admin --password=admin -O - '
c=0
while [ "$c" -lt "5" ]
do
wip=`wan.sh`
vicp=`nslookup myhome.vicp.net | tail -n2 | grep "Address" | awk '{print $2}'`
if [ "$wip" == "$vicp" ]; then
echo "Match done."
exit 0
fi
echo "my wan ip : "$wip
echo "myhome.vicp.net : "$vicp
echo "Fix ip ..."
if [ -n wip ]; then
echo " disconnect PPPoe ..."
`$wg $disUrl > /dev/null`
sleep 3
fi
echo " connect PPPoE ..."
`$wg $conUrl > /dev/null`
sleep 37
c=`expr $c + 1`
done
半夜醒来睡不着,干脆穿上衣服倒腾我的PSP,研究了PSPTube的通讯协议,发现其实是依靠youtube网的xml文件来实现节目列表,数据结构很简单.正好原来想用PSP PMPlayer Advance来当Motion的Client计划一直没成功,于是对PSPTube做了点调整,在服务器写了个生成xml的脚本,整个过程花了四个小时,完工时刚好天亮.
打算把服务器的timezone由UTC改成CST,但修改了/etc/timezone、/etc/default/rcS和/etc/localtime都没有用,在/etc/profile里加上export TZ='Asia/Shanghai'后普通用户登陆没问题,但用su切到root后timezone又变回UTC,实在没办法了在/etc下执行grep -e "UTC" -f *,结果在environment里发现TZ="UTC",原来是前几天做实验改后忘改回来了,又是一个因忘事犯的错误,浪费了不少时间,晕啊。
直接从deb里安装只得到btsco,snd_bt_sco要从source里编译,真是麻烦,服务器的硬盘太小,不想装linux-source了,只好等明天从本子编译好再拷贝过来.
今天家里 服务器连不上了,对VectorLinux早已看不顺眼,但一直懒得换掉,刚好乘这机会换成比较顺手的Debian,把分区设置成ext3格式,apt-get的确好用,用Mini Install CD安装了基本系统后从网上装shttpd、gspca、subversion、java,公司的2M带宽节约了不少时间。内核就将就用安装盘上的,重编译内核太麻烦,以后有时间再说了。
前几天有个大学生找到我要写个程序,又不想让我知道程序用在什么地方,画了半天xyz 我大概知道他的意思,我问他是不是用来买彩票的,他不好意义的确认了.真想和他讲讲概率论,但看他研究得这么起劲也不好打击他,何况写这程序我可以收一笔小钱来买点书
.算法是这样的:某个游戏有总数个N球,每次将会出M个球,如果你买B个球的话就能挣钱.现在要写个程序,随机在N个球里找出A个球(N>M>A>B),A个球里找出所有B个球的组合,并用这些B个球去匹配出M个球的历史记录,找到最远没出这B个球的买法A.看起来复杂,其实可以通过一个镶套的递归算法来解决,我用了单独一个线程来和处理界面的程序分开,把递归算法用个Recusion的C++类封装起来(幸亏没用C的写法,不然写到后面就惨了),加上点ADO的数据库代码,完工!
但我不认为那小伙子能用这程序挣到钱,因为概率论的精髓就是:本次发生的事件和上次无关.
VCam SDK正是我要找的东西,除了那个水印外没有其他限制,估计加密机制在驱动层里,我要学的东西已经够多了,没打算为了解这东东专门去学windows的驱动编程,但还是想碰下运气,跟踪了设置授权码的函数,找到DeviceIOControl的时候脑子里有个念头闪了一下,找来IDA反编译VCam的驱动,查找Function Code,接下来继续看...写这程序的老兄估计和我一样懒,为了调试方便加了句...呃...加了句"芝麻开门"!呵呵,美好的一天.
收到从当当发来的汪德贝多芬交响乐全集,自从听了汪德指挥的舒伯特第八就开始对他感兴趣,这套碟也没让我失望,录音的质量很好。三十块的价钱算是超值了。
接了两个USB摄像头后,用了延长线的工作不正常,估计是USB的供电问题,回头换根好点的试试看。
看了一大堆书后开始写vmotiond,基于多线程并发TCP守护进程还真不好写,要处理的东西很多,signal、mutex、IO timeout ...,头有点晕,写了一下午程序好歹可以运行起来了,代码很乱,有时间再整理,看到开几个窗口同时跑live video让我兴奋了好一阵子。目前用spca5xx的库用USB Cam做,bt8x8估计问题不大,起码FreeBSD下有bktr的东西,视频录制打算用berkeleyDB做载体,如果直接保存jpeg的话一天下来一个点有24*60*60个文件,太可怕了,对于我这简约主义者来说是不能忍受的。前两天被一大堆问题困扰得差点放弃在FreeBSD做改换Linux,幸亏坚持下来了。
本打算写个HttpConnection的子类HtdigestConnection把MD5的摘要认证封装起来,但发现因为HttpConnection是用Connector通过工厂模式生成的,让Connector.open()生成HtdigestConnection是不可能的,更糟糕的是认证操作必须在一次连接里完成,HttpConnection里没“Keep Alive”的机制。看来要用SocketConnection来自己实现HTTP层的东西,#$%^&*(
研究htdigest有一段时间了,在网上能找到的资料对具体的算法描述都很模糊,硬着头皮看RFC 2671对算法大概有了认识,然后参考shttpd的源代码终于搞清楚了,其实也很简单:
response=MD5(ha1:nonce:nc:cnone:qop:a2)
其中:
ha1=MD5(username:realm:password)
a2=MD5(method:uri)
学习源码是硬道理,网上写这些东西的人不是相互对抄就是对RFC 2671简单的翻译,要不然就是我太笨了,郁闷...
sniffer备注:
GET / HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Host: obol.kmip.net
Connection: Keep-Alive
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest realm="My Site",
nonce="3266a84c73f7e0e13f4fa6ba1d52d4ce",
qop="auth"
Content-Type: text/html
Content-Length: 351
Date: Sun, 10 Jun 2007 23:52:57 GMT
Server: lighttpd/1.4.13
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>401 - Unauthorized</title>
</head>
<body>
<h1>401 - Unauthorized</h1>
</body>
</html>
GET / HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Host: obol.kmip.net
Connection: Keep-Alive
Authorization: Digest username="test",
realm="My Site",
qop="auth",
algorithm="MD5",
uri="/",
nonce="3266a84c73f7e0e13f4fa6ba1d52d4ce",
nc=00000001,
cnonce="5886b782b452993f7559cbd83b6b611b",
response="932dd7f51f34d766997923876508e620"
HTTP/1.1 200 OK
Content-Type: text/html
ETag: "972667827"
Accept-Ranges: bytes
Last-Modified: Sun, 22 Apr 2007 05:10:52 GMT
Content-Length: 2878
Date: Sun, 10 Jun 2007 23:56:44 GMT
Server: lighttpd/1.4.13
写了个小MIDlet测试Image在我的NOKIA 3230上是否能加载jpeg文件格式,为把WebCam的Client移植到手机上做准备,写好的程序在模拟器上可以正常使用,但在手机上老报“版本错误”,倒腾了半天才发现NOKIA 3230是CLDC1.0的设备而不是1.1,超低级的错误,晕@#$%^&*(
因为MySQL的授权问题,想把手上的程序换成PostgreSQL,但装了PostgreSQL发现它比MySQL复杂多了,一下移植过去不太可能,要花些时间弄清楚后再说.
python升级到2.4.4后发现所有牵涉到socket的模块都无法使用,上网找相关资料,发现居然连作者也不知道原因,没办法从package-6.1-release里装回python-2.4.2,但py24-bsddb3无法使用,只能用py24-bsddb-2.4.2_2,被这奇怪的问题折腾到半夜3点,原来想倒腾berkeley db的兴趣被弄得一点也没了。
用spca5xx做的Livecam通过CGI在lighttpd下实现总有个问题:client网速慢的时候lighttpd的内存用量会不断增加,一直到把系统榨干,没办法硬着头皮看lighttpd的mod_cgi源码,通过分析发现:
while(1) {
int n;
buffer_prepare_copy(hctx->response, 1024);
if (-1 == (n = read(hctx->fd, hctx->response->ptr, hctx->response->size - 1))) {
if (errno == EAGAIN || errno == EINTR) {
/* would block, wait for signal */
return FDEVENT_HANDLED_NOT_FINISHED;
}
......
} else {
http_chunk_append_mem(srv, con, hctx->response->ptr, hctx->response->used);
joblist_append(srv, con);
}
mod_cgi通过hctx->fd从cgi读取数据,然后由http_chunk_append_men()提交到后台,但chunk_append却没有限制内存的使用,当从cgi读取的速度快过提交给client速度时内存用量就会不断增加。本来想通过signal来同步cgi的采样,但这样太麻烦而且会破坏mod_cgi的结构,试着在read(hctx->fd...前加个阻塞判断:
if (http_chunkqueue_length(server *srv, connection *con) > 102400) {
return FDEVENT_HANDLED_NOT_FINISHED;
}
if (-1==(n=read(hctx->fd...
然后在spca5shot里每采样一frame加个sleep(1),运行几天看效果再说
倒腾了一天webcam,利用spca5xx的MJpeg流通过管道直接输出在客户端异常断开时老有问题,加上 | dd后正常,想不通,有空看看dd源码再说。
今天收到从美国寄来的Solaris 10 安装DVD,原来只是随便申请了一下,想不到居然SUN会发过来.
FreeBSD的蓝牙问题在网上很难找资料,来来去去就是那一两个档,而且也没Linux下的bluez、lightblue、pybluez可以利用,为了避免GPL的授权问题重写了实现,可以用的东西有:sdpd、hcsecd、rfcomm_pppd、rfcomm_sppd、obexapp。要想和我手机上的pyS60程序通讯,看来只有利用rfcomm_sppd,被ISSCBTA芯片的hci timeout问题搞得半死,最终也没能解决,花钱买了bcm芯片的dongle。
sudo dpkg-reconfigure xserver-xorg
sudo aticonfig --initial=dual-head
sudo aticonfig --overlay-type=Xv --desktop-setup=horizontal --screen-layout=right
Unofficial ATI Linux Driver Wiki[ubuntu] 兩台不同解析度的雙螢幕設定
前幾天把 Radeon 9550 從 Yuren's Info Area 拿下來以後,就迫不及待的裝到我的 Desktop 上。Windows 上設定當然是很簡單,稍微更改一下 ATI 專用軟體的設定就好了。在 Linux 上嘛,就要稍微設定一下了。
我電腦的顯示卡是洛克人 9550,螢幕 17" 的是 AG Neovo F-417,15" 的則是 cmv CT-529A。安裝 fglrx 驅動程式的步驟就不說了,很多地方都可以查的到。
接著就要修改一下 /etc/X11/xorg.conf,首先在 Section "Device" 加入以下設定:
Option "DesktopSetup" "0x00000200" #這是設定雙螢幕顯示是水平顯示(一左一右)
Option "MonitorLayout" "AUTO, AUTO" #兩個螢幕的 layout 用自動的
Option "HSync2" "28-65" #第二個螢幕的水平掃描頻率(請參照你自己的螢幕設定)
Option "VRefresh2" "50-78" #第二個螢幕的垂直掃描頻率(請參照你自己的螢幕設定)
Option "Mode2" "1024x768" #第二個螢幕的解析度設定
Option "ScreenOverlap" "0" #兩個螢幕要重複的像素點要多少
接著新增第二個螢幕的設定:
Section "Monitor"
Identifier "CT-529A"
Option "DPMS"
HorizSync 28-65
VertRefresh 50-78
EndSection
這樣就大功告成了。不過別忘了只有使用 fglrx 驅動程式的才能這麼設定,別的驅動程式有別種方法。完整的 xorg.conf 在
這裡
# loginbbs.py
import urllib,httplib
params = urllib.urlencode({'username':'pytest', #此处为要post的登陆参数,你可以修改为你自己的参数
'password':'pypassword',
'Cookies_Time': 1,
'IsLogin':True})
headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "text/plain"}
#构建headers
conn = httplib.HTTPConnection("music.popv.net:80") #建立http连接,记得地址不要加'http://'且要加上port
conn.request("POST",http://music.popv.net/popv/login.asp, params, headers)
#发送登陆请求
response = conn.getresponse() #获得回复
print response.status, response.reason #获得请求状态
data = response.read() #获得登陆后的网页内容
conn.close() #关闭连接
为了实现一个音频流服务写了几天的程序,但效果都不理想。昨天偶然看到inetd的运行机制,发现自己真是个猪:(,UNIX特有的fork配合pipe可以做出威力很大的东西来,以前一直没注意inetd这东西,要实现的功能其实写个脚本挂在inetd下就可以了,而且效率很高,CPU占用率比我自己写的程序低10倍,UNIX真是棒!
1. 建立内核配置文件graph
# cd /sys/i386/conf
# cp GENERIC graph
编辑配置文件graph,在其中加入两行:
options VESA
options SC_PIXEL_MODE
第一行选项让內核支持VESA 2,第二行让内核支持控制台图形模式。
2. 编译并安装内核
# config graph
# cd ../compile/graph
# make cleandepend
# make depend
# make
# make install
重新启动:
reboot
3. 激活高分辨率模式
用 vidcontrol -i mode|grep G 来查看支持MODE的列表,注意第一列的号码,你可能会用到,如279
用 vidcontrol MODE_279 来更改分辨率(我最高能上1280X1024,字太小了我受不了,呵呵)
如果想启动时生效,就在 /etc/rc.conf 加入 allscreens_flags="MODE_279
在做了几天的尝试后,我放弃了在FreeBSD做Video Motion的想法,FreeBSD没有Linux下Video4Linux的接口,网上也没找到在FreeBSD下使用V4L的例子,用ffmpeg可能是唯一的办法了,但不灵活,而且我也不想为了这点小东西去读ffmpeg的源码。
前两天看见google的LOGO很特别,突然有了收集的想法,就好象小时候集邮一样,写了个脚本在FreeBSD服务器上,用cron每天检查一次,如果有更新就拉下来,python的确很好用,虽然以前我没实际使用的经验,但写这个脚本没花太多的时间就完成了.
今天把写好的网页通过ftp传到服务器,但在服务器上看到文件的长度总是为零,搞了几分钟才发现是/usr满,在台式机的120G硬盘上用久了,都没节约空间的概念了,忘了服务器硬盘才4G!
圣诞夜陪同学去逛梦之岛商城,碰上搞活动,头脑发热去凑热闹买了双球鞋和个钱包。
用了FreeBSD一段时间后,发现自己的视野开阔了很多,以前碰上问题后马上在Win API里翻腾,找不到办法就上网找现成的SDK,然后自己crack一把,没有源码,具体的机制不知道,出了问题也没办法,只有再上网,然后crack...,在BSD和Linux下不一样,有很多现成的解决方案,大多数有源码,在解决问题的同时也可以学到很多东西,最主要的是:BSD很好玩,有很多东西可以自己捣腾。
搞定一个Flash的VCL控件,跟踪不是很难,就是点多,花了一上午的时间
昨天门面的财务数据突然出错,软件提示病毒或数据错误,排除病毒可能,应该就是数据错误了,DBF的数据结构很方便地找了个工具打开来看,看完吓一跳,明细序号都被清零了,因为用的是自己CRACK的软件,可以肯定中“诡雷”了,上网查了下居然有提供此问题的“数据恢复服务”,不过一颗心也放下了,毕竟还是有恢复的可能性。本子上没熟悉的ICE,硬着头皮用OD来跟踪,不熟悉OD操作浪费了蛮多时间,没来得看仔细本子没电了,他NN的,如果是ICE早搞定了。没办法在做帐的机器上恢复前几天的数据,试着乱做几笔帐让“现场”从新出现,通过观察DBF对比发现当明细刚好到一个B值时数据被破坏,利用HEX工具在主程序里也可以找B值,后面的代码也是熟悉的XX XX XXX ...,呵呵,这下我明白了,不用跟踪程序我居然可以猜出它的思路,我真是佩服自己,哇哈哈哈!!!晚上回家写了个程序利用DBF里剩余的数据修复被清空的部分,程序很简单,但为了用DBF,CRACK一个在网上找到的SDK倒花了我差不多一晚上,晕。
刚发现问题时居然担心自己解决不了,不象以前自信满满,看来我的心有点老了...
冷得手都有点不听话了,如果原来买Acer的笔记本就好了,外壳散热技术在冬天是个很有用的东东:),糟糕的是鼻炎犯了,想把POSTFIX的东西再看一遍,但鼻子发酸,老打喷嚏,没办法集中注意力。
和nakenchat的作者聊了几天,这家伙好象有点自大:),我说他的代码写得有点乱,他好象有点不高兴,说他的代码已经很完美了,不需要修改,他的另一朋友还叫我这个菜鸟不要乱发言,今天发现他代码里有个BUG,在某些平台上程序会当掉,写了email给他,这下他不敢再小瞧俺了吧,呵呵.
昨天被autoconf折腾了一天,搞得头晕眼花,做点小程序用它的话太麻烦。听说qmake是个轻量级的Makefile管理工具,今天在FreeBSD装了个来试试,和以往一样,装好后第一次使用失败:(,好在我对FreeBSD这种情况已经习惯了,检查生成的Makefile发现错误是由未找到qt相关文件引起的,利用freebsd-g++生成freebsd-cc的qmake.conf,把qt相关的项目取消,另外很少用到c++,把g++改为cc,export QMAKESPEC=freebsd-cc,问题解决。
一直觉得Apache太“肥大”了点,做点小东西不是很方便,想找个“轻”点又能配合tomcat的httpd服务,选来选去决定试用lighttpd,不说别的,光它的名字就很顺眼:),安装很方便,配置文件也不是很复杂,没看什么文档就跑起来了。
上网找了很多资料,关于自动升级的实现都是基于web的,对我手头上的基于LAN的程序没有帮助,既然程序是数据库的应用,那为什么不把升级的程序放到数据库里呢?mysql的blob字段有长度限制,大概800K左右,要做分段处理,但BCB的Stream机制可以很方便的解决问题。
TMemoryStream* memStream = new TMemoryStream();
TFileStream* fStream = new TFileStream("update.exe",fmCreate);
while (!update->Eof)
{
update->GetBlob("Data")->SaveToStream(memStream);
memStream->SaveToStream(fStream);
update->Next();
}
delete memStream;
delete fStream;
多优雅的处理,BCB写数据库应用好得没话说。
从新安装了FreeBSD服务器和Tomcat5.5,把原来的struts应用ObolHome.war发布上去出现了“Servlet action is not available”错误,上网查了半天也没得到解决的办法,因为原来的应用一直没问题,想一下应该不是配置文件的问题,检查windows下的tomcat发现tomcat/common/lib下有mysql-connector.jar,于是试着把FreeBSD上ObolHome/WEB-LIB/lib的mysql-connector.jar移到tomcat/common/lib下,问题解决!
刚写好的程序要用SSL通道来加密数据,为了实现方便通过加载stunnel来实现,程序开始前用CreateProcess打开stunnel,结束后PostMessage(WM_QUIT),但任务栏上该死的stunnel图标却要用鼠标晃一下才消失,没办法只好“帮”它一把:Shell_NotifyIcon,HWND参数可以用FindWindow找到,uID麻烦点,用调试工具拦截stunnel调用Shell_NotifyIcon的地址,uID=1。
Info Power 是个很棒的VCL,特别是RecordViewDlg控件很有特点,在添加和编辑数据时很有用,但在打开EnterToTab参数时不能跳到确认键上,必须用鼠标操作。还好有它的源码,稍微修改一下就可以了:
//--------------------
// wwrcdvw.pas
//--------------------
......
RecordPanel:= TPanel.create(RecordViewForm);
with RecordPanel do begin
parent:= RecordViewForm;
Left := 0;
Top := 41;
Align := alClient;
BevelInner := bvLowered;
BorderWidth := 4;
Caption := '';
TabOrder := 0; //I hack
Name:= 'RecordPanel';
visible:= True;
end;
if (rvokShowOKCancel in OKCancelOptions) then begin
ButtonPanel:= TPanel.create(RecordViewForm);
with ButtonPanel do begin
parent:= RecordViewForm;
Left := 0;
Top := 0;
Align := alBottom;
Name:= 'UserPanel';
Caption := '';
TabOrder := 1; //I hack
visible:= True;
OkBtn:= TButton(wwCreateCommonButton(RecordViewForm, bkOK));
OKBtn.Default:= not (rvoEnterToTab in Options);
OkBtn.parent:= ButtonPanel;
OKBtn.visible:= True;
OKBtn.OnClick := OKBtnClick;
OKBtn.TabStop:= True; //I hack
CancelBtn:= TButton(wwCreateCommonButton(RecordViewForm, bkCancel));
CancelBtn.Parent := ButtonPanel;
CancelBtn.visible:= True;
CancelBtn.OnClick := CancelBtnClick;
CancelBtn.TabStop:= True; //I hack
CancelBtn.Cancel:= False; { Allows Escape to be processed }
bottomPad := 1 + GetSystemMetrics(SM_CYDLGFRAME)*2 +8 +1; {Win95 fix }
Height := OkBtn.Top + OkBtn.height + BottomPad;
OkBtn.Top := GetSystemMetrics(SM_CYDLGFRAME) + 5;
CancelBtn.Top := GetSystemMetrics(SM_CYDLGFRAME) +5;
end;
end;
......