用户送礼流程:
1. 定时同步用户的最新礼品数据。 <-- ok
2. 用户点击礼品,弹出送礼窗口。
3. 在窗口中显示,送给 主持人... 礼品 ... 数量 为 1 。
4. 允许用户修改数量,最大为30。
5. 有一个选项,假如积分不足,则自动送能送的最大值。
6. 用户点击确认后,自动关闭当前窗口,发送私聊消息给主持人
?sys_gift_send?
JSON_Encode(gift:xxx, giftcount:xxx,giftid:xxx, auto:0/1)
?/sys_gift_send?
auto=1表示自动计算
auto=0表示不作计算,失败则返回。
7. 主持人收到后,发送请求给服务器,确认是否能成功送出礼物:
index.php?Controller=Chat&Action=sendGift&giftid=xxx&giftcount=xxx&auto=xxx&account=xxx
服务器返回的数据为
JSON_Encode(gift:xxx, giftcount:xxx,giftid:xxx,success:0/1,message:积分不足)
success=1表示成功,success=0表示失败
<-- ok
8. success=1成功
向所有在线用户广播 ?sys_top_message/? xxx 送给 xxx xxx ( x giftcount ) . 这个显示到头条。
向房间内所有用户广播:xxx 送给 xxx xxx 显示 giftcount 次数。
向用户发送私聊信息
?sys_gift_send_ack?
JSON_Encode(gift:xxx, giftcount:xxx,giftid:xxx,success:0/1,message:积分不足)
?/sys_gift_send_ack?
收到后,弹出提示信息。并且同时从服务器更新 profile(heartbeat)
9. success=0 失败
向原用户回复,失败。以及失败原因:message
向用户发送私聊信息
?sys_gift_send_ack?
JSON_Encode(gift:xxx, giftcount:xxx,giftid:xxx,success:0/1,message:积分不足)
?/sys_gift_send_ack?
收到后,弹出提示信息。并且同时从服务器更新 profile(heartbeat)
10. 下一个送礼循环
2008年11月30日星期日
2008年11月23日星期日
Flex 的样式问题 tab Alert 等
http://www.cnblogs.com/taobataoma/archive/2008/01/13/1037060.html
-- Tab 的样式
http://www.nshen.net/blog/article.asp?id=552l
-- Alert 的样式定义
-- Tab 的样式
http://www.nshen.net/blog/article.asp?id=552l
-- Alert 的样式定义
2008年11月10日星期一
2008年11月7日星期五
开发你自己的XMPP IM
http://phoenixtoday.blogbus.com/logs/20285574.html
http://phoenixtoday.blogbus.com/logs/17878527.html
http://phoenixtoday.blogbus.com/logs/17246727.html
http://initiative.yo2.cn/archives/591950
http://phoenixtoday.blogbus.com/logs/17878527.html
http://phoenixtoday.blogbus.com/logs/17246727.html
http://initiative.yo2.cn/archives/591950
2008年11月5日星期三
wapshop网站安装
1. 安装Apache日志截断程序cronolog
wget -c wget http://cronolog.org/download/cronolog-1.6.2.tar.gz
tar -zxvf cronolog-1.6.2.tar.gz
cd cronolog-1.6.2
./configure --prefix=/usr/wapshop/install/cronolog
make
make install
2. 安装apache服务器,测试index.html
2.1 下载
wget -c http://apache.freelamp.com/httpd/httpd-2.2.9.tar.gz
2.2 解压缩,配置,编译,安装
tar -zxvf httpd-2.2.9.tar.gz
cd httpd-2.2.9
./configure \
--prefix=/usr/wapshop/install/apache2 \
--enable-so \
--enable-rewrite=static \
--enable-cache \
--enable-file-cache \
--enable-mem-cache \
--enable-disk-cache \
--enable-static-support \
--enable-static-htpasswd \
--enable-static-htdigest \
--enable-static-rotatelogs \
--enable-static-logresolve \
--enable-static-htdbm \
--enable-static-ab \
--enable-static-checkgid \
--disable-cgid \
--disable-cgi
========================================
编译配置说明
./configure //配置源代码树
--prefix=/usr/wapshop/install/apache2 //体系无关文件的顶级安装目录PREFIX ,也就Apache的安装目录。
--enable-so //打开 so 模块,so 模块是用来提 DSO 支持的 apache 核心模块
--enable-rewrite=static //打开rewrite 功能模块
--enable-mods-shared=all //编译全部的模板,对于不需要我们可以在httpd.conf去掉。这个选项打开可能会需要有更多的依赖库,在这里可以去掉
--enable-cache //支持缓存
--enable-file-cache //支持文件缓存
--enable-mem-cache //支持记忆缓存
--enable-disk-cache //支持磁盘缓存
--enable-static-support //支持静态连接(默认为动态连接)
--enable-static-htpasswd //使用静态连接编译 htpasswd - 管理用于基本认证的用户文件
--enable-static-htdigest //使用静态连接编译 htdigest - 管理用于摘要认证的用户文件
--enable-static-rotatelogs //使用静态连接编译 rotatelogs - 滚动 Apache 日志的管道日志程序
--enable-static-logresolve //使用静态连接编译 logresolve - 解析 Apache 日志中的IP地址为主机名
--enable-static-htdbm //使用静态连接编译 htdbm - 操作 DBM 密码数据库
--enable-static-ab //使用静态连接编译 ab - Apache HTTP 服务器性能测试工具
--enable-static-checkgid //使用静态连接编译 checkgid
--disable-cgid //禁止用一个外部 CGI 守护进程执行CGI脚本
--disable-cgi //禁止编译 CGI 版本的 PHP
--enable-ssl // 编译 ssl模块。这个选项打开可能需要更多的依赖库,在这里可以去掉
=============================
make
make install
2.3 配置apache2的端口和根目录
cd /usr/wapshop/install/apache2
cp conf/httpd.conf conf/httpd.conf.20081106
vi conf/httpd.conf
==========================================
Listen 80 --> Listen 8080 不过暂时使用80,因为需要映射该端口到10080
DirectoryIndex index.html --> DirectoryIndex index.php index.html
DocumentRoot "/usr/wapshop/install/apache2/htdocs" --> DocumentRoot "/usr/wapshop/htdocs"
Directory "/usr/wapshop/install/apache2/htdocs" --> Directory "/usr/wapshop/htdocs"
==========================================
2.4 配置cronolog日志截断程序
vi conf/httpd.conf
==========================================
CustomLog "logs/access_log" common
-->
CustomLog "|/usr/wapshop/install/cronolog/sbin/cronolog /usr/wapshop/install/apache2/logs/access_log.%Y%m%d" combined
==========================================
2.5 配置启动脚本
mkdir /usr/wapshop/install/init.d
cd /usr/wapshop/install/init.d
ln -s ../apache2/bin/apachectl apache2
启动命令: /usr/wapshop/install/init.d/apache2 start
关闭命令: /usr/wapshop/install/init.d/apache2 stop
2.6 测试服务器
mkdir /usr/wapshop/htdocs
vi /usr/wapshop/htdocs/index.html
===========================================
<html>
<head>
<title> test </title>
</head>
<body>
<h1>Test</h1>
</body>
</html>
===========================================
/usr/wapshop/install/init.d/apache2 start
wget http://127.0.0.1/index.html
cat index.html | grep -e "Test"
3. 安装mysql服务器
3.0 需要安装g++ 和 ncurse-devel
wget -c ftp://mirror.switch.ch/pool/3/mirror/centos/4.6/os/x86_64/CentOS/RPMS/gcc-c++-3.4.6-9.x86_64.rpm
wget -c ftp://mirror.switch.ch/pool/3/mirror/centos/4.6/os/x86_64/CentOS/RPMS/libstdc++-devel-3.4.6-9.x86_64.rpm
wget -c ftp://mirror.switch.ch/pool/3/mirror/centos/4.6/os/x86_64/CentOS/RPMS/libstdc++-3.4.6-9.x86_64.rpm
wget -c ftp://ftp.chg.ru/pub/Linux/scientific/41/x86_64/SL/RPMS/ncurses-devel-5.4-13.x86_64.rpm
rpm -i gcc-c++-3.4.6-9.x86_64.rpm libstdc++-devel-3.4.6-9.x86_64.rpm libstdc++-3.4.6-9.x86_64.rpm ncurses-devel-5.4-13.x86_64.rpm
3.1 为了避免对系统的干扰,需要注意修改端口号和相关的目录。
wget -c http://mysql.mirror.rafal.ca/Downloads/MySQL-5.0/mysql-5.0.67.tar.gz
cd /usr/wapshop/download/mysql-5.0.67
mkdir /usr/wapshop/install/mysql5
mkdir -p /usr/wapshop/var/lib/mysql5
./configure \
--prefix=/usr/wapshop/install/mysql5 \
--localstatedir=/usr/wapshop/var/lib/mysql5 \
--with-comment=Source \
--with-server-suffix=-Community \
--with-mysqld-user=mysql \
--without-debug \
--with-big-tables \
--with-charset=utf8 \
--with-collation=utf8_unicode_ci \
--with-extra-charsets=all \
--with-pthread \
--enable-static \
--enable-thread-safe-client \
--with-client-ldflags=-all-static \
--with-mysqld-ldflags=-all-static \
--enable-assembler \
--without-innodb \
--without-ndb-debug
make
make install
cd /usr/wapshop/install/mysql5
groupadd mysql //添加 mysql 组
useradd -g mysql mysql //添加 mysql 用户
chown -R mysql .
chgrp -R mysql .
./bin/mysql_install_db --user=mysql
chown -R root .
chown -R mysql /usr/wapshop/var/lib/mysql5
cp share/mysql/my-huge.cnf .
vi my-huge.cnf
==========================================
port: 3306 --> 3307 两个地方
socket: /tmp/mysql.sock --> /tmp/mysqlwapshop.sock 两个地方
==========================================
cp share/mysql/mysql.server /usr/wapshop/install/init.d/mysqlwapshop
vi /usr/wapshop/install/init.d/mysqlwapshop
==========================================
datadir= --> datadir=/usr/wapshop/var/lib/mysql5
conf=/etc/my.cnf --> conf=/usr/wapshop/install/mysql5/my-huge.cnf
把"$bindir/mysqld_safe --datadir=$datadir --pid-file=$server_pid_file $other_args >/dev/null 2>&1 &"替换为(双引号中的)
"$bindir/mysqld_safe --defaults-file=/usr/wapshop/install/mysql5/my-huge.cnf --datadir=$datadir --pid-file=$server_pid_file $other_args >/dev/null 2>&1 &"(双引号中的)
==========================================
chmod 755 /usr/wapshop/install/init.d/mysqlwapshop
//chkconfig --add mysqlwapshop <-- 暂时不用
3.2 启动数据库
/usr/wapshop/install/init.d/mysqlwapshop start
3.3 确认服务正常启动
netstat -an | grep -e "LISTEN"|grep -e "3307"
3.4 修改root用户密码
./bin/mysql -u root -S /tmp/mysqlwapshop.sock
======================================================
mysql> use mysql
mysql> update user set password=password('wapshop') where user='root';
mysql> FLUSH PRIVILEGES;
======================================================
3.5 停止数据库运行
/usr/wapshop/install/init.d/mysqlwapshop stop
4. 安装php环境,测试phpinfo.php
4.0 需要lib-xml2
wget -c ftp://ftp.pbone.net/mirror/www.startcom.org/AS-4.0.0/updates/x86_64/zlib-devel-1.2.1.2-1.2.x86_64.rpm
wget -c ftp://ftp.pbone.net/mirror/www.startcom.org/AS-4.0.0/os/x86_64/StartCom/RPMS/libxml2-devel-2.6.16-6.x86_64.rpm
rpm -i libxml2-devel-2.6.16-6.x86_64.rpm zlib-devel-1.2.1.2-1.2.x86_64.rpm
4.1 下载
wget -c http://cn.php.net/get/php-5.2.6.tar.gz/from/this/mirror
4.2 解压缩,编译,安装
tar -zxvf php-5.2.6.tar.gz
cd php-5.2.6
ln -sf libjpeg.so.62.0.0 libjpeg.so
ln -sf libpng.so.3.1.2.7 libpng.so
./configure \
--prefix=/usr/wapshop/install/php5 \
--with-apxs2=/usr/wapshop/install/apache2/bin/apxs \
--with-mysql=/usr/wapshop/install/mysql5 \
--disable-debug \
--with-zlib \
--enable-mbstring \
--with-gd \
--with-jpeg-dir \
--with-png-dir \
--enable-fastcgi \
--with-config-file-scan-dir=/usr/wapshop/install/php5/etc/php \
--with-mysqli=/usr/wapshop/install/mysql5/bin/mysql_config
make
make test
make install
mkdir -p /usr/wapshop/install/php5/etc/php
cp php.ini-dist /usr/wapshop/install/php5/etc/php/php.ini
4.3 整合php和apache2
#make install 会自动修改http.conf 加上 LoadModule php5_module modules/libphp5.so
只需要在最后一行加上:
AddType application/x-httpd-php .php
4.4 测试phpinfo()
/usr/wapshop/install/init.d/apache2 stop
/usr/wapshop/install/init.d/apache2 start
cd /usr/wapshop/htdocs/
vi index.php
=========================================
phpinfo();
?>
=========================================
需要确认有 gd 和 mysqli 的支持。
wget -c wget http://cronolog.org/download/cronolog-1.6.2.tar.gz
tar -zxvf cronolog-1.6.2.tar.gz
cd cronolog-1.6.2
./configure --prefix=/usr/wapshop/install/cronolog
make
make install
2. 安装apache服务器,测试index.html
2.1 下载
wget -c http://apache.freelamp.com/httpd/httpd-2.2.9.tar.gz
2.2 解压缩,配置,编译,安装
tar -zxvf httpd-2.2.9.tar.gz
cd httpd-2.2.9
./configure \
--prefix=/usr/wapshop/install/apache2 \
--enable-so \
--enable-rewrite=static \
--enable-cache \
--enable-file-cache \
--enable-mem-cache \
--enable-disk-cache \
--enable-static-support \
--enable-static-htpasswd \
--enable-static-htdigest \
--enable-static-rotatelogs \
--enable-static-logresolve \
--enable-static-htdbm \
--enable-static-ab \
--enable-static-checkgid \
--disable-cgid \
--disable-cgi
========================================
编译配置说明
./configure //配置源代码树
--prefix=/usr/wapshop/install/apache2 //体系无关文件的顶级安装目录PREFIX ,也就Apache的安装目录。
--enable-so //打开 so 模块,so 模块是用来提 DSO 支持的 apache 核心模块
--enable-rewrite=static //打开rewrite 功能模块
--enable-mods-shared=all //编译全部的模板,对于不需要我们可以在httpd.conf去掉。这个选项打开可能会需要有更多的依赖库,在这里可以去掉
--enable-cache //支持缓存
--enable-file-cache //支持文件缓存
--enable-mem-cache //支持记忆缓存
--enable-disk-cache //支持磁盘缓存
--enable-static-support //支持静态连接(默认为动态连接)
--enable-static-htpasswd //使用静态连接编译 htpasswd - 管理用于基本认证的用户文件
--enable-static-htdigest //使用静态连接编译 htdigest - 管理用于摘要认证的用户文件
--enable-static-rotatelogs //使用静态连接编译 rotatelogs - 滚动 Apache 日志的管道日志程序
--enable-static-logresolve //使用静态连接编译 logresolve - 解析 Apache 日志中的IP地址为主机名
--enable-static-htdbm //使用静态连接编译 htdbm - 操作 DBM 密码数据库
--enable-static-ab //使用静态连接编译 ab - Apache HTTP 服务器性能测试工具
--enable-static-checkgid //使用静态连接编译 checkgid
--disable-cgid //禁止用一个外部 CGI 守护进程执行CGI脚本
--disable-cgi //禁止编译 CGI 版本的 PHP
--enable-ssl // 编译 ssl模块。这个选项打开可能需要更多的依赖库,在这里可以去掉
=============================
make
make install
2.3 配置apache2的端口和根目录
cd /usr/wapshop/install/apache2
cp conf/httpd.conf conf/httpd.conf.20081106
vi conf/httpd.conf
==========================================
Listen 80 --> Listen 8080 不过暂时使用80,因为需要映射该端口到10080
DirectoryIndex index.html --> DirectoryIndex index.php index.html
DocumentRoot "/usr/wapshop/install/apache2/htdocs" --> DocumentRoot "/usr/wapshop/htdocs"
Directory "/usr/wapshop/install/apache2/htdocs" --> Directory "/usr/wapshop/htdocs"
==========================================
2.4 配置cronolog日志截断程序
vi conf/httpd.conf
==========================================
CustomLog "logs/access_log" common
-->
CustomLog "|/usr/wapshop/install/cronolog/sbin/cronolog /usr/wapshop/install/apache2/logs/access_log.%Y%m%d" combined
==========================================
2.5 配置启动脚本
mkdir /usr/wapshop/install/init.d
cd /usr/wapshop/install/init.d
ln -s ../apache2/bin/apachectl apache2
启动命令: /usr/wapshop/install/init.d/apache2 start
关闭命令: /usr/wapshop/install/init.d/apache2 stop
2.6 测试服务器
mkdir /usr/wapshop/htdocs
vi /usr/wapshop/htdocs/index.html
===========================================
<html>
<head>
<title> test </title>
</head>
<body>
<h1>Test</h1>
</body>
</html>
===========================================
/usr/wapshop/install/init.d/apache2 start
wget http://127.0.0.1/index.html
cat index.html | grep -e "Test"
3. 安装mysql服务器
3.0 需要安装g++ 和 ncurse-devel
wget -c ftp://mirror.switch.ch/pool/3/mirror/centos/4.6/os/x86_64/CentOS/RPMS/gcc-c++-3.4.6-9.x86_64.rpm
wget -c ftp://mirror.switch.ch/pool/3/mirror/centos/4.6/os/x86_64/CentOS/RPMS/libstdc++-devel-3.4.6-9.x86_64.rpm
wget -c ftp://mirror.switch.ch/pool/3/mirror/centos/4.6/os/x86_64/CentOS/RPMS/libstdc++-3.4.6-9.x86_64.rpm
wget -c ftp://ftp.chg.ru/pub/Linux/scientific/41/x86_64/SL/RPMS/ncurses-devel-5.4-13.x86_64.rpm
rpm -i gcc-c++-3.4.6-9.x86_64.rpm libstdc++-devel-3.4.6-9.x86_64.rpm libstdc++-3.4.6-9.x86_64.rpm ncurses-devel-5.4-13.x86_64.rpm
3.1 为了避免对系统的干扰,需要注意修改端口号和相关的目录。
wget -c http://mysql.mirror.rafal.ca/Downloads/MySQL-5.0/mysql-5.0.67.tar.gz
cd /usr/wapshop/download/mysql-5.0.67
mkdir /usr/wapshop/install/mysql5
mkdir -p /usr/wapshop/var/lib/mysql5
./configure \
--prefix=/usr/wapshop/install/mysql5 \
--localstatedir=/usr/wapshop/var/lib/mysql5 \
--with-comment=Source \
--with-server-suffix=-Community \
--with-mysqld-user=mysql \
--without-debug \
--with-big-tables \
--with-charset=utf8 \
--with-collation=utf8_unicode_ci \
--with-extra-charsets=all \
--with-pthread \
--enable-static \
--enable-thread-safe-client \
--with-client-ldflags=-all-static \
--with-mysqld-ldflags=-all-static \
--enable-assembler \
--without-innodb \
--without-ndb-debug
make
make install
cd /usr/wapshop/install/mysql5
groupadd mysql //添加 mysql 组
useradd -g mysql mysql //添加 mysql 用户
chown -R mysql .
chgrp -R mysql .
./bin/mysql_install_db --user=mysql
chown -R root .
chown -R mysql /usr/wapshop/var/lib/mysql5
cp share/mysql/my-huge.cnf .
vi my-huge.cnf
==========================================
port: 3306 --> 3307 两个地方
socket: /tmp/mysql.sock --> /tmp/mysqlwapshop.sock 两个地方
==========================================
cp share/mysql/mysql.server /usr/wapshop/install/init.d/mysqlwapshop
vi /usr/wapshop/install/init.d/mysqlwapshop
==========================================
datadir= --> datadir=/usr/wapshop/var/lib/mysql5
conf=/etc/my.cnf --> conf=/usr/wapshop/install/mysql5/my-huge.cnf
把"$bindir/mysqld_safe --datadir=$datadir --pid-file=$server_pid_file $other_args >/dev/null 2>&1 &"替换为(双引号中的)
"$bindir/mysqld_safe --defaults-file=/usr/wapshop/install/mysql5/my-huge.cnf --datadir=$datadir --pid-file=$server_pid_file $other_args >/dev/null 2>&1 &"(双引号中的)
==========================================
chmod 755 /usr/wapshop/install/init.d/mysqlwapshop
//chkconfig --add mysqlwapshop <-- 暂时不用
3.2 启动数据库
/usr/wapshop/install/init.d/mysqlwapshop start
3.3 确认服务正常启动
netstat -an | grep -e "LISTEN"|grep -e "3307"
3.4 修改root用户密码
./bin/mysql -u root -S /tmp/mysqlwapshop.sock
======================================================
mysql> use mysql
mysql> update user set password=password('wapshop') where user='root';
mysql> FLUSH PRIVILEGES;
======================================================
3.5 停止数据库运行
/usr/wapshop/install/init.d/mysqlwapshop stop
4. 安装php环境,测试phpinfo.php
4.0 需要lib-xml2
wget -c ftp://ftp.pbone.net/mirror/www.startcom.org/AS-4.0.0/updates/x86_64/zlib-devel-1.2.1.2-1.2.x86_64.rpm
wget -c ftp://ftp.pbone.net/mirror/www.startcom.org/AS-4.0.0/os/x86_64/StartCom/RPMS/libxml2-devel-2.6.16-6.x86_64.rpm
rpm -i libxml2-devel-2.6.16-6.x86_64.rpm zlib-devel-1.2.1.2-1.2.x86_64.rpm
4.1 下载
wget -c http://cn.php.net/get/php-5.2.6.tar.gz/from/this/mirror
4.2 解压缩,编译,安装
tar -zxvf php-5.2.6.tar.gz
cd php-5.2.6
ln -sf libjpeg.so.62.0.0 libjpeg.so
ln -sf libpng.so.3.1.2.7 libpng.so
./configure \
--prefix=/usr/wapshop/install/php5 \
--with-apxs2=/usr/wapshop/install/apache2/bin/apxs \
--with-mysql=/usr/wapshop/install/mysql5 \
--disable-debug \
--with-zlib \
--enable-mbstring \
--with-gd \
--with-jpeg-dir \
--with-png-dir \
--enable-fastcgi \
--with-config-file-scan-dir=/usr/wapshop/install/php5/etc/php \
--with-mysqli=/usr/wapshop/install/mysql5/bin/mysql_config
make
make test
make install
mkdir -p /usr/wapshop/install/php5/etc/php
cp php.ini-dist /usr/wapshop/install/php5/etc/php/php.ini
4.3 整合php和apache2
#make install 会自动修改http.conf 加上 LoadModule php5_module modules/libphp5.so
只需要在最后一行加上:
AddType application/x-httpd-php .php
4.4 测试phpinfo()
/usr/wapshop/install/init.d/apache2 stop
/usr/wapshop/install/init.d/apache2 start
cd /usr/wapshop/htdocs/
vi index.php
=========================================
phpinfo();
?>
=========================================
需要确认有 gd 和 mysqli 的支持。
2008年10月30日星期四
2008年10月28日星期二
Linux/Unix Shell Script To Find Your Google Page Rank
http://linuxshellaccount.blogspot.com/2008/10/linuxunix-shell-script-to-find-your.html
2008年10月27日星期一
ouxunsi视频网站搭建(2)
openfire + red5 + (openmeetings / jwchat / spark)
1. 安装JDK1.6
下载jdk-6u3-linux-i586.bin
# chmod +x jdk-6u3-linux-i586.bin
# ./jdk-6u3-linux-i586.bin
# mv jdk1.6.3 /usr/local/ ----------移动位置
# mv jdk1.6.3 jdk1.6 ----------文件夹改名
配置环境变量
# vi /etc/profile
在末尾追加
#Java environment
export JAVA_HOME=/usr/local/jdk1.6
export CLASSPATH=.:$JAVA_HOME/jre/lib:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar
export PATH=$JAVA_HOME/bin:$PATH
:wq保存退出。
# source /etc/profile -------------使配置生效
执行# java -version 命令,显示
java version "1.6.0_03"
Java(TM) SE Runtime Environment (build 1.6.0_03-b05)
Java HotSpot(TM) Client VM (build 1.6.0_03-b05, mixed mode, sharing)
2.安装ANT
下载apache-ant-1.7.0-bin.tar.gz
# tar zxvf apache-ant-1.7.0-bin.tar.gz
# mv apache-ant-1.7.0 /usr/local/
# mv apache-ant-1.7.0 ant
配置环境变量
# vi /etc/profile
在末尾追加
#Ant environment
export ANT_HOME=/usr/local/ant
export PATH=$ANT_HOME/bin:$PATH
:wq保存退出。
# source /etc/profile
执行ant -version命令,显示
Apache Ant version 1.7.0 compiled on December 13 2006
安装成功!
2.安装openfire
在http://www.igniterealtime.org/downloads/index.jsp#openfire上下载openfire-3.5.1-1.i386.rpm包
# rpm -ivh openfire-3.5.1-1.i386.rpm
默认安装在 /opt/openfire
# vi /etc/sysconfig/iptables
追加下面2行
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 9090 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 9091 -j ACCEPT
:wq保存退出后执行
# service iptables restart
可以使用下面的命令启动服务:
# /opt/openfire/bin/openfire.sh
或者用保存在/etc/init.d/下的openfire脚本启动服务,命令是/etc/init.d/openfire start
脚本如下:
#!/bin/sh
#
# openfire Stops and starts the Openfire XMPP service.
#
# chkconfig: 2345 99 1
# description: Openfire is an XMPP server, which is a server that facilitates \
# XML based communication, such as chat.
# config: /opt/openfire/conf/openfire.xml
# config: /etc/sysconfig/openfire
# pidfile: /var/run/openfire.pid
#
# This script has currently been tested on Redhat, CentOS, and Fedora based
# systems.
#
#####
# Begin setup work
#####
# Initialization
PATH="/sbin:/bin:/usr/bin:/usr/sbin"
RETVAL=0
# Check that we are root ... so non-root users stop here.
[ "`id -u`" = 0 ] || exit 1
# Get config.
[ -f "/etc/sysconfig/openfire" ] && . /etc/sysconfig/openfire
# If openfire user is not set in sysconfig, set to daemon.
[ -z "$OPENFIRE_USER" ] && OPENFIRE_USER="daemon"
# If pid file path is not set in sysconfig, set to /var/run/openfire.pid.
[ -z "$OPENFIRE_PIDFILE" ] && OPENFIRE_PIDFILE="/var/run/openfire.pid"
# -----------------------------------------------------------------
# If a openfire home variable has not been specified, try to determine it.
if [ -z "$OPENFIRE_HOME" -o ! -d "$OPENFIRE_HOME" ]; then
if [ -d "/usr/share/openfire" ]; then
OPENFIRE_HOME="/usr/share/openfire"
elif [ -d "/usr/local/openfire" ]; then
OPENFIRE_HOME="/usr/local/openfire"
elif [ -d "/opt/openfire" ]; then
OPENFIRE_HOME="/opt/openfire"
else
echo "Could not find Openfire installation under /opt, /usr/share, or /usr/local."
echo "Please specify the Openfire installation location as variable OPENFIRE_HOME"
echo "in /etc/sysconfig/openfire."
exit 1
fi
fi
# If log path is not set in sysconfig, set to $OPENFIRE_HOME/logs.
[ -z "$OPENFIRE_LOGDIR" ] && OPENFIRE_LOGDIR="${OPENFIRE_HOME}/logs"
# Attempt to locate java installation.
if [ -z "$JAVA_HOME" ]; then
if [ -d "${OPENFIRE_HOME}/jre" ]; then
JAVA_HOME="${OPENFIRE_HOME}/jre"
elif [ -d "/etc/alternatives/jre" ]; then
JAVA_HOME="/etc/alternatives/jre"
else
jdks=`ls -r1d /usr/java/j*`
for jdk in $jdks; do
if [ -f "${jdk}/bin/java" ]; then
JAVA_HOME="$jdk"
break
fi
done
fi
fi
JAVACMD="${JAVA_HOME}/bin/java"
if [ ! -d "$JAVA_HOME" -o ! -x "$JAVACMD" ]; then
echo "Error: JAVA_HOME is not defined correctly."
echo " Can not sure execute $JAVACMD."
exit 1
fi
# Prepare location of openfire libraries
OPENFIRE_LIB="${OPENFIRE_HOME}/lib"
# Prepare openfire command line
OPENFIRE_OPTS="${OPENFIRE_OPTS} -DopenfireHome=${OPENFIRE_HOME} -Dopenfire.lib.dir=${OPENFIRE_LIB}"
# Prepare local java class path
if [ -z "$LOCALCLASSPATH" ]; then
LOCALCLASSPATH="${OPENFIRE_LIB}/startup.jar"
else
LOCALCLASSPATH="${OPENFIRE_LIB}/startup.jar:${LOCALCLASSPATH}"
fi
# Export any necessary variables
#export JAVA_HOME JAVACMD
export JAVA_HOME=/usr/local/jdk1.6
export JAVACMD=/usr/local/jdk1.6/bin/java
# Lastly, prepare the full command that we are going to run.
OPENFIRE_RUN_CMD="${JAVACMD} -server ${OPENFIRE_OPTS} -classpath \"${LOCALCLASSPATH}\" -jar \"${OPENFIRE_LIB}/startup.jar\""
#####
# End setup work
#####
start() {
OLD_PWD=`pwd`
cd $OPENFIRE_LOGDIR
# Start daemons.
echo -n "Starting openfire: "
rm -f nohup.out
sudo su -s /bin/sh -c "nohup $OPENFIRE_RUN_CMD > $OPENFIRE_LOGDIR/nohup.out 2>&1 &" $OPENFIRE_USER
RETVAL=$?
PID=`ps ax --width=1000 | grep openfire | grep startup.jar | awk '{print $1}'`
if [ $RETVAL -eq 0 -a ! -z "$PID" -a ! -z "$OPENFIRE_PIDFILE" ]; then
echo $PID > $OPENFIRE_PIDFILE
fi
echo
[ $RETVAL -eq 0 -a -d /var/lock/subsys ] && touch /var/lock/subsys/openfire
sleep 1 # allows prompt to return
cd $OLD_PWD
}
stop() {
# Stop daemons.
echo -n "Shutting down openfire: "
[ -f "$OPENFIRE_PIDFILE" ] && kill `cat $OPENFIRE_PIDFILE`
RETVAL=$?
echo
[ $RETVAL -eq 0 -a -f "$OPENFIRE_PIDFILE" ] && rm -f $OPENFIRE_PIDFILE
[ $RETVAL -eq 0 -a -f "/var/lock/subsys/openfire" ] && rm -f /var/lock/subsys/openfire
}
restart() {
stop
sleep 10 # give it a few moments to shut down
start
}
condrestart() {
[ -e "/var/lock/subsys/openfire" ] && restart
return 0
}
status() {
pid=`cat $OPENFIRE_PIDFILE 2>&1`
if [ "$?" = "1" ]; then
echo "openfire is not running"
RETVAL=0
else
ps -p $pid > /dev/null 2>&1
if [ "$?" = "0" ]; then
echo "openfire is running"
RETVAL=0
else
echo "openfire is not running"
RETVAL=0
fi
fi
}
# Handle how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
condrestart)
condrestart
;;
reload)
restart
;;
status)
status
;;
*)
echo "Usage $0 {start|stop|restart|status|condrestart|reload}"
RETVAL=1
esac
exit $RETVAL
脚本到此结束。
设置为开机自启动
# chkconfig openfire on
# chkconfig --list openfire
openfire 0:关闭 1:关闭 2:启用 3:启用 4:启用 5:启用 6:关闭
设置成功!
接下来在浏览器中输入http://你的服务器的IP:9090即可开始即时通讯服务器配置
(1)语言选择:中文简体
(2)服务期设置:选择域及端口,建议默认
(3)数据库设置:根据需要,这里选“标准数据库”
(4)标准数据库设置:选择MySQL,数据库URL填入你的数据库地址,端口和数据库名称(请自行创建)用户名密码填入你的mysql的帐号密码,其他根据需要选择填写。继续之后会在你的mysql中创建表并初始化。
(5)特性设置:如果你不打算用LDAP,保留默认
(6)管理员帐户设置:填入系统管理员信息
(7)安装完成
至此,Openfire安装完毕。你可以继续登录到管理控制台,进行更为详细的设置。
服务器到此安装完成。建议客户端在windows上使用spark,因为Spark和Openfire能够很好的相互支持,是黄金组合。
下载地址:http://www.igniterealtime.org/downloads/index.jsp#spark
安装比较简单,安装完成后就可以注册-->登录-->使用了。挺不错的开源聊天软件。
3. 安装Red5
下载Red5的安装文件,下载地址:http://osflash.org/red5
# tar zxvf red5-0.6.3.tar.gz
# cd red5-0.6.3
# ant
编译完后把dist文件夹内的文件copy到 /var/www/red5 文件夹下。
# vi /etc/sysconfig/iptables
开放端口,添加以下内容:
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 1935 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 1936 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 1945 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 5080 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 8088 -j ACCEPT
# /etc/rc.d/init.d/iptables restart
重启防火墙
#cd /var/www/red5
# ./red5.sh &
启动服务
可以访问http://ip:5080。
安装完成。
http://www.javaeye.com/topic/212656
1. 安装JDK1.6
下载jdk-6u3-linux-i586.bin
# chmod +x jdk-6u3-linux-i586.bin
# ./jdk-6u3-linux-i586.bin
# mv jdk1.6.3 /usr/local/ ----------移动位置
# mv jdk1.6.3 jdk1.6 ----------文件夹改名
配置环境变量
# vi /etc/profile
在末尾追加
#Java environment
export JAVA_HOME=/usr/local/jdk1.6
export CLASSPATH=.:$JAVA_HOME/jre/lib:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar
export PATH=$JAVA_HOME/bin:$PATH
:wq保存退出。
# source /etc/profile -------------使配置生效
执行# java -version 命令,显示
java version "1.6.0_03"
Java(TM) SE Runtime Environment (build 1.6.0_03-b05)
Java HotSpot(TM) Client VM (build 1.6.0_03-b05, mixed mode, sharing)
2.安装ANT
下载apache-ant-1.7.0-bin.tar.gz
# tar zxvf apache-ant-1.7.0-bin.tar.gz
# mv apache-ant-1.7.0 /usr/local/
# mv apache-ant-1.7.0 ant
配置环境变量
# vi /etc/profile
在末尾追加
#Ant environment
export ANT_HOME=/usr/local/ant
export PATH=$ANT_HOME/bin:$PATH
:wq保存退出。
# source /etc/profile
执行ant -version命令,显示
Apache Ant version 1.7.0 compiled on December 13 2006
安装成功!
2.安装openfire
在http://www.igniterealtime.org/downloads/index.jsp#openfire上下载openfire-3.5.1-1.i386.rpm包
# rpm -ivh openfire-3.5.1-1.i386.rpm
默认安装在 /opt/openfire
# vi /etc/sysconfig/iptables
追加下面2行
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 9090 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 9091 -j ACCEPT
:wq保存退出后执行
# service iptables restart
可以使用下面的命令启动服务:
# /opt/openfire/bin/openfire.sh
或者用保存在/etc/init.d/下的openfire脚本启动服务,命令是/etc/init.d/openfire start
脚本如下:
#!/bin/sh
#
# openfire Stops and starts the Openfire XMPP service.
#
# chkconfig: 2345 99 1
# description: Openfire is an XMPP server, which is a server that facilitates \
# XML based communication, such as chat.
# config: /opt/openfire/conf/openfire.xml
# config: /etc/sysconfig/openfire
# pidfile: /var/run/openfire.pid
#
# This script has currently been tested on Redhat, CentOS, and Fedora based
# systems.
#
#####
# Begin setup work
#####
# Initialization
PATH="/sbin:/bin:/usr/bin:/usr/sbin"
RETVAL=0
# Check that we are root ... so non-root users stop here.
[ "`id -u`" = 0 ] || exit 1
# Get config.
[ -f "/etc/sysconfig/openfire" ] && . /etc/sysconfig/openfire
# If openfire user is not set in sysconfig, set to daemon.
[ -z "$OPENFIRE_USER" ] && OPENFIRE_USER="daemon"
# If pid file path is not set in sysconfig, set to /var/run/openfire.pid.
[ -z "$OPENFIRE_PIDFILE" ] && OPENFIRE_PIDFILE="/var/run/openfire.pid"
# -----------------------------------------------------------------
# If a openfire home variable has not been specified, try to determine it.
if [ -z "$OPENFIRE_HOME" -o ! -d "$OPENFIRE_HOME" ]; then
if [ -d "/usr/share/openfire" ]; then
OPENFIRE_HOME="/usr/share/openfire"
elif [ -d "/usr/local/openfire" ]; then
OPENFIRE_HOME="/usr/local/openfire"
elif [ -d "/opt/openfire" ]; then
OPENFIRE_HOME="/opt/openfire"
else
echo "Could not find Openfire installation under /opt, /usr/share, or /usr/local."
echo "Please specify the Openfire installation location as variable OPENFIRE_HOME"
echo "in /etc/sysconfig/openfire."
exit 1
fi
fi
# If log path is not set in sysconfig, set to $OPENFIRE_HOME/logs.
[ -z "$OPENFIRE_LOGDIR" ] && OPENFIRE_LOGDIR="${OPENFIRE_HOME}/logs"
# Attempt to locate java installation.
if [ -z "$JAVA_HOME" ]; then
if [ -d "${OPENFIRE_HOME}/jre" ]; then
JAVA_HOME="${OPENFIRE_HOME}/jre"
elif [ -d "/etc/alternatives/jre" ]; then
JAVA_HOME="/etc/alternatives/jre"
else
jdks=`ls -r1d /usr/java/j*`
for jdk in $jdks; do
if [ -f "${jdk}/bin/java" ]; then
JAVA_HOME="$jdk"
break
fi
done
fi
fi
JAVACMD="${JAVA_HOME}/bin/java"
if [ ! -d "$JAVA_HOME" -o ! -x "$JAVACMD" ]; then
echo "Error: JAVA_HOME is not defined correctly."
echo " Can not sure execute $JAVACMD."
exit 1
fi
# Prepare location of openfire libraries
OPENFIRE_LIB="${OPENFIRE_HOME}/lib"
# Prepare openfire command line
OPENFIRE_OPTS="${OPENFIRE_OPTS} -DopenfireHome=${OPENFIRE_HOME} -Dopenfire.lib.dir=${OPENFIRE_LIB}"
# Prepare local java class path
if [ -z "$LOCALCLASSPATH" ]; then
LOCALCLASSPATH="${OPENFIRE_LIB}/startup.jar"
else
LOCALCLASSPATH="${OPENFIRE_LIB}/startup.jar:${LOCALCLASSPATH}"
fi
# Export any necessary variables
#export JAVA_HOME JAVACMD
export JAVA_HOME=/usr/local/jdk1.6
export JAVACMD=/usr/local/jdk1.6/bin/java
# Lastly, prepare the full command that we are going to run.
OPENFIRE_RUN_CMD="${JAVACMD} -server ${OPENFIRE_OPTS} -classpath \"${LOCALCLASSPATH}\" -jar \"${OPENFIRE_LIB}/startup.jar\""
#####
# End setup work
#####
start() {
OLD_PWD=`pwd`
cd $OPENFIRE_LOGDIR
# Start daemons.
echo -n "Starting openfire: "
rm -f nohup.out
sudo su -s /bin/sh -c "nohup $OPENFIRE_RUN_CMD > $OPENFIRE_LOGDIR/nohup.out 2>&1 &" $OPENFIRE_USER
RETVAL=$?
PID=`ps ax --width=1000 | grep openfire | grep startup.jar | awk '{print $1}'`
if [ $RETVAL -eq 0 -a ! -z "$PID" -a ! -z "$OPENFIRE_PIDFILE" ]; then
echo $PID > $OPENFIRE_PIDFILE
fi
echo
[ $RETVAL -eq 0 -a -d /var/lock/subsys ] && touch /var/lock/subsys/openfire
sleep 1 # allows prompt to return
cd $OLD_PWD
}
stop() {
# Stop daemons.
echo -n "Shutting down openfire: "
[ -f "$OPENFIRE_PIDFILE" ] && kill `cat $OPENFIRE_PIDFILE`
RETVAL=$?
echo
[ $RETVAL -eq 0 -a -f "$OPENFIRE_PIDFILE" ] && rm -f $OPENFIRE_PIDFILE
[ $RETVAL -eq 0 -a -f "/var/lock/subsys/openfire" ] && rm -f /var/lock/subsys/openfire
}
restart() {
stop
sleep 10 # give it a few moments to shut down
start
}
condrestart() {
[ -e "/var/lock/subsys/openfire" ] && restart
return 0
}
status() {
pid=`cat $OPENFIRE_PIDFILE 2>&1`
if [ "$?" = "1" ]; then
echo "openfire is not running"
RETVAL=0
else
ps -p $pid > /dev/null 2>&1
if [ "$?" = "0" ]; then
echo "openfire is running"
RETVAL=0
else
echo "openfire is not running"
RETVAL=0
fi
fi
}
# Handle how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
condrestart)
condrestart
;;
reload)
restart
;;
status)
status
;;
*)
echo "Usage $0 {start|stop|restart|status|condrestart|reload}"
RETVAL=1
esac
exit $RETVAL
脚本到此结束。
设置为开机自启动
# chkconfig openfire on
# chkconfig --list openfire
openfire 0:关闭 1:关闭 2:启用 3:启用 4:启用 5:启用 6:关闭
设置成功!
接下来在浏览器中输入http://你的服务器的IP:9090即可开始即时通讯服务器配置
(1)语言选择:中文简体
(2)服务期设置:选择域及端口,建议默认
(3)数据库设置:根据需要,这里选“标准数据库”
(4)标准数据库设置:选择MySQL,数据库URL填入你的数据库地址,端口和数据库名称(请自行创建)用户名密码填入你的mysql的帐号密码,其他根据需要选择填写。继续之后会在你的mysql中创建表并初始化。
(5)特性设置:如果你不打算用LDAP,保留默认
(6)管理员帐户设置:填入系统管理员信息
(7)安装完成
至此,Openfire安装完毕。你可以继续登录到管理控制台,进行更为详细的设置。
服务器到此安装完成。建议客户端在windows上使用spark,因为Spark和Openfire能够很好的相互支持,是黄金组合。
下载地址:http://www.igniterealtime.org/downloads/index.jsp#spark
安装比较简单,安装完成后就可以注册-->登录-->使用了。挺不错的开源聊天软件。
3. 安装Red5
下载Red5的安装文件,下载地址:http://osflash.org/red5
# tar zxvf red5-0.6.3.tar.gz
# cd red5-0.6.3
# ant
编译完后把dist文件夹内的文件copy到 /var/www/red5 文件夹下。
# vi /etc/sysconfig/iptables
开放端口,添加以下内容:
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 1935 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 1936 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 1945 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 5080 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 8088 -j ACCEPT
# /etc/rc.d/init.d/iptables restart
重启防火墙
#cd /var/www/red5
# ./red5.sh &
启动服务
可以访问http://ip:5080。
安装完成。
http://www.javaeye.com/topic/212656
2008年10月26日星期日
phpbb3 用户同步的想法
1. 需要考虑已有用户的同步问题,已有用户的密码采用了md5加密。
2. 注册时,将新用户的密码md5加密后,再送给phpbb3注册
3. 登录时,判断该用户是否在phpbb3中,假如没有则自动同步。
4. 修改phpbb3的注册入口到当前主站的注册入口
5. 修改phpbb3的用户登录入口,需要将用户输入的密码进行md5加密后,再送给phpbb3验证
6. 修改phpbb3的用户修改密码入口,到主站的修改密码入口。
http://www.gnuedu.org/view/printview-23.html
2. 注册时,将新用户的密码md5加密后,再送给phpbb3注册
3. 登录时,判断该用户是否在phpbb3中,假如没有则自动同步。
4. 修改phpbb3的注册入口到当前主站的注册入口
5. 修改phpbb3的用户登录入口,需要将用户输入的密码进行md5加密后,再送给phpbb3验证
6. 修改phpbb3的用户修改密码入口,到主站的修改密码入口。
http://www.gnuedu.org/view/printview-23.html
2008年10月16日星期四
Flex Mp3 Player
1. http://axel.cfwebtools.com/index.cfm/2007/10/18/Open-source-flex-xml-mp3-player
2. http://ntt.cc/2008/02/19/a-small-open-source-flash-mp3-player.html
3. http://www.lemlinh.com/flash-source-as-30-xml-mp3-player
2. http://ntt.cc/2008/02/19/a-small-open-source-flash-mp3-player.html
3. http://www.lemlinh.com/flash-source-as-30-xml-mp3-player
2008年10月9日星期四
P2P Video on JXTA study (add google talk , Libjingle, XMPP)
1. 下载 jxta 2.5.2版本
2. 服务端的采用何种形式部署?
3. 客户端采用swing的形式,还是applet的形式,还是flash的形式?
4. 普通用户,管理员用户,高级用户
5. 阶段性目标
5.1 服务端运行
5.2 客户端运行
5.3 客户端和服务端通讯,并且登陆成功。
5.4 多用户登陆,查看在线用户。 在线/离开/掉线/隐身/忙碌/勿扰
5.5 文字聊天
5.6 收听语音节目
5.7 收看视频节目
5.8 建立语音聊天室 (高级用户)
5.9 建立视频聊天室 (高级用户)
5.10 普通用户加入语音聊天室
5.11 普通用户语音聊天
5.12 普通用户加入视频聊天室
5.13 普通用户视频聊天
5.14 共享文件夹
5.15 分布式搜索共享文件夹
参考文章:
http://technica.blogbus.com/logs/15909321.html
http://www.cnblogs.com/jobs/archive/2007/03/25.html
http://sourceforge.net/projects/activex
http://osflash.org/red5/linux-install
http://www.linuxidc.com/Linux/2008-04/12293.htm
http://soft.zdnet.com.cn/software_zone/2007/1009/543087.shtml
http://www.d5power.com/thread-35-1-1.html
http://blog.zol.com.cn/779/article_778677.html
http://xinsync.xju.edu.cn/index.php/archives/2656#more-2656
-- Performance Issue: just extend the class MultiThreadedApplicationAdapter instead of the previous ApplicationAdapter and make sure your code is thread-safe
http://xinsync.xju.edu.cn/index.php/archives/2284#more-2284
-- 直接修改得到一个版本?
XMPP for flex <-- client
XMPP wildfire (java) <-- server
1. http://blog.csdn.net/rongjch/archive/2006/04/20/670721.aspx
2. http://hi.baidu.com/jabber/blog/category/Wildfire
3. http://www.xiongcaocao.com/yaotian/diary/122
使用wildfire和linq在一个客户端整合QQ,MSN,Gtalk。
1. http://www.jivesoftware.org/ 感谢jive提供了如此优秀的xmpp服务端和客户端库文件。
2. http://www.google.com/talk/intl/zh-CN/ 感谢gtalk对xmpp协议的支持。
3. http://linq.sourceforge.net/ 非常优秀的xmpp客户端。
4. http://lumaqq.linuxsir.org/main/ 超级出色的纯java的qq客户端。
5.http://hi.baidu.com/jabber 一个很不错的关于xmpp的blog。
http://wangcheng.javaeye.com/blog/153548
Flex2基于XMPP的chat程序(二)
暂定框架
1. 目标。
20个视频聊天室
1个公共文字聊天室
1.1. 公共文字聊天室
所有人群聊,直接滚屏即可。
1.2. 视频聊天室
1个主持人。
1个视频双向直连观众 第一梯队
2个声频直连观众 第二梯队
1 http://www.javaeye.com/topic/154697
构建 基于openfire + jwchat 的 WEB IM
2. http://code.google.com/p/xmpphp/
3. http://fairyfish.net/2008/08/28/xmpphp/
4. http://wiki.jabber.org/web/Bidirectional-streams_Over_Synchronous_HTTP_(BOSH)_(XEP-0124)
2. 服务端的采用何种形式部署?
3. 客户端采用swing的形式,还是applet的形式,还是flash的形式?
4. 普通用户,管理员用户,高级用户
5. 阶段性目标
5.1 服务端运行
5.2 客户端运行
5.3 客户端和服务端通讯,并且登陆成功。
5.4 多用户登陆,查看在线用户。 在线/离开/掉线/隐身/忙碌/勿扰
5.5 文字聊天
5.6 收听语音节目
5.7 收看视频节目
5.8 建立语音聊天室 (高级用户)
5.9 建立视频聊天室 (高级用户)
5.10 普通用户加入语音聊天室
5.11 普通用户语音聊天
5.12 普通用户加入视频聊天室
5.13 普通用户视频聊天
5.14 共享文件夹
5.15 分布式搜索共享文件夹
参考文章:
http://technica.blogbus.com/logs/15909321.html
http://www.cnblogs.com/jobs/archive/2007/03/25.html
http://sourceforge.net/projects/activex
http://osflash.org/red5/linux-install
http://www.linuxidc.com/Linux/2008-04/12293.htm
http://soft.zdnet.com.cn/software_zone/2007/1009/543087.shtml
http://www.d5power.com/thread-35-1-1.html
http://blog.zol.com.cn/779/article_778677.html
http://xinsync.xju.edu.cn/index.php/archives/2656#more-2656
-- Performance Issue: just extend the class MultiThreadedApplicationAdapter instead of the previous ApplicationAdapter and make sure your code is thread-safe
http://xinsync.xju.edu.cn/index.php/archives/2284#more-2284
-- 直接修改得到一个版本?
XMPP for flex <-- client
XMPP wildfire (java) <-- server
1. http://blog.csdn.net/rongjch/archive/2006/04/20/670721.aspx
2. http://hi.baidu.com/jabber/blog/category/Wildfire
3. http://www.xiongcaocao.com/yaotian/diary/122
使用wildfire和linq在一个客户端整合QQ,MSN,Gtalk。
1. http://www.jivesoftware.org/ 感谢jive提供了如此优秀的xmpp服务端和客户端库文件。
2. http://www.google.com/talk/intl/zh-CN/ 感谢gtalk对xmpp协议的支持。
3. http://linq.sourceforge.net/ 非常优秀的xmpp客户端。
4. http://lumaqq.linuxsir.org/main/ 超级出色的纯java的qq客户端。
5.http://hi.baidu.com/jabber 一个很不错的关于xmpp的blog。
http://wangcheng.javaeye.com/blog/153548
Flex2基于XMPP的chat程序(二)
暂定框架
1. 目标。
20个视频聊天室
1个公共文字聊天室
1.1. 公共文字聊天室
所有人群聊,直接滚屏即可。
1.2. 视频聊天室
1个主持人。
1个视频双向直连观众 第一梯队
2个声频直连观众 第二梯队
1 http://www.javaeye.com/topic/154697
构建 基于openfire + jwchat 的 WEB IM
2. http://code.google.com/p/xmpphp/
3. http://fairyfish.net/2008/08/28/xmpphp/
4. http://wiki.jabber.org/web/Bidirectional-streams_Over_Synchronous_HTTP_(BOSH)_(XEP-0124)
2008年10月2日星期四
ouxunsi视频网站搭建
1. 确认登录服务器没有问题。[ok 20080909]
1.1 服务器上已经存在的服务分析
----------------------------------------
# netstat -an | grep -e "LISTEN"
tcp 0 0 0.0.0.0:905 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN <-- mysql服务
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:6000 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN <-- ftp服务
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
tcp 0 0 ::ffff:127.0.0.1:8005 :::* LISTEN
tcp 0 0 :::8009 :::* LISTEN
tcp 0 0 :::80 :::* LISTEN <-- http服务
tcp 0 0 :::6000 :::* LISTEN
tcp 0 0 :::22 :::* LISTEN <-- ssh服务
unix 2 [ ACC ] STREAM LISTENING 8533 /var/run/xdmctl/dmctl/socket
unix 2 [ ACC ] STREAM LISTENING 8565 /var/run/xdmctl/dmctl-:0/socket
unix 2 [ ACC ] STREAM LISTENING 7071 /tmp/mysql.sock
unix 2 [ ACC ] STREAM LISTENING 6575 /var/run/dbus/system_bus_socket
unix 2 [ ACC ] STREAM LISTENING 6505 /tmp/.font-unix/fs7100
unix 2 [ ACC ] STREAM LISTENING 8560 /tmp/.X11-unix/X0
unix 2 [ ACC ] STREAM LISTENING 6367 /dev/gpmctl
unix 2 [ ACC ] STREAM LISTENING 6059 /var/run/acpid.socket
unix 2 [ ACC ] STREAM LISTENING 6452 /var/run/iiim/.iiimp-unix/9010
----------------------------------------
1.2 已经存在的相关应用分析
java version "1.5.0_07" 安装位置 /usr/java/jdk1.5.0_07
apache-tomcat-6.0.10 安装位置 /usr/apache-tomcat-6.0.10
mysql Ver 14.12 Distrib 5.0.45 安装位置 /usr/mysql-5.0.45-linux-i686
gcc version 3.4.6 20060404 (Red Hat 3.4.6-9)
----------------------------------------
# ps -ef | grep -e "java"
root 4254 1 0 Jul29 ? 12:17:31 /usr/java/jdk1.5.0_07/bin/java -
Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.log
ging.config.file=/usr/apache-tomcat-6.0.10/conf/logging.properties -server -XX:P
ermSize=64M -XX:MaxPermSize=128M -Djava.endorsed.dirs=/usr/apache-tomcat-6.0.10/
endorsed -classpath :/usr/apache-tomcat-6.0.10/bin/bootstrap.jar:/usr/apache-tom
cat-6.0.10/bin/commons-logging-api.jar -Dcatalina.base=/usr/apache-tomcat-6.0.10
-Dcatalina.home=/usr/apache-tomcat-6.0.10 -Djava.io.tmpdir=/usr/apache-tomcat-6
.0.10/temp org.apache.catalina.startup.Bootstrap start
# gcc -v
Reading specs from /usr/lib/gcc/x86_64-redhat-linux/3.4.6/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/u
sr/share/info --enable-shared --enable-threads=posix --disable-checking --with-s
ystem-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-java-aw
t=gtk --host=x86_64-redhat-linux
Thread model: posix
gcc version 3.4.6 20060404 (Red Hat 3.4.6-9)
# java -version
java version "1.5.0_07"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-b03)
Java HotSpot(TM) Client VM (build 1.5.0_07-b03, mixed mode)
# /usr/mysql-5.0.45-linux-i686/bin/mysql -V
/usr/mysql-5.0.45-linux-i686/bin/mysql Ver 14.12 Distrib 5.0.45, for pc-linux-g
nu (i686) using readline 5.0
----------------------------------------
2. 安装apache服务器,测试index.html [ok 20081003]
2.0 安装Apache日志截断程序cronolog
wget -c wget http://cronolog.org/download/cronolog-1.6.2.tar.gz
tar -zxvf cronolog-1.6.2.tar.gz
cd cronolog-1.6.2
./configure --prefix=/usr/ouxunsi/video/install/cronolog
make
make install
2.1 下载
wget -c http://apache.freelamp.com/httpd/httpd-2.2.9.tar.gz
2.2 解压缩,配置,编译,安装
tar -zxvf httpd-2.2.9.tar.gz
cd httpd-2.2.9
./configure \
--prefix=/usr/ouxunsi/video/install/apache2 \
--enable-so \
--enable-rewrite=static \
--enable-cache \
--enable-file-cache \
--enable-mem-cache \
--enable-disk-cache \
--enable-static-support \
--enable-static-htpasswd \
--enable-static-htdigest \
--enable-static-rotatelogs \
--enable-static-logresolve \
--enable-static-htdbm \
--enable-static-ab \
--enable-static-checkgid \
--disable-cgid \
--disable-cgi
========================================
编译配置说明
./configure //配置源代码树
--prefix=/usr/ouxunsi/video/install/apache2 //体系无关文件的顶级安装目录PREFIX ,也就Apache的安装目录。
--enable-so //打开 so 模块,so 模块是用来提 DSO 支持的 apache 核心模块
--enable-rewrite=static //打开rewrite 功能模块
--enable-mods-shared=all //编译全部的模板,对于不需要我们可以在httpd.conf去掉。这个选项打开可能会需要有更多的依赖库,在这里可以去掉
--enable-cache //支持缓存
--enable-file-cache //支持文件缓存
--enable-mem-cache //支持记忆缓存
--enable-disk-cache //支持磁盘缓存
--enable-static-support //支持静态连接(默认为动态连接)
--enable-static-htpasswd //使用静态连接编译 htpasswd - 管理用于基本认证的用户文件
--enable-static-htdigest //使用静态连接编译 htdigest - 管理用于摘要认证的用户文件
--enable-static-rotatelogs //使用静态连接编译 rotatelogs - 滚动 Apache 日志的管道日志程序
--enable-static-logresolve //使用静态连接编译 logresolve - 解析 Apache 日志中的IP地址为主机名
--enable-static-htdbm //使用静态连接编译 htdbm - 操作 DBM 密码数据库
--enable-static-ab //使用静态连接编译 ab - Apache HTTP 服务器性能测试工具
--enable-static-checkgid //使用静态连接编译 checkgid
--disable-cgid //禁止用一个外部 CGI 守护进程执行CGI脚本
--disable-cgi //禁止编译 CGI 版本的 PHP
--enable-ssl // 编译 ssl模块。这个选项打开可能需要更多的依赖库,在这里可以去掉
=============================
make
make install
2.3 配置apache2的端口和根目录
cd /usr/ouxunsi/video/install/apache2
cp conf/httpd.conf conf/httpd.conf.20081003
vi conf/httpd.conf
==========================================
Listen 80 --> Listen 8080
DirectoryIndex index.html --> DirectoryIndex index.php index.html
DocumentRoot "/usr/ouxunsi/video/install/apache2/htdocs" --> DocumentRoot "/usr/ouxunsi/video/htdocs"
-->
==========================================
2.4 配置cronolog日志截断程序
vi conf/httpd.conf
==========================================
CustomLog "logs/access_log" common
-->
CustomLog "|/usr/ouxunsi/video/install/cronolog/sbin/cronolog /usr/ouxunsi/v
ideo/install/apache2/logs/access_log.%Y%m%d" combined
==========================================
3. 安装php环境,测试phpinfo.php (应该在安装完 mysql 之后安装)
3.0 需要lib-xml2
wget -c ftp://ftp.pbone.net/mirror/www.startcom.org/AS-4.0.0/updates/x86_64/zlib-devel-1.2.1.2-1.2.x86_64.rpm
wget -c ftp://ftp.pbone.net/mirror/www.startcom.org/AS-4.0.0/os/x86_64/StartCom/RPMS/libxml2-devel-2.6.16-6.x86_64.rpm
rpm -i libxml2-devel-2.6.16-6.x86_64.rpm zlib-devel-1.2.1.2-1.2.x86_64.rpm
3.1 下载
wget -c http://cn.php.net/get/php-5.2.6.tar.gz/from/this/mirror
3.2 解压缩,编译,安装
tar -zxvf php-5.2.6.tar.gz
cd php-5.2.6
ln -sf libjpeg.so.62.0.0 libjpeg.so
ln -sf libpng.so.3.1.2.7 libpng.so
./configure \
--prefix=/usr/ouxunsi/video/install/php5 \
--with-apxs2=/usr/ouxunsi/video/install/apache2/bin/apxs \
--with-mysql=/usr/ouxunsi/video/install/mysql5 \
--disable-debug \
--with-zlib \
--enable-mbstring \
--with-gd \
--with-jpeg-dir \
--with-png-dir \
--enable-fastcgi \
--with-config-file-scan-dir=/usr/ouxunsi/video/install/php5/etc/php \
--with-mysqli=/usr/ouxunsi/video/install/mysql5/bin/mysql_config
make
make test
make install
cp php.ini-dist /usr/ouxunsi/video/install/php5/etc/php/php.ini
3.3 整合php和apache2
#make install 会自动修改http.conf 加上 LoadModule php5_module modules/libphp5.so
只需要在最后一行加上:
AddType application/x-httpd-php .php
或者更加安全的:
SetHandler application/x-httpd-php
4. 安装mysql服务器
4.0 需要安装g++ 和 ncurse-devel
wget -c ftp://mirror.switch.ch/pool/3/mirror/centos/4.6/os/x86_64/CentOS/RPMS/gcc-c++-3.4.6-9.x86_64.rpm
wget -c ftp://mirror.switch.ch/pool/3/mirror/centos/4.6/os/x86_64/CentOS/RPMS/libstdc++-devel-3.4.6-9.x86_64.rpm
wget -c ftp://mirror.switch.ch/pool/3/mirror/centos/4.6/os/x86_64/CentOS/RPMS/libstdc++-3.4.6-9.x86_64.rpm
wget -c ftp://ftp.chg.ru/pub/Linux/scientific/41/x86_64/SL/RPMS/ncurses-devel-5.4-13.x86_64.rpm
rpm -i gcc-c++-3.4.6-9.x86_64.rpm libstdc++-devel-3.4.6-9.x86_64.rpm libstdc++-3.4.6-9.x86_64.rpm ncurses-devel-5.4-13.x86_64.rpm
4.1 已经存在了一个mysql5数据库,需要注意修改端口号和相关的目录。不需要重复增加mysql用户帐号了。
wget -c http://mysql.mirror.rafal.ca/Downloads/MySQL-5.0/mysql-5.0.67.tar.gz
cd /usr/ouxunsi/video/download/mysql-5.0.67
mkdir /usr/ouxunsi/video/install/mysql5
mkdir /usr/ouxunsi/video/var/lib/mysql5
./configure \
--prefix=/usr/ouxunsi/video/install/mysql5 \
--localstatedir=/usr/ouxunsi/video/var/lib/mysql5 \
--with-comment=Source \
--with-server-suffix=-Community \
--with-mysqld-user=mysql \
--without-debug \
--with-big-tables \
--with-charset=utf8 \
--with-collation=utf8_unicode_ci \
--with-extra-charsets=all \
--with-pthread \
--enable-static \
--enable-thread-safe-client \
--with-client-ldflags=-all-static \
--with-mysqld-ldflags=-all-static \
--enable-assembler \
--without-innodb \
--without-ndb-debug
make
make install
cd /usr/ouxunsi/video/install/mysql5
#useradd mysql //添加 mysql 用户,已经存在,所以不用重复添加
./bin/mysql_install_db --user=mysql
chown -R root:mysql .
chown -R mysql /usr/ouxunsi/video/var/lib/mysql5
chgrp -R mysql .
cp share/mysql/my-huge.cnf .
vi my-huge.cnf
==========================================
port: 3306 --> 3307 两个地方
socket: /tmp/mysql.sock --> /tmp/mysqlvideo.sock 两个地方
==========================================
cp share/mysql/mysql.server /etc/rc.d/init.d/mysqlvideo
vi /etc/rc.d/init.d/mysqlvideo
==========================================
datadir=/var/lib/mysql5
conf=/usr/ouxunsi/video/install/mysql5/my-huge.cnf
把"$bindir/mysqld_safe --datadir=$datadir --pid-file=$server_pid_file $other_args >/dev/null 2>&1 &"替换为(双引号中的)
"$bindir/mysqld_safe --defaults-file=/usr/ouxunsi/video/install/mysql5/my-huge.cnf --datadir=$datadir --pid-file=$server_pid_file $other_args >/dev/null 2>&1 &"(双引号中的)
==========================================
chmod 755 /etc/rc.d/init.d/mysqlvideo
chkconfig --add mysqlvideo
4.2 启动数据库
/etc/rc.d/init.d/mysqlvideo start
4.3 修改root用户密码
./bin/mysql -u root -S /tmp/mysqlvideo.sock
======================================================
mysql> use mysql
mysql> update user set password=password('video') where user='root';
mysql> FLUSH PRIVILEGES;
======================================================
4.4 停止数据库运行
/etc/rc.d/init.d/mysqlvideo stop
5. 安装svn服务器,是否可以提供密码保护(使用svn+ssh实现)
5.0 需要expat-devel neon等库
wget -c ftp://ftp.pbone.net/mirror/www.startcom.org/AS-4.0.0/os/x86_64/StartCom/RPMS/expat-devel-1.95.7-4.x86_64.rpm
rpm -i expat-devel-1.95.7-4.x86_64.rpm
wget -c ftp://ftp.pbone.net/mirror/www.startcom.org/AS-4.0.0/os/x86_64/StartCom/RPMS/neon-devel-0.24.7-4.x86_64.rpm
wget -c http://ftp.riken.go.jp/Linux/cern/slc41/updates/x86_64/RPMS/openssl-devel-0.9.7a-43.10.x86_64.rpm
wget -c http://ftp.riken.go.jp/Linux/cern/slc41/updates/x86_64/RPMS/krb5-devel-1.3.4-33.x86_64.rpm
wget -c http://ftp.riken.go.jp/Linux/cern/slc41/updates/x86_64/RPMS/e2fsprogs-devel-1.35-12.4.EL4.x86_64.rpm
rpm -i neon-devel-0.24.7-4.x86_64.rpm openssl-devel-0.9.7a-43.10.x86_64.rpm krb5-devel-1.3.4-33.x86_64.rpm e2fsprogs-devel-1.35-12.4.EL4.x86_64.rpm
5.1 下载svn源代码
wget -c http://subversion.tigris.org/downloads/subversion-1.5.2.tar.gz
tar -zxvf subversion-1.5.2.tar.gz
cd subversion-1.5.2
./configure --with-apr=/usr/ouxunsi/video/install/apache2 \
--with-apr-util=/usr/ouxunsi/video/install/apache2 \
--prefix=/usr/ouxunsi/video/install/subversion \
--with-ssl \
--with-neon=/usr
make
make install
5.2 创建代码库
cd /usr/ouxunsi/video/
mkdir svnroot
cd svnroot
svnadmin create .
5.3 增加一个软链接到svnserve 从而可以使用 svn+ssh
ln -s /usr/ouxunsi/video/install/subversion/bin/svnserve /usr/bin/svnserve
svn checkout svn+ssh://root@xxx.xxx.xxx.xxx/usr/ouxunsi/video/svnroot .
6. 安装web ftp服务器
6.1 下载安装
wget -c ftp://ftp.proftpd.org/distrib/source/proftpd-1.3.1.tar.gz
tar -zxvf proftpd-1.3.1.tar.gz
cd proftpd-1.3.1
mkdir /usr/ouxunsi/video/install/proftpd
mkdir /usr/ouxunsi/video/install/proftpd/etc
./configure --prefix=/usr/ouxunsi/video/install/proftpd \
--sysconfdir=/usr/ouxunsi/video/install/proftpd/etc
make
make install
6.2 配置proftpd.conf
cd /usr/ouxunsi/video/install/proftpd/etc
cp proftpd.conf proftpd.conf.20081010
vi proftpd.conf
====================================================
Port 21 --> Port 8021
Group nogroup --> Group nobody
注释所有Anonymous部分
在最后增加如下行,定义虚拟用户和目录权限
RequireValidShell off
AuthOrder mod_auth_file.c
AuthUserFile /usr/ouxunsi/video/install/proftpd/etc/passwd
AuthGroupFile /usr/ouxunsi/video/install/proftpd/etc/group
SystemLog /usr/ouxunsi/video/var/proftpd.log
AllowGroup editor
====================================================
cp /usr/ouxunsi/video/download/proftpd-1.3.1/contrib/ftpasswd .
./ftpasswd --passwd --file /usr/ouxunsi/video/install/proftpd/etc/passwd --name=editor01 --uid=2001 --home=/usr/ouxunsi/video/htdocs --shell=/bin/false
./ftpasswd --group --name=editor --gid=2001 --file /usr/ouxunsi/video/install/proftpd/etc/group
./ftpasswd --passwd --file /usr/ouxunsi/video/install/proftpd/etc/passwd --name=ftpupload --uid=2001 --home=/usr/ouxunsi/video/ftpupload --shell=/bin/false
./ftpasswd --passwd --file /usr/ouxunsi/video/install/proftpd/etc/passwd --name=editor01 --uid=99 --gid=99 --home=/usr/ouxunsi/video/htdocs --shell=/bin/false
./ftpasswd --passwd --file /usr/ouxunsi/video/install/proftpd/etc/passwd --name=ftpupload --uid=99 --gid=99 --home=/usr/ouxunsi/video/ftpupload --shell=/bin/false
./ftpasswd --passwd --file /usr/ouxunsi/video/install/proftpd/etc/passwd --name=ftpupload --uid=2 --gid=2 --home=/usr/ouxunsi/video/ftpupload --shell=/bin/false
<-- 因为apache httpd2默认的用户名为daemon,所以需要用同样的,从而避免权限问题。
chown -R nobody:nobody /usr/ouxunsi/video/htdocs
chmod -R 777 /usr/ouxunsi/video/htdocs
6.3 配置启动脚本
cp /usr/ouxunsi/video/download/proftpd-1.3.1/contrib/dist/rpm/proftpd.init.d /usr/ouxunsi/video/install/proftpd
vi /usr/ouxunsi/video/install/proftpd/proftpd.init.d
===========================================
PATH="$PATH:/usr/local/sbin" --> PATH="$PATH:/usr/ouxunsi/video/install/proftpd/sbin"
===========================================
参考文章:
[01] http://www.centoschina.com/read.php?tid-9692.html
centos 5.0 编译安装apache 2.2.6+php5.2.5+mysql5.0.46+Zend笔记
[02] http://www.javaeye.com/topic/203986
Linux下两个不同版本Mysql的安装实战(Mysql5和mysql4)
[03] http://203.208.37.104/search?q=cache:61JaO2KxL5gJ:bbs.dadipedia.com/showthread.php%3Ft%3D24+subversion+%E7%BC%96%E8%AF%91+with-neon+with-ssl&hl=zh-CN&ct=clnk&cd=1&gl=cn&st_usg=ALhdy292DtxQYGhYxFtJKeHaST1h_1KwNA
LAMP, Trac, SQLite3, SubVersion 编译参数
1.1 服务器上已经存在的服务分析
----------------------------------------
# netstat -an | grep -e "LISTEN"
tcp 0 0 0.0.0.0:905 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN <-- mysql服务
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:6000 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN <-- ftp服务
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
tcp 0 0 ::ffff:127.0.0.1:8005 :::* LISTEN
tcp 0 0 :::8009 :::* LISTEN
tcp 0 0 :::80 :::* LISTEN <-- http服务
tcp 0 0 :::6000 :::* LISTEN
tcp 0 0 :::22 :::* LISTEN <-- ssh服务
unix 2 [ ACC ] STREAM LISTENING 8533 /var/run/xdmctl/dmctl/socket
unix 2 [ ACC ] STREAM LISTENING 8565 /var/run/xdmctl/dmctl-:0/socket
unix 2 [ ACC ] STREAM LISTENING 7071 /tmp/mysql.sock
unix 2 [ ACC ] STREAM LISTENING 6575 /var/run/dbus/system_bus_socket
unix 2 [ ACC ] STREAM LISTENING 6505 /tmp/.font-unix/fs7100
unix 2 [ ACC ] STREAM LISTENING 8560 /tmp/.X11-unix/X0
unix 2 [ ACC ] STREAM LISTENING 6367 /dev/gpmctl
unix 2 [ ACC ] STREAM LISTENING 6059 /var/run/acpid.socket
unix 2 [ ACC ] STREAM LISTENING 6452 /var/run/iiim/.iiimp-unix/9010
----------------------------------------
1.2 已经存在的相关应用分析
java version "1.5.0_07" 安装位置 /usr/java/jdk1.5.0_07
apache-tomcat-6.0.10 安装位置 /usr/apache-tomcat-6.0.10
mysql Ver 14.12 Distrib 5.0.45 安装位置 /usr/mysql-5.0.45-linux-i686
gcc version 3.4.6 20060404 (Red Hat 3.4.6-9)
----------------------------------------
# ps -ef | grep -e "java"
root 4254 1 0 Jul29 ? 12:17:31 /usr/java/jdk1.5.0_07/bin/java -
Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.log
ging.config.file=/usr/apache-tomcat-6.0.10/conf/logging.properties -server -XX:P
ermSize=64M -XX:MaxPermSize=128M -Djava.endorsed.dirs=/usr/apache-tomcat-6.0.10/
endorsed -classpath :/usr/apache-tomcat-6.0.10/bin/bootstrap.jar:/usr/apache-tom
cat-6.0.10/bin/commons-logging-api.jar -Dcatalina.base=/usr/apache-tomcat-6.0.10
-Dcatalina.home=/usr/apache-tomcat-6.0.10 -Djava.io.tmpdir=/usr/apache-tomcat-6
.0.10/temp org.apache.catalina.startup.Bootstrap start
# gcc -v
Reading specs from /usr/lib/gcc/x86_64-redhat-linux/3.4.6/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/u
sr/share/info --enable-shared --enable-threads=posix --disable-checking --with-s
ystem-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-java-aw
t=gtk --host=x86_64-redhat-linux
Thread model: posix
gcc version 3.4.6 20060404 (Red Hat 3.4.6-9)
# java -version
java version "1.5.0_07"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-b03)
Java HotSpot(TM) Client VM (build 1.5.0_07-b03, mixed mode)
# /usr/mysql-5.0.45-linux-i686/bin/mysql -V
/usr/mysql-5.0.45-linux-i686/bin/mysql Ver 14.12 Distrib 5.0.45, for pc-linux-g
nu (i686) using readline 5.0
----------------------------------------
2. 安装apache服务器,测试index.html [ok 20081003]
2.0 安装Apache日志截断程序cronolog
wget -c wget http://cronolog.org/download/cronolog-1.6.2.tar.gz
tar -zxvf cronolog-1.6.2.tar.gz
cd cronolog-1.6.2
./configure --prefix=/usr/ouxunsi/video/install/cronolog
make
make install
2.1 下载
wget -c http://apache.freelamp.com/httpd/httpd-2.2.9.tar.gz
2.2 解压缩,配置,编译,安装
tar -zxvf httpd-2.2.9.tar.gz
cd httpd-2.2.9
./configure \
--prefix=/usr/ouxunsi/video/install/apache2 \
--enable-so \
--enable-rewrite=static \
--enable-cache \
--enable-file-cache \
--enable-mem-cache \
--enable-disk-cache \
--enable-static-support \
--enable-static-htpasswd \
--enable-static-htdigest \
--enable-static-rotatelogs \
--enable-static-logresolve \
--enable-static-htdbm \
--enable-static-ab \
--enable-static-checkgid \
--disable-cgid \
--disable-cgi
========================================
编译配置说明
./configure //配置源代码树
--prefix=/usr/ouxunsi/video/install/apache2 //体系无关文件的顶级安装目录PREFIX ,也就Apache的安装目录。
--enable-so //打开 so 模块,so 模块是用来提 DSO 支持的 apache 核心模块
--enable-rewrite=static //打开rewrite 功能模块
--enable-mods-shared=all //编译全部的模板,对于不需要我们可以在httpd.conf去掉。这个选项打开可能会需要有更多的依赖库,在这里可以去掉
--enable-cache //支持缓存
--enable-file-cache //支持文件缓存
--enable-mem-cache //支持记忆缓存
--enable-disk-cache //支持磁盘缓存
--enable-static-support //支持静态连接(默认为动态连接)
--enable-static-htpasswd //使用静态连接编译 htpasswd - 管理用于基本认证的用户文件
--enable-static-htdigest //使用静态连接编译 htdigest - 管理用于摘要认证的用户文件
--enable-static-rotatelogs //使用静态连接编译 rotatelogs - 滚动 Apache 日志的管道日志程序
--enable-static-logresolve //使用静态连接编译 logresolve - 解析 Apache 日志中的IP地址为主机名
--enable-static-htdbm //使用静态连接编译 htdbm - 操作 DBM 密码数据库
--enable-static-ab //使用静态连接编译 ab - Apache HTTP 服务器性能测试工具
--enable-static-checkgid //使用静态连接编译 checkgid
--disable-cgid //禁止用一个外部 CGI 守护进程执行CGI脚本
--disable-cgi //禁止编译 CGI 版本的 PHP
--enable-ssl // 编译 ssl模块。这个选项打开可能需要更多的依赖库,在这里可以去掉
=============================
make
make install
2.3 配置apache2的端口和根目录
cd /usr/ouxunsi/video/install/apache2
cp conf/httpd.conf conf/httpd.conf.20081003
vi conf/httpd.conf
==========================================
Listen 80 --> Listen 8080
DirectoryIndex index.html --> DirectoryIndex index.php index.html
DocumentRoot "/usr/ouxunsi/video/install/apache2/htdocs" --> DocumentRoot "/usr/ouxunsi/video/htdocs"
==========================================
2.4 配置cronolog日志截断程序
vi conf/httpd.conf
==========================================
CustomLog "logs/access_log" common
-->
CustomLog "|/usr/ouxunsi/video/install/cronolog/sbin/cronolog /usr/ouxunsi/v
ideo/install/apache2/logs/access_log.%Y%m%d" combined
==========================================
3. 安装php环境,测试phpinfo.php (应该在安装完 mysql 之后安装)
3.0 需要lib-xml2
wget -c ftp://ftp.pbone.net/mirror/www.startcom.org/AS-4.0.0/updates/x86_64/zlib-devel-1.2.1.2-1.2.x86_64.rpm
wget -c ftp://ftp.pbone.net/mirror/www.startcom.org/AS-4.0.0/os/x86_64/StartCom/RPMS/libxml2-devel-2.6.16-6.x86_64.rpm
rpm -i libxml2-devel-2.6.16-6.x86_64.rpm zlib-devel-1.2.1.2-1.2.x86_64.rpm
3.1 下载
wget -c http://cn.php.net/get/php-5.2.6.tar.gz/from/this/mirror
3.2 解压缩,编译,安装
tar -zxvf php-5.2.6.tar.gz
cd php-5.2.6
ln -sf libjpeg.so.62.0.0 libjpeg.so
ln -sf libpng.so.3.1.2.7 libpng.so
./configure \
--prefix=/usr/ouxunsi/video/install/php5 \
--with-apxs2=/usr/ouxunsi/video/install/apache2/bin/apxs \
--with-mysql=/usr/ouxunsi/video/install/mysql5 \
--disable-debug \
--with-zlib \
--enable-mbstring \
--with-gd \
--with-jpeg-dir \
--with-png-dir \
--enable-fastcgi \
--with-config-file-scan-dir=/usr/ouxunsi/video/install/php5/etc/php \
--with-mysqli=/usr/ouxunsi/video/install/mysql5/bin/mysql_config
make
make test
make install
cp php.ini-dist /usr/ouxunsi/video/install/php5/etc/php/php.ini
3.3 整合php和apache2
#make install 会自动修改http.conf 加上 LoadModule php5_module modules/libphp5.so
只需要在最后一行加上:
AddType application/x-httpd-php .php
或者更加安全的:
SetHandler application/x-httpd-php
4. 安装mysql服务器
4.0 需要安装g++ 和 ncurse-devel
wget -c ftp://mirror.switch.ch/pool/3/mirror/centos/4.6/os/x86_64/CentOS/RPMS/gcc-c++-3.4.6-9.x86_64.rpm
wget -c ftp://mirror.switch.ch/pool/3/mirror/centos/4.6/os/x86_64/CentOS/RPMS/libstdc++-devel-3.4.6-9.x86_64.rpm
wget -c ftp://mirror.switch.ch/pool/3/mirror/centos/4.6/os/x86_64/CentOS/RPMS/libstdc++-3.4.6-9.x86_64.rpm
wget -c ftp://ftp.chg.ru/pub/Linux/scientific/41/x86_64/SL/RPMS/ncurses-devel-5.4-13.x86_64.rpm
rpm -i gcc-c++-3.4.6-9.x86_64.rpm libstdc++-devel-3.4.6-9.x86_64.rpm libstdc++-3.4.6-9.x86_64.rpm ncurses-devel-5.4-13.x86_64.rpm
4.1 已经存在了一个mysql5数据库,需要注意修改端口号和相关的目录。不需要重复增加mysql用户帐号了。
wget -c http://mysql.mirror.rafal.ca/Downloads/MySQL-5.0/mysql-5.0.67.tar.gz
cd /usr/ouxunsi/video/download/mysql-5.0.67
mkdir /usr/ouxunsi/video/install/mysql5
mkdir /usr/ouxunsi/video/var/lib/mysql5
./configure \
--prefix=/usr/ouxunsi/video/install/mysql5 \
--localstatedir=/usr/ouxunsi/video/var/lib/mysql5 \
--with-comment=Source \
--with-server-suffix=-Community \
--with-mysqld-user=mysql \
--without-debug \
--with-big-tables \
--with-charset=utf8 \
--with-collation=utf8_unicode_ci \
--with-extra-charsets=all \
--with-pthread \
--enable-static \
--enable-thread-safe-client \
--with-client-ldflags=-all-static \
--with-mysqld-ldflags=-all-static \
--enable-assembler \
--without-innodb \
--without-ndb-debug
make
make install
cd /usr/ouxunsi/video/install/mysql5
#useradd mysql //添加 mysql 用户,已经存在,所以不用重复添加
./bin/mysql_install_db --user=mysql
chown -R root:mysql .
chown -R mysql /usr/ouxunsi/video/var/lib/mysql5
chgrp -R mysql .
cp share/mysql/my-huge.cnf .
vi my-huge.cnf
==========================================
port: 3306 --> 3307 两个地方
socket: /tmp/mysql.sock --> /tmp/mysqlvideo.sock 两个地方
==========================================
cp share/mysql/mysql.server /etc/rc.d/init.d/mysqlvideo
vi /etc/rc.d/init.d/mysqlvideo
==========================================
datadir=/var/lib/mysql5
conf=/usr/ouxunsi/video/install/mysql5/my-huge.cnf
把"$bindir/mysqld_safe --datadir=$datadir --pid-file=$server_pid_file $other_args >/dev/null 2>&1 &"替换为(双引号中的)
"$bindir/mysqld_safe --defaults-file=/usr/ouxunsi/video/install/mysql5/my-huge.cnf --datadir=$datadir --pid-file=$server_pid_file $other_args >/dev/null 2>&1 &"(双引号中的)
==========================================
chmod 755 /etc/rc.d/init.d/mysqlvideo
chkconfig --add mysqlvideo
4.2 启动数据库
/etc/rc.d/init.d/mysqlvideo start
4.3 修改root用户密码
./bin/mysql -u root -S /tmp/mysqlvideo.sock
======================================================
mysql> use mysql
mysql> update user set password=password('video') where user='root';
mysql> FLUSH PRIVILEGES;
======================================================
4.4 停止数据库运行
/etc/rc.d/init.d/mysqlvideo stop
5. 安装svn服务器,是否可以提供密码保护(使用svn+ssh实现)
5.0 需要expat-devel neon等库
wget -c ftp://ftp.pbone.net/mirror/www.startcom.org/AS-4.0.0/os/x86_64/StartCom/RPMS/expat-devel-1.95.7-4.x86_64.rpm
rpm -i expat-devel-1.95.7-4.x86_64.rpm
wget -c ftp://ftp.pbone.net/mirror/www.startcom.org/AS-4.0.0/os/x86_64/StartCom/RPMS/neon-devel-0.24.7-4.x86_64.rpm
wget -c http://ftp.riken.go.jp/Linux/cern/slc41/updates/x86_64/RPMS/openssl-devel-0.9.7a-43.10.x86_64.rpm
wget -c http://ftp.riken.go.jp/Linux/cern/slc41/updates/x86_64/RPMS/krb5-devel-1.3.4-33.x86_64.rpm
wget -c http://ftp.riken.go.jp/Linux/cern/slc41/updates/x86_64/RPMS/e2fsprogs-devel-1.35-12.4.EL4.x86_64.rpm
rpm -i neon-devel-0.24.7-4.x86_64.rpm openssl-devel-0.9.7a-43.10.x86_64.rpm krb5-devel-1.3.4-33.x86_64.rpm e2fsprogs-devel-1.35-12.4.EL4.x86_64.rpm
5.1 下载svn源代码
wget -c http://subversion.tigris.org/downloads/subversion-1.5.2.tar.gz
tar -zxvf subversion-1.5.2.tar.gz
cd subversion-1.5.2
./configure --with-apr=/usr/ouxunsi/video/install/apache2 \
--with-apr-util=/usr/ouxunsi/video/install/apache2 \
--prefix=/usr/ouxunsi/video/install/subversion \
--with-ssl \
--with-neon=/usr
make
make install
5.2 创建代码库
cd /usr/ouxunsi/video/
mkdir svnroot
cd svnroot
svnadmin create .
5.3 增加一个软链接到svnserve 从而可以使用 svn+ssh
ln -s /usr/ouxunsi/video/install/subversion/bin/svnserve /usr/bin/svnserve
svn checkout svn+ssh://root@xxx.xxx.xxx.xxx/usr/ouxunsi/video/svnroot .
6. 安装web ftp服务器
6.1 下载安装
wget -c ftp://ftp.proftpd.org/distrib/source/proftpd-1.3.1.tar.gz
tar -zxvf proftpd-1.3.1.tar.gz
cd proftpd-1.3.1
mkdir /usr/ouxunsi/video/install/proftpd
mkdir /usr/ouxunsi/video/install/proftpd/etc
./configure --prefix=/usr/ouxunsi/video/install/proftpd \
--sysconfdir=/usr/ouxunsi/video/install/proftpd/etc
make
make install
6.2 配置proftpd.conf
cd /usr/ouxunsi/video/install/proftpd/etc
cp proftpd.conf proftpd.conf.20081010
vi proftpd.conf
====================================================
Port 21 --> Port 8021
Group nogroup --> Group nobody
注释所有Anonymous部分
在最后增加如下行,定义虚拟用户和目录权限
RequireValidShell off
AuthOrder mod_auth_file.c
AuthUserFile /usr/ouxunsi/video/install/proftpd/etc/passwd
AuthGroupFile /usr/ouxunsi/video/install/proftpd/etc/group
SystemLog /usr/ouxunsi/video/var/proftpd.log
AllowGroup editor
====================================================
cp /usr/ouxunsi/video/download/proftpd-1.3.1/contrib/ftpasswd .
./ftpasswd --passwd --file /usr/ouxunsi/video/install/proftpd/etc/passwd --name=editor01 --uid=2001 --home=/usr/ouxunsi/video/htdocs --shell=/bin/false
./ftpasswd --group --name=editor --gid=2001 --file /usr/ouxunsi/video/install/proftpd/etc/group
./ftpasswd --passwd --file /usr/ouxunsi/video/install/proftpd/etc/passwd --name=ftpupload --uid=2001 --home=/usr/ouxunsi/video/ftpupload --shell=/bin/false
./ftpasswd --passwd --file /usr/ouxunsi/video/install/proftpd/etc/passwd --name=editor01 --uid=99 --gid=99 --home=/usr/ouxunsi/video/htdocs --shell=/bin/false
./ftpasswd --passwd --file /usr/ouxunsi/video/install/proftpd/etc/passwd --name=ftpupload --uid=99 --gid=99 --home=/usr/ouxunsi/video/ftpupload --shell=/bin/false
./ftpasswd --passwd --file /usr/ouxunsi/video/install/proftpd/etc/passwd --name=ftpupload --uid=2 --gid=2 --home=/usr/ouxunsi/video/ftpupload --shell=/bin/false
<-- 因为apache httpd2默认的用户名为daemon,所以需要用同样的,从而避免权限问题。
chown -R nobody:nobody /usr/ouxunsi/video/htdocs
chmod -R 777 /usr/ouxunsi/video/htdocs
6.3 配置启动脚本
cp /usr/ouxunsi/video/download/proftpd-1.3.1/contrib/dist/rpm/proftpd.init.d /usr/ouxunsi/video/install/proftpd
vi /usr/ouxunsi/video/install/proftpd/proftpd.init.d
===========================================
PATH="$PATH:/usr/local/sbin" --> PATH="$PATH:/usr/ouxunsi/video/install/proftpd/sbin"
===========================================
参考文章:
[01] http://www.centoschina.com/read.php?tid-9692.html
centos 5.0 编译安装apache 2.2.6+php5.2.5+mysql5.0.46+Zend笔记
[02] http://www.javaeye.com/topic/203986
Linux下两个不同版本Mysql的安装实战(Mysql5和mysql4)
[03] http://203.208.37.104/search?q=cache:61JaO2KxL5gJ:bbs.dadipedia.com/showthread.php%3Ft%3D24+subversion+%E7%BC%96%E8%AF%91+with-neon+with-ssl&hl=zh-CN&ct=clnk&cd=1&gl=cn&st_usg=ALhdy292DtxQYGhYxFtJKeHaST1h_1KwNA
LAMP, Trac, SQLite3, SubVersion 编译参数
2008年9月24日星期三
2008年9月22日星期一
2008年9月21日星期日
中国移动WAP 2.0业务开发建议
1)必须是XHTML格式页面,不能是WML页面
这是WAP 2.0与WAP 1.X的根本区别之一。
2)必须限定页面大小,建议为5K~10K
虽然WAP 2.0协议栈的传输效率要高于WAP 1.X,但为了限制页面下载时间,提高业务可用性,保持良好的用户感受,必须对页面大小进行限定。
3)必须是彩色页面,使用图文混排功能
图文混排能极大的提高用户界面内操作的数量和方便程度,对于提高用户对于WAP 2.0业务的体验极为有效。
4)建议使用BANNAR功能,以方便用户返回到相应层次
例如:首页》掌中新闻》今日星闻
5)建议使用CSS样式表,来实现终端适配功能
对于WAP 2.0业务,终端适配的要求比WAP 1.X更高,而CSS样式表极大方便了SP终端适配的工作。
6)对于新闻咨询类应用,建议在使用大量文字时,使用背景色以增强用户感受,并区别于WAP1.X业务。
对于新闻咨询类应用,在页面布局上可能与WAP 1.X业务比较类似,都是按条排列,有上下翻页功能。为了区别与WAP 1.X业务,同时使得用户界面更加美观,建议在使用大量文字时,使用背景色以增强用户感受。
7)对于图铃下载类应用,建议可以直接点击预览图片来下载相应图片
WAP2.0支持图片链接,对于图片下载业务,可以通过直接点击图片的方式来下载图片,以提高页面布局效率。
8)对于视频下载类应用,建议对视频文件的长度进行限制,以保证下载成功率
对于新的视频下载类应用,应当限制下载文件大小,以提高用户感受。
9)对于需要翻页的应用,建议使用“最前页”“下一页”“上一页”“最后页”等选项,并且尽量排列在同一行上。同时翻页次数不要太多,若超过一定次数,建议分为不同栏目。
新闻咨询、图铃下载等业务都大量的使用到了翻页功能,为了提高页面效率和用户感受,建议将翻页选项放在同一行上,同时翻页次数不要过多,限制在5次之内比较合适。
10)对于游戏类应用,建议尽量使用小GIF图片来实现相关操作以增加游戏趣味性,以及页面布局效果。
这是WAP 2.0与WAP 1.X的根本区别之一。
2)必须限定页面大小,建议为5K~10K
虽然WAP 2.0协议栈的传输效率要高于WAP 1.X,但为了限制页面下载时间,提高业务可用性,保持良好的用户感受,必须对页面大小进行限定。
3)必须是彩色页面,使用图文混排功能
图文混排能极大的提高用户界面内操作的数量和方便程度,对于提高用户对于WAP 2.0业务的体验极为有效。
4)建议使用BANNAR功能,以方便用户返回到相应层次
例如:首页》掌中新闻》今日星闻
5)建议使用CSS样式表,来实现终端适配功能
对于WAP 2.0业务,终端适配的要求比WAP 1.X更高,而CSS样式表极大方便了SP终端适配的工作。
6)对于新闻咨询类应用,建议在使用大量文字时,使用背景色以增强用户感受,并区别于WAP1.X业务。
对于新闻咨询类应用,在页面布局上可能与WAP 1.X业务比较类似,都是按条排列,有上下翻页功能。为了区别与WAP 1.X业务,同时使得用户界面更加美观,建议在使用大量文字时,使用背景色以增强用户感受。
7)对于图铃下载类应用,建议可以直接点击预览图片来下载相应图片
WAP2.0支持图片链接,对于图片下载业务,可以通过直接点击图片的方式来下载图片,以提高页面布局效率。
8)对于视频下载类应用,建议对视频文件的长度进行限制,以保证下载成功率
对于新的视频下载类应用,应当限制下载文件大小,以提高用户感受。
9)对于需要翻页的应用,建议使用“最前页”“下一页”“上一页”“最后页”等选项,并且尽量排列在同一行上。同时翻页次数不要太多,若超过一定次数,建议分为不同栏目。
新闻咨询、图铃下载等业务都大量的使用到了翻页功能,为了提高页面效率和用户感受,建议将翻页选项放在同一行上,同时翻页次数不要过多,限制在5次之内比较合适。
10)对于游戏类应用,建议尽量使用小GIF图片来实现相关操作以增加游戏趣味性,以及页面布局效果。
2008年9月17日星期三
各种垃圾回收算法的通俗解释
引用计数( Reference Counting )算法
1960 年以前,人们为胚胎中的 Lisp 语言设计垃圾收集机制时,第一个想到的算法是引用计数算法。拿餐巾纸的例子来说,这种算法的原理大致可以描述为:
午餐时,为了把脑子里突然跳出来的设计灵感记下来,我从餐巾纸袋中抽出一张餐巾纸,打算在上面画出系统架构的蓝图。按照“餐巾纸使用规约之引用计数版”的要求,画图之前,我必须先在餐巾纸的一角写上计数值 1 ,以表示我在使用这张餐巾纸。这时,如果你也想看看我画的蓝图,那你就要把餐巾纸上的计数值加 1 ,将它改为 2 ,这表明目前有 2 个人在同时使用这张餐巾纸(当然,我是不会允许你用这张餐巾纸来擦鼻涕的)。你看完后,必须把计数值减 1 ,表明你对该餐巾纸的使用已经结束。同样,当我将餐巾纸上的内容全部誊写到笔记本上之后,我也会自觉地把餐巾纸上的计数值减 1 。此时,不出意外的话,这张餐巾纸上的计数值应当是 0 ,它会被垃圾收集器——假设那是一个专门负责打扫卫生的机器人——捡起来扔到垃圾箱里,因为垃圾收集器的惟一使命就是找到所有计数值为 0 的餐巾纸并清理它们。
引用计数算法的优点和缺陷同样明显。这一算法在执行垃圾收集任务时速度较快,但算法对程序中每一次内存分配和指针操作提出了额外的要求(增加或减少内存块的引用计数)。更重要的是,引用计数算法无法正确释放循环引用的内存块,对此, D. Hillis 有一段风趣而精辟的论述:
一天,一个学生走到 Moon 面前说:“我知道如何设计一个更好的垃圾收集器了。我们必须记录指向每个结点的指针数目。” Moon 耐心地给这位学生讲了下面这个故事:“一天,一个学生走到 Moon 面前说:‘我知道如何设计一个更好的垃圾收集器了……’”
D. Hillis 的故事和我们小时候常说的“从前有座山,山上有个庙,庙里有个老和尚”的故事有异曲同工之妙。这说明,单是使用引用计数算法还不足以解决垃圾收集中的所有问题。正因为如此,引用计数算法也常常被研究者们排除在狭义的垃圾收集算法之外。当然,作为一种最简单、最直观的解决方案,引用计数算法本身具有其不可替代的优越性。 1980 年代前后, D. P. Friedman , D. S. Wise , H. G. Baker 等人对引用计数算法进行了数次改进,这些改进使得引用计数算法及其变种(如延迟计数算法等)在简单的环境下,或是在一些综合了多种算法的现代垃圾收集系统中仍然可以一展身手。
标记-清除( Mark-Sweep )算法
第一种实用和完善的垃圾收集算法是 J. McCarthy 等人在 1960 年提出并成功地应用于 Lisp 语言的标记-清除算法。仍以餐巾纸为例,标记-清除算法的执行过程是这样的:
午餐过程中,餐厅里的所有人都根据自己的需要取用餐巾纸。当垃圾收集机器人想收集废旧餐巾纸的时候,它会让所有用餐的人先停下来,然后,依次询问餐厅里的每一个人:“你正在用餐巾纸吗?你用的是哪一张餐巾纸?”机器人根据每个人的回答将人们正在使用的餐巾纸画上记号。询问过程结束后,机器人在餐厅里寻找所有散落在餐桌上且没有记号的餐巾纸(这些显然都是用过的废旧餐巾纸),把它们统统扔到垃圾箱里。
正如其名称所暗示的那样,标记-清除算法的执行过程分为“标记”和“清除”两大阶段。这种分步执行的思路奠定了现代垃圾收集算法的思想基础。与引用计数算法不同的是,标记-清除算法不需要运行环境监测每一次内存分配和指针操作,而只要在“标记”阶段中跟踪每一个指针变量的指向——用类似思路实现的垃圾收集器也常被后人统称为跟踪收集器( Tracing Collector )
伴随着 Lisp 语言的成功,标记-清除算法也在大多数早期的 Lisp 运行环境中大放异彩。尽管最初版本的标记-清除算法在今天看来还存在效率不高(标记和清除是两个相当耗时的过程)等诸多缺陷,但在后面的讨论中,我们可以看到,几乎所有现代垃圾收集算法都是标记-清除思想的延续,仅此一点, J. McCarthy 等人在垃圾收集技术方面的贡献就丝毫不亚于他们在 Lisp 语言上的成就了。
复制( Copying )算法
为了解决标记-清除算法在垃圾收集效率方面的缺陷, M. L. Minsky 于 1963 年发表了著名的论文“一种使用双存储区的 Lisp 语言垃圾收集器( A LISP Garbage Collector Algorithm Using Serial Secondary Storage )”。 M. L. Minsky 在该论文中描述的算法被人们称为复制算法,它也被 M. L. Minsky 本人成功地引入到了 Lisp 语言的一个实现版本中。
复制算法别出心裁地将堆空间一分为二,并使用简单的复制操作来完成垃圾收集工作,这个思路相当有趣。借用餐巾纸的比喻,我们可以这样理解 M. L. Minsky 的复制算法:
餐厅被垃圾收集机器人分成南区和北区两个大小完全相同的部分。午餐时,所有人都先在南区用餐(因为空间有限,用餐人数自然也将减少一半),用餐时可以随意使用餐巾纸。当垃圾收集机器人认为有必要回收废旧餐巾纸时,它会要求所有用餐者以最快的速度从南区转移到北区,同时随身携带自己正在使用的餐巾纸。等所有人都转移到北区之后,垃圾收集机器人只要简单地把南区中所有散落的餐巾纸扔进垃圾箱就算完成任务了。下一次垃圾收集的工作过程也大致类似,惟一的不同只是人们的转移方向变成了从北区到南区。如此循环往复,每次垃圾收集都只需简单地转移(也就是复制)一次,垃圾收集速度无与伦比——当然,对于用餐者往返奔波于南北两区之间的辛劳,垃圾收集机器人是决不会流露出丝毫怜悯的。
M. L. Minsky 的发明绝对算得上一种奇思妙想。分区、复制的思路不仅大幅提高了垃圾收集的效率,而且也将原本繁纷复杂的内存分配算法变得前所未有地简明和扼要(既然每次内存回收都是对整个半区的回收,内存分配时也就不用考虑内存碎片等复杂情况,只要移动堆顶指针,按顺序分配内存就可以了),这简直是个奇迹!不过,任何奇迹的出现都有一定的代价,在垃圾收集技术中,复制算法提高效率的代价是人为地将可用内存缩小了一半。实话实说,这个代价未免也太高了一些。
标记-整理( Mark-Compact )算法
标记-整理算法是标记-清除算法和复制算法的有机结合。把标记-清除算法在内存占用上的优点和复制算法在执行效率上的特长综合起来,这是所有人都希望看到的结果。不过,两种垃圾收集算法的整合并不像 1 加 1 等于 2 那样简单,我们必须引入一些全新的思路。 1970 年前后, G. L. Steele , C. J. Cheney 和 D. S. Wise 等研究者陆续找到了正确的方向,标记-整理算法的轮廓也逐渐清晰了起来:
在我们熟悉的餐厅里,这一次,垃圾收集机器人不再把餐厅分成两个南北区域了。需要执行垃圾收集任务时,机器人先执行标记-清除算法的第一个步骤,为所有使用中的餐巾纸画好标记,然后,机器人命令所有就餐者带上有标记的餐巾纸向餐厅的南面集中,同时把没有标记的废旧餐巾纸扔向餐厅北面。这样一来,机器人只消站在餐厅北面,怀抱垃圾箱,迎接扑面而来的废旧餐巾纸就行了。
实验表明,标记-整理算法的总体执行效率高于标记-清除算法,又不像复制算法那样需要牺牲一半的存储空间,这显然是一种非常理想的结果。在许多现代的垃圾收集器中,人们都使用了标记-整理算法或其改进版本。
增量收集( Incremental Collecting )算法
对实时垃圾收集算法的研究直接导致了增量收集算法的诞生。
最初,人们关于实时垃圾收集的想法是这样的:为了进行实时的垃圾收集,可以设计一个多进程的运行环境,比如用一个进程执行垃圾收集工作,另一个进程执行程序代码。这样一来,垃圾收集工作看上去就仿佛是在后台悄悄完成的,不会打断程序代码的运行。
在收集餐巾纸的例子中,这一思路可以被理解为:垃圾收集机器人在人们用餐的同时寻找废弃的餐巾纸并将它们扔到垃圾箱里。这个看似简单的思路会在设计和实现时碰上进程间冲突的难题。比如说,如果垃圾收集进程包括标记和清除两个工作阶段,那么,垃圾收集器在第一阶段中辛辛苦苦标记出的结果很可能被另一个进程中的内存操作代码修改得面目全非,以至于第二阶段的工作没有办法开展。
M. L. Minsky 和 D. E. Knuth 对实时垃圾收集过程中的技术难点进行了早期的研究, G. L. Steele 于 1975 年发表了题为“多进程整理的垃圾收集( Multiprocessing compactifying garbage collection )”的论文,描述了一种被后人称为“ Minsky-Knuth-Steele 算法”的实时垃圾收集算法。 E. W. Dijkstra , L. Lamport , R. R. Fenichel 和 J. C. Yochelson 等人也相继在此领域做出了各自的贡献。 1978 年, H. G. Baker 发表了“串行计算机上的实时表处理技术( List Processing in Real Time on a Serial Computer )”一文,系统阐述了多进程环境下用于垃圾收集的增量收集算法。
增量收集算法的基础仍是传统的标记-清除和复制算法。增量收集算法通过对进程间冲突的妥善处理,允许垃圾收集进程以分阶段的方式完成标记、清理或复制工作。详细分析各种增量收集算法的内部机理是一件相当繁琐的事情,在这里,读者们需要了解的仅仅是: H. G. Baker 等人的努力已经将实时垃圾收集的梦想变成了现实,我们再也不用为垃圾收集打断程序的运行而烦恼了
分代收集( Generational Collecting )算法
和大多数软件开发技术一样,统计学原理总能在技术发展的过程中起到强力催化剂的作用。 1980 年前后,善于在研究中使用统计分析知识的技术人员发现,大多数内存块的生存周期都比较短,垃圾收集器应当把更多的精力放在检查和清理新分配的内存块上。这个发现对于垃圾收集技术的价值可以用餐巾纸的例子概括如下:
如果垃圾收集机器人足够聪明,事先摸清了餐厅里每个人在用餐时使用餐巾纸的习惯——比如有些人喜欢在用餐前后各用掉一张餐巾纸,有的人喜欢自始至终攥着一张餐巾纸不放,有的人则每打一个喷嚏就用去一张餐巾纸——机器人就可以制定出更完善的餐巾纸回收计划,并总是在人们刚扔掉餐巾纸没多久就把垃圾捡走。这种基于统计学原理的做法当然可以让餐厅的整洁度成倍提高。
D. E. Knuth , T. Knight , G. Sussman 和 R. Stallman 等人对内存垃圾的分类处理做了最早的研究。 1983 年, H. Lieberman 和 C. Hewitt 发表了题为“基于对象寿命的一种实时垃圾收集器( A real-time garbage collector based on the lifetimes of objects )”的论文。这篇著名的论文标志着分代收集算法的正式诞生。此后,在 H. G. Baker , R. L. Hudson , J. E. B. Moss 等人的共同努力下,分代收集算法逐渐成为了垃圾收集领域里的主流技术。
分代收集算法通常将堆中的内存块按寿命分为两类,年老的和年轻的。垃圾收集器使用不同的收集算法或收集策略,分别处理这两类内存块,并特别地把主要工作时间花在处理年轻的内存块上。分代收集算法使垃圾收集器在有限的资源条件下,可以更为有效地工作——这种效率上的提高在今天的 Java 虚拟机中得到了最好的证明。
一个简单的实现
http://www.utdallas.edu/~ramakrishnan/Projects/GC_for_C/index.htm
惠普的一个免费的C/C++内存回收器的实现.
http://www.hpl.hp.com/personal/Hans_Boehm/gc/
动态分配的选择、折衷和实现
http://blog.csdn.net/wishfly/archive/2005/10/16/504854.aspx
Art of C++ 一书的C++ 的内存回收器的实现
http://www.devarticles.com/c/a/Cplusplus/A-Simple-Garbage-Collector-for-C-plus-plus/11/
1960 年以前,人们为胚胎中的 Lisp 语言设计垃圾收集机制时,第一个想到的算法是引用计数算法。拿餐巾纸的例子来说,这种算法的原理大致可以描述为:
午餐时,为了把脑子里突然跳出来的设计灵感记下来,我从餐巾纸袋中抽出一张餐巾纸,打算在上面画出系统架构的蓝图。按照“餐巾纸使用规约之引用计数版”的要求,画图之前,我必须先在餐巾纸的一角写上计数值 1 ,以表示我在使用这张餐巾纸。这时,如果你也想看看我画的蓝图,那你就要把餐巾纸上的计数值加 1 ,将它改为 2 ,这表明目前有 2 个人在同时使用这张餐巾纸(当然,我是不会允许你用这张餐巾纸来擦鼻涕的)。你看完后,必须把计数值减 1 ,表明你对该餐巾纸的使用已经结束。同样,当我将餐巾纸上的内容全部誊写到笔记本上之后,我也会自觉地把餐巾纸上的计数值减 1 。此时,不出意外的话,这张餐巾纸上的计数值应当是 0 ,它会被垃圾收集器——假设那是一个专门负责打扫卫生的机器人——捡起来扔到垃圾箱里,因为垃圾收集器的惟一使命就是找到所有计数值为 0 的餐巾纸并清理它们。
引用计数算法的优点和缺陷同样明显。这一算法在执行垃圾收集任务时速度较快,但算法对程序中每一次内存分配和指针操作提出了额外的要求(增加或减少内存块的引用计数)。更重要的是,引用计数算法无法正确释放循环引用的内存块,对此, D. Hillis 有一段风趣而精辟的论述:
一天,一个学生走到 Moon 面前说:“我知道如何设计一个更好的垃圾收集器了。我们必须记录指向每个结点的指针数目。” Moon 耐心地给这位学生讲了下面这个故事:“一天,一个学生走到 Moon 面前说:‘我知道如何设计一个更好的垃圾收集器了……’”
D. Hillis 的故事和我们小时候常说的“从前有座山,山上有个庙,庙里有个老和尚”的故事有异曲同工之妙。这说明,单是使用引用计数算法还不足以解决垃圾收集中的所有问题。正因为如此,引用计数算法也常常被研究者们排除在狭义的垃圾收集算法之外。当然,作为一种最简单、最直观的解决方案,引用计数算法本身具有其不可替代的优越性。 1980 年代前后, D. P. Friedman , D. S. Wise , H. G. Baker 等人对引用计数算法进行了数次改进,这些改进使得引用计数算法及其变种(如延迟计数算法等)在简单的环境下,或是在一些综合了多种算法的现代垃圾收集系统中仍然可以一展身手。
标记-清除( Mark-Sweep )算法
第一种实用和完善的垃圾收集算法是 J. McCarthy 等人在 1960 年提出并成功地应用于 Lisp 语言的标记-清除算法。仍以餐巾纸为例,标记-清除算法的执行过程是这样的:
午餐过程中,餐厅里的所有人都根据自己的需要取用餐巾纸。当垃圾收集机器人想收集废旧餐巾纸的时候,它会让所有用餐的人先停下来,然后,依次询问餐厅里的每一个人:“你正在用餐巾纸吗?你用的是哪一张餐巾纸?”机器人根据每个人的回答将人们正在使用的餐巾纸画上记号。询问过程结束后,机器人在餐厅里寻找所有散落在餐桌上且没有记号的餐巾纸(这些显然都是用过的废旧餐巾纸),把它们统统扔到垃圾箱里。
正如其名称所暗示的那样,标记-清除算法的执行过程分为“标记”和“清除”两大阶段。这种分步执行的思路奠定了现代垃圾收集算法的思想基础。与引用计数算法不同的是,标记-清除算法不需要运行环境监测每一次内存分配和指针操作,而只要在“标记”阶段中跟踪每一个指针变量的指向——用类似思路实现的垃圾收集器也常被后人统称为跟踪收集器( Tracing Collector )
伴随着 Lisp 语言的成功,标记-清除算法也在大多数早期的 Lisp 运行环境中大放异彩。尽管最初版本的标记-清除算法在今天看来还存在效率不高(标记和清除是两个相当耗时的过程)等诸多缺陷,但在后面的讨论中,我们可以看到,几乎所有现代垃圾收集算法都是标记-清除思想的延续,仅此一点, J. McCarthy 等人在垃圾收集技术方面的贡献就丝毫不亚于他们在 Lisp 语言上的成就了。
复制( Copying )算法
为了解决标记-清除算法在垃圾收集效率方面的缺陷, M. L. Minsky 于 1963 年发表了著名的论文“一种使用双存储区的 Lisp 语言垃圾收集器( A LISP Garbage Collector Algorithm Using Serial Secondary Storage )”。 M. L. Minsky 在该论文中描述的算法被人们称为复制算法,它也被 M. L. Minsky 本人成功地引入到了 Lisp 语言的一个实现版本中。
复制算法别出心裁地将堆空间一分为二,并使用简单的复制操作来完成垃圾收集工作,这个思路相当有趣。借用餐巾纸的比喻,我们可以这样理解 M. L. Minsky 的复制算法:
餐厅被垃圾收集机器人分成南区和北区两个大小完全相同的部分。午餐时,所有人都先在南区用餐(因为空间有限,用餐人数自然也将减少一半),用餐时可以随意使用餐巾纸。当垃圾收集机器人认为有必要回收废旧餐巾纸时,它会要求所有用餐者以最快的速度从南区转移到北区,同时随身携带自己正在使用的餐巾纸。等所有人都转移到北区之后,垃圾收集机器人只要简单地把南区中所有散落的餐巾纸扔进垃圾箱就算完成任务了。下一次垃圾收集的工作过程也大致类似,惟一的不同只是人们的转移方向变成了从北区到南区。如此循环往复,每次垃圾收集都只需简单地转移(也就是复制)一次,垃圾收集速度无与伦比——当然,对于用餐者往返奔波于南北两区之间的辛劳,垃圾收集机器人是决不会流露出丝毫怜悯的。
M. L. Minsky 的发明绝对算得上一种奇思妙想。分区、复制的思路不仅大幅提高了垃圾收集的效率,而且也将原本繁纷复杂的内存分配算法变得前所未有地简明和扼要(既然每次内存回收都是对整个半区的回收,内存分配时也就不用考虑内存碎片等复杂情况,只要移动堆顶指针,按顺序分配内存就可以了),这简直是个奇迹!不过,任何奇迹的出现都有一定的代价,在垃圾收集技术中,复制算法提高效率的代价是人为地将可用内存缩小了一半。实话实说,这个代价未免也太高了一些。
标记-整理( Mark-Compact )算法
标记-整理算法是标记-清除算法和复制算法的有机结合。把标记-清除算法在内存占用上的优点和复制算法在执行效率上的特长综合起来,这是所有人都希望看到的结果。不过,两种垃圾收集算法的整合并不像 1 加 1 等于 2 那样简单,我们必须引入一些全新的思路。 1970 年前后, G. L. Steele , C. J. Cheney 和 D. S. Wise 等研究者陆续找到了正确的方向,标记-整理算法的轮廓也逐渐清晰了起来:
在我们熟悉的餐厅里,这一次,垃圾收集机器人不再把餐厅分成两个南北区域了。需要执行垃圾收集任务时,机器人先执行标记-清除算法的第一个步骤,为所有使用中的餐巾纸画好标记,然后,机器人命令所有就餐者带上有标记的餐巾纸向餐厅的南面集中,同时把没有标记的废旧餐巾纸扔向餐厅北面。这样一来,机器人只消站在餐厅北面,怀抱垃圾箱,迎接扑面而来的废旧餐巾纸就行了。
实验表明,标记-整理算法的总体执行效率高于标记-清除算法,又不像复制算法那样需要牺牲一半的存储空间,这显然是一种非常理想的结果。在许多现代的垃圾收集器中,人们都使用了标记-整理算法或其改进版本。
增量收集( Incremental Collecting )算法
对实时垃圾收集算法的研究直接导致了增量收集算法的诞生。
最初,人们关于实时垃圾收集的想法是这样的:为了进行实时的垃圾收集,可以设计一个多进程的运行环境,比如用一个进程执行垃圾收集工作,另一个进程执行程序代码。这样一来,垃圾收集工作看上去就仿佛是在后台悄悄完成的,不会打断程序代码的运行。
在收集餐巾纸的例子中,这一思路可以被理解为:垃圾收集机器人在人们用餐的同时寻找废弃的餐巾纸并将它们扔到垃圾箱里。这个看似简单的思路会在设计和实现时碰上进程间冲突的难题。比如说,如果垃圾收集进程包括标记和清除两个工作阶段,那么,垃圾收集器在第一阶段中辛辛苦苦标记出的结果很可能被另一个进程中的内存操作代码修改得面目全非,以至于第二阶段的工作没有办法开展。
M. L. Minsky 和 D. E. Knuth 对实时垃圾收集过程中的技术难点进行了早期的研究, G. L. Steele 于 1975 年发表了题为“多进程整理的垃圾收集( Multiprocessing compactifying garbage collection )”的论文,描述了一种被后人称为“ Minsky-Knuth-Steele 算法”的实时垃圾收集算法。 E. W. Dijkstra , L. Lamport , R. R. Fenichel 和 J. C. Yochelson 等人也相继在此领域做出了各自的贡献。 1978 年, H. G. Baker 发表了“串行计算机上的实时表处理技术( List Processing in Real Time on a Serial Computer )”一文,系统阐述了多进程环境下用于垃圾收集的增量收集算法。
增量收集算法的基础仍是传统的标记-清除和复制算法。增量收集算法通过对进程间冲突的妥善处理,允许垃圾收集进程以分阶段的方式完成标记、清理或复制工作。详细分析各种增量收集算法的内部机理是一件相当繁琐的事情,在这里,读者们需要了解的仅仅是: H. G. Baker 等人的努力已经将实时垃圾收集的梦想变成了现实,我们再也不用为垃圾收集打断程序的运行而烦恼了
分代收集( Generational Collecting )算法
和大多数软件开发技术一样,统计学原理总能在技术发展的过程中起到强力催化剂的作用。 1980 年前后,善于在研究中使用统计分析知识的技术人员发现,大多数内存块的生存周期都比较短,垃圾收集器应当把更多的精力放在检查和清理新分配的内存块上。这个发现对于垃圾收集技术的价值可以用餐巾纸的例子概括如下:
如果垃圾收集机器人足够聪明,事先摸清了餐厅里每个人在用餐时使用餐巾纸的习惯——比如有些人喜欢在用餐前后各用掉一张餐巾纸,有的人喜欢自始至终攥着一张餐巾纸不放,有的人则每打一个喷嚏就用去一张餐巾纸——机器人就可以制定出更完善的餐巾纸回收计划,并总是在人们刚扔掉餐巾纸没多久就把垃圾捡走。这种基于统计学原理的做法当然可以让餐厅的整洁度成倍提高。
D. E. Knuth , T. Knight , G. Sussman 和 R. Stallman 等人对内存垃圾的分类处理做了最早的研究。 1983 年, H. Lieberman 和 C. Hewitt 发表了题为“基于对象寿命的一种实时垃圾收集器( A real-time garbage collector based on the lifetimes of objects )”的论文。这篇著名的论文标志着分代收集算法的正式诞生。此后,在 H. G. Baker , R. L. Hudson , J. E. B. Moss 等人的共同努力下,分代收集算法逐渐成为了垃圾收集领域里的主流技术。
分代收集算法通常将堆中的内存块按寿命分为两类,年老的和年轻的。垃圾收集器使用不同的收集算法或收集策略,分别处理这两类内存块,并特别地把主要工作时间花在处理年轻的内存块上。分代收集算法使垃圾收集器在有限的资源条件下,可以更为有效地工作——这种效率上的提高在今天的 Java 虚拟机中得到了最好的证明。
一个简单的实现
http://www.utdallas.edu/~ramakrishnan/Projects/GC_for_C/index.htm
惠普的一个免费的C/C++内存回收器的实现.
http://www.hpl.hp.com/personal/Hans_Boehm/gc/
动态分配的选择、折衷和实现
http://blog.csdn.net/wishfly/archive/2005/10/16/504854.aspx
Art of C++ 一书的C++ 的内存回收器的实现
http://www.devarticles.com/c/a/Cplusplus/A-Simple-Garbage-Collector-for-C-plus-plus/11/
2008年8月29日星期五
swing中JFileChooser的用法
1、基本用法
JFileChooser dlg = new JFileChooser();
dlg.setDialogTitle("Open JPEG file");
int result = dlg.showOpenDialog(this); // 打开"打开文件"对话框
// int result = dlg.showSaveDialog(this); // 打"开保存文件"对话框
if (result == JFileChooser.APPROVE_OPTION) {
File file = dlg.getSelectedFile();
...
}
2、自定义FileFilter
JDK没有提供默认的文件过滤器,但提供了过滤器的抽象超类,我们可以继承它。
import javax.swing.filechooser.FileFilter;
public final class PictureFileFilter extends FileFilter {
private String extension;
private String description;
public PictureFileFilter(String extension, String description) {
super();
this.extension = extension;
this.description = description;
}
public boolean accept(File f) {
if (f != null) {
if (f.isDirectory()) {
return true;
}
String extension = getExtension(f);
if (extension != null && extension.equalsIgnoreCase(this.extension)) {
return true;
}
}
return false;
}
public String getDescription() {
return description;
}
private String getExtension(File f) {
if (f != null) {
String filename = f.getName();
int i = filename.lastIndexOf('.');
if (i > 0 && i < filename.length() - 1) {
return filename.substring(i + 1).toLowerCase();
}
}
return null;
}
}
其实主要就是accept(File f)函数。上例中只有一个过滤器,多个过滤器可参考JDK目录中“demo\jfc\FileChooserDemo\src”中的“ExampleFileFilter.java”
3、多选
在基本用法中,设置
c.setMultiSelectionEnabled(true);
即可实现文件的多选。
读取选择的文件时需使用
File[] files = c.getSelectedFiles();
4、选择目录
利用这个打开对话框,不仅可以选择文件,还可以选择目录。
其实,对话框有一个FileSelectionMode属性,其默认值为“JFileChooser.FILES_ONLY”,只需要将其修改为“JFileChooser.DIRECTORIES_ONLY”即可。
JFileChooser c = new JFileChooser();
c.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
c.setDialogTitle("Select path to save");
int result = c.showOpenDialog(PrintDatetime.this);
if (result == JFileChooser.APPROVE_OPTION) {
String path = c.getSelectedFile().getAbsolutePath());
...
}
JFileChooser dlg = new JFileChooser();
dlg.setDialogTitle("Open JPEG file");
int result = dlg.showOpenDialog(this); // 打开"打开文件"对话框
// int result = dlg.showSaveDialog(this); // 打"开保存文件"对话框
if (result == JFileChooser.APPROVE_OPTION) {
File file = dlg.getSelectedFile();
...
}
2、自定义FileFilter
JDK没有提供默认的文件过滤器,但提供了过滤器的抽象超类,我们可以继承它。
import javax.swing.filechooser.FileFilter;
public final class PictureFileFilter extends FileFilter {
private String extension;
private String description;
public PictureFileFilter(String extension, String description) {
super();
this.extension = extension;
this.description = description;
}
public boolean accept(File f) {
if (f != null) {
if (f.isDirectory()) {
return true;
}
String extension = getExtension(f);
if (extension != null && extension.equalsIgnoreCase(this.extension)) {
return true;
}
}
return false;
}
public String getDescription() {
return description;
}
private String getExtension(File f) {
if (f != null) {
String filename = f.getName();
int i = filename.lastIndexOf('.');
if (i > 0 && i < filename.length() - 1) {
return filename.substring(i + 1).toLowerCase();
}
}
return null;
}
}
其实主要就是accept(File f)函数。上例中只有一个过滤器,多个过滤器可参考JDK目录中“demo\jfc\FileChooserDemo\src”中的“ExampleFileFilter.java”
3、多选
在基本用法中,设置
c.setMultiSelectionEnabled(true);
即可实现文件的多选。
读取选择的文件时需使用
File[] files = c.getSelectedFiles();
4、选择目录
利用这个打开对话框,不仅可以选择文件,还可以选择目录。
其实,对话框有一个FileSelectionMode属性,其默认值为“JFileChooser.FILES_ONLY”,只需要将其修改为“JFileChooser.DIRECTORIES_ONLY”即可。
JFileChooser c = new JFileChooser();
c.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
c.setDialogTitle("Select path to save");
int result = c.showOpenDialog(PrintDatetime.this);
if (result == JFileChooser.APPROVE_OPTION) {
String path = c.getSelectedFile().getAbsolutePath());
...
}
2008年8月25日星期一
2008年8月22日星期五
Install OpenMoko or Qtopia in Rokr E6 or A1200
http://linuxpdablog.blogspot.com/2008/06/install-openmoko-or-qtopia-in-rokr-e6.html
http://www.openmoko.com/product-qa.html
http://planet.openezx.org/
http://www.openmoko.com/product-qa.html
http://planet.openezx.org/
2008年8月20日星期三
2008年8月5日星期二
USB Test Tools
http://www.usb.org/developers/tools/
USBCV R1.3.2 - Windows XP SP2 (English Version) only
USBCV R1.3.2 - Windows XP SP2 (English Version) only
电脑打开文件夹(内有 swf、flv 格式)都会很慢,右链菜单也要半分钟才能出来,解决办法
你用的是深度 sp3吧?这是一个小bug,现在可以用如下办法解决:
在GHOST8.1 中SWF,FLV,F4A,F4V,F4P 文件的图标都关联到了一个网络上的一个文件上了(192.168.1.2\公用目录\XP SP3 工作目录\克隆版制作\sa_flashplayer_9_debug.exe)。导致系统在打开一个含有以上文件的问件夹时出现假死现象。此注册表补丁就是重新关联了以上文件和文件的图标。
打开一个文本文档,复制如下注册表代码进去,然后保存,把文档的后缀名改成.reg
如:“关联修复.reg” 然后双击运行把注册表文件导入即可。
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\FlashPlayer.FlashVideo\DefaultIcon]
@="C:\\WINDOWS\\system32\\Macromed\\Flash\\sa_flashplayer_9.exe,-202"
[HKEY_CLASSES_ROOT\FlashPlayer.FlashVideo\shell\open\command]
@="\"C:\\WINDOWS\\system32\\Macromed\\Flash\\sa_flashplayer_9.exe\" %1"
[HKEY_CLASSES_ROOT\FlashPlayer.VideoForFlashPlayer\DefaultIcon]
@="C:\\WINDOWS\\system32\\Macromed\\Flash\\sa_flashplayer_9.exe,-203"
[HKEY_CLASSES_ROOT\FlashPlayer.VideoForFlashPlayer\shell\open\command]
@="\"C:\\WINDOWS\\system32\\Macromed\\Flash\\sa_flashplayer_9.exe\" %1"
[HKEY_CLASSES_ROOT\FlashPlayer.ProtectedMediaForFlashPlayer\DefaultIcon]
@="C:\\WINDOWS\\system32\\Macromed\\Flash\\sa_flashplayer_9.exe,-204"
[HKEY_CLASSES_ROOT\FlashPlayer.ProtectedMediaForFlashPlayer\shell\open\command]
@="\"C:\\WINDOWS\\system32\\Macromed\\Flash\\sa_flashplayer_9.exe\" %1"
[HKEY_CLASSES_ROOT\FlashPlayer.AudioForFlashPlayer\DefaultIcon]
@="C:\\WINDOWS\\system32\\Macromed\\Flash\\sa_flashplayer_9.exe,-205"
[HKEY_CLASSES_ROOT\FlashPlayer.AudioForFlashPlayer\shell\open\command]
@="\"C:\\WINDOWS\\system32\\Macromed\\Flash\\sa_flashplayer_9.exe\" %1"
[HKEY_CLASSES_ROOT\ShockwaveFlash.ShockwaveFlash\DefaultIcon]
@="C:\\WINDOWS\\system32\\Macromed\\Flash\\sa_flashplayer_9.exe,-608"
[HKEY_CLASSES_ROOT\ShockwaveFlash.ShockwaveFlash\shell\open\command]
@="\"C:\\WINDOWS\\system32\\Macromed\\Flash\\sa_flashplayer_9.exe\" %1"
参考资料:深度技术论坛
在GHOST8.1 中SWF,FLV,F4A,F4V,F4P 文件的图标都关联到了一个网络上的一个文件上了(192.168.1.2\公用目录\XP SP3 工作目录\克隆版制作\sa_flashplayer_9_debug.exe)。导致系统在打开一个含有以上文件的问件夹时出现假死现象。此注册表补丁就是重新关联了以上文件和文件的图标。
打开一个文本文档,复制如下注册表代码进去,然后保存,把文档的后缀名改成.reg
如:“关联修复.reg” 然后双击运行把注册表文件导入即可。
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\FlashPlayer.FlashVideo\DefaultIcon]
@="C:\\WINDOWS\\system32\\Macromed\\Flash\\sa_flashplayer_9.exe,-202"
[HKEY_CLASSES_ROOT\FlashPlayer.FlashVideo\shell\open\command]
@="\"C:\\WINDOWS\\system32\\Macromed\\Flash\\sa_flashplayer_9.exe\" %1"
[HKEY_CLASSES_ROOT\FlashPlayer.VideoForFlashPlayer\DefaultIcon]
@="C:\\WINDOWS\\system32\\Macromed\\Flash\\sa_flashplayer_9.exe,-203"
[HKEY_CLASSES_ROOT\FlashPlayer.VideoForFlashPlayer\shell\open\command]
@="\"C:\\WINDOWS\\system32\\Macromed\\Flash\\sa_flashplayer_9.exe\" %1"
[HKEY_CLASSES_ROOT\FlashPlayer.ProtectedMediaForFlashPlayer\DefaultIcon]
@="C:\\WINDOWS\\system32\\Macromed\\Flash\\sa_flashplayer_9.exe,-204"
[HKEY_CLASSES_ROOT\FlashPlayer.ProtectedMediaForFlashPlayer\shell\open\command]
@="\"C:\\WINDOWS\\system32\\Macromed\\Flash\\sa_flashplayer_9.exe\" %1"
[HKEY_CLASSES_ROOT\FlashPlayer.AudioForFlashPlayer\DefaultIcon]
@="C:\\WINDOWS\\system32\\Macromed\\Flash\\sa_flashplayer_9.exe,-205"
[HKEY_CLASSES_ROOT\FlashPlayer.AudioForFlashPlayer\shell\open\command]
@="\"C:\\WINDOWS\\system32\\Macromed\\Flash\\sa_flashplayer_9.exe\" %1"
[HKEY_CLASSES_ROOT\ShockwaveFlash.ShockwaveFlash\DefaultIcon]
@="C:\\WINDOWS\\system32\\Macromed\\Flash\\sa_flashplayer_9.exe,-608"
[HKEY_CLASSES_ROOT\ShockwaveFlash.ShockwaveFlash\shell\open\command]
@="\"C:\\WINDOWS\\system32\\Macromed\\Flash\\sa_flashplayer_9.exe\" %1"
参考资料:深度技术论坛
2008年7月30日星期三
WAP Development
http://www.hawhaw.de/
http://jquery.glyphix.com/
jquery xslt engine
hawhaw + glyphix should be a good choice.
http://hi.baidu.com/panzhong/blog/item/7efd986455f589f3f73654aa.html
开源 J2ME Wap2.0 浏览器开发
http://dulpi.com/modules/wordpress/blog13.html
使用PHP建立WML/WAP站点
http://dev.mobi/article/device-simulator-skinning-with-php
Device simulator skinning with PHP
http://shiaowu.javaeye.com/blog/132769
一篇介绍hawhaw及用它来做wap站的文章
http://www.webmonkey.com/tutorial/Easy_XML_Consumption_using_jQuery?oldid=20032
Easy XML Consumption using jQuery
http://15daysofjquery.com/edit-in-place-with-ajax-using-jquery-javascript-library/15/
Edit In Place with AJAX Using jQuery Javascript Library
http://www.ajaxbestiary.com/2007/11/13/a-lightweight-rich-text-editor-in-jquery/
A Lightweight Rich Text Editor in jQuery
http://www.appelsiini.net/projects/jeditable
Jeditable - Edit In Place Plugin For jQuery
http://code.google.com/p/jwysiwyg/
jwysiwyg WYSIWYG jQuery Plugin
http://www.wymeditor.org/en/
WYMeditor: web-based XHTML editor
http://jquery.glyphix.com/
jquery xslt engine
hawhaw + glyphix should be a good choice.
http://hi.baidu.com/panzhong/blog/item/7efd986455f589f3f73654aa.html
开源 J2ME Wap2.0 浏览器开发
http://dulpi.com/modules/wordpress/blog13.html
使用PHP建立WML/WAP站点
http://dev.mobi/article/device-simulator-skinning-with-php
Device simulator skinning with PHP
http://shiaowu.javaeye.com/blog/132769
一篇介绍hawhaw及用它来做wap站的文章
http://www.webmonkey.com/tutorial/Easy_XML_Consumption_using_jQuery?oldid=20032
Easy XML Consumption using jQuery
http://15daysofjquery.com/edit-in-place-with-ajax-using-jquery-javascript-library/15/
Edit In Place with AJAX Using jQuery Javascript Library
http://www.ajaxbestiary.com/2007/11/13/a-lightweight-rich-text-editor-in-jquery/
A Lightweight Rich Text Editor in jQuery
http://www.appelsiini.net/projects/jeditable
Jeditable - Edit In Place Plugin For jQuery
http://code.google.com/p/jwysiwyg/
jwysiwyg WYSIWYG jQuery Plugin
http://www.wymeditor.org/en/
WYMeditor: web-based XHTML editor
2008年7月29日星期二
C/C++格式化字符串说明
C++的格式化字符串经常用作格式化数字的输出、字符串合并和转换等等很多场合。
1. 格式化规定符
━━━━━━━━━━━━━━━━━━━━━━━━━━
符号 作用
──────────────────────────
%d 十进制有符号整数
%u 十进制无符号整数
%f 浮点数
%s 字符串
%c 单个字符
%p 指针的值
%e 指数形式的浮点数
%x, %X 无符号以十六进制表示的整数
%0 无符号以八进制表示的整数
%g 自动选择合适的表示法
━━━━━━━━━━━━━━━━━━━━━━━━━━
说明:
(1). 可以在"%"和字母之间插进数字表示最大场宽。
例如: %3d 表示输出3位整型数, 不够3位右对齐。
%9.2f表示输出场宽为9的浮点数, 其中小数位为2, 整数位为6,
小数点占一位, 不够9位右对齐。
%8s 表示输出8个字符的字符串, 不够8个字符右对齐。
如果字符串的长度、或整型数位数超过说明的场宽, 将按其实际长度输出。但对浮点数, 若整数部分位数超过了说明的整数位宽度, 将按实际整数位输出; 若小数部分位数超过了说明的小数位宽度, 则按说明的宽度以四舍五入输出。
另外, 若想在输出值前加一些0, 就应在场宽项前加个0。
例如: %04d 表示在输出一个小于4位的数值时, 将在前面补0使其总宽度为4位。
如果用浮点数表示字符或整型量的输出格式, 小数点后的数字代表最大宽度, 小数点前的数字代表最小宽度。
例如: %6.9s 表示显示一个长度不小于6且不大于9的字符串。若大于9, 则第9个字符以后的内容将被删除。
(2). 可以在"%"和字母之间加小写字母l, 表示输出的是长型数。
例如: %ld 表示输出long整数
%lf 表示输出double浮点数
(3). 可以控制输出左对齐或右对齐, 即在"%"和字母之间加入一个"-" 号可说明输出为左对齐, 否则为右对齐。
例如: %-7d 表示输出7位整数左对齐
%-10s 表示输出10个字符左对齐
2. 一些特殊规定字符
━━━━━━━━━━━━━━━━━━━━━━━━━━
字符 作用
──────────────────────────
\n 换行
\f 清屏并换页
\r 回车
\t Tab符
\xhh 表示一个ASCII码用16进表示, 其中hh是1到2个16进制数
━━━━━━━━━━━━━━━━━━━━━━━━━━
char c, s[20], *p;
int a=1234, *i;
float f=3.141592653589;
double x=0.12345678987654321;
p="How do you do";
strcpy(s, "Hello, Comrade");
*i=12;
c='\x41';
printf("a=%d\n", a); /*结果输出十进制整数a=1234*/
printf("a=%6d\n", a); /*结果输出6位十进制数a= 1234*/
printf("a=%06d\n", a); /*结果输出6位十进制数a=001234*/
printf("a=%2d\n", a); /*a超过2位, 按实际值输出a=1234*/
printf("*i=%4d\n", *i); /*输出4位十进制整数*i= 12*/
printf("*i=%-4d\n", *i); /*输出左对齐4位十进制整数*i=12*/
printf("i=%p\n", i); /*输出地址i=06E4*/
printf("f=%f\n", f); /*输出浮点数f=3.141593*/
printf("f=6.4f\n", f); /*输出6位其中小数点后4位的浮点数f=3.1416*/
printf("x=%lf\n", x); /*输出长浮点数x=0.123457*/
printf("x=%18.16lf\n", x);/*输出18位其中小数点后16位的长浮点数x=0.1234567898765432*/
printf("c=%c\n", c); /*输出字符c=A*/
printf("c=%x\n", c); /*输出字符的ASCII码值c=41*/
printf("s[]=%s\n", s); /*输出数组字符串s[]=Hello, Comrade*/
printf("s[]=%6.9s\n", s);/*输出最多9个字符的字符串s[]=Hello,Co*/
printf("s=%p\n", s); /*输出数组字符串首字符地址s=FFBE*/
printf("*p=%s\n", p); /* 输出指针字符串p=How do you do*/
printf("p=%p\n", p); /*输出指针的值p=0194*/
上面结果中的地址值在不同计算机上可能不同。
1. 格式化规定符
━━━━━━━━━━━━━━━━━━━━━━━━━━
符号 作用
──────────────────────────
%d 十进制有符号整数
%u 十进制无符号整数
%f 浮点数
%s 字符串
%c 单个字符
%p 指针的值
%e 指数形式的浮点数
%x, %X 无符号以十六进制表示的整数
%0 无符号以八进制表示的整数
%g 自动选择合适的表示法
━━━━━━━━━━━━━━━━━━━━━━━━━━
说明:
(1). 可以在"%"和字母之间插进数字表示最大场宽。
例如: %3d 表示输出3位整型数, 不够3位右对齐。
%9.2f表示输出场宽为9的浮点数, 其中小数位为2, 整数位为6,
小数点占一位, 不够9位右对齐。
%8s 表示输出8个字符的字符串, 不够8个字符右对齐。
如果字符串的长度、或整型数位数超过说明的场宽, 将按其实际长度输出。但对浮点数, 若整数部分位数超过了说明的整数位宽度, 将按实际整数位输出; 若小数部分位数超过了说明的小数位宽度, 则按说明的宽度以四舍五入输出。
另外, 若想在输出值前加一些0, 就应在场宽项前加个0。
例如: %04d 表示在输出一个小于4位的数值时, 将在前面补0使其总宽度为4位。
如果用浮点数表示字符或整型量的输出格式, 小数点后的数字代表最大宽度, 小数点前的数字代表最小宽度。
例如: %6.9s 表示显示一个长度不小于6且不大于9的字符串。若大于9, 则第9个字符以后的内容将被删除。
(2). 可以在"%"和字母之间加小写字母l, 表示输出的是长型数。
例如: %ld 表示输出long整数
%lf 表示输出double浮点数
(3). 可以控制输出左对齐或右对齐, 即在"%"和字母之间加入一个"-" 号可说明输出为左对齐, 否则为右对齐。
例如: %-7d 表示输出7位整数左对齐
%-10s 表示输出10个字符左对齐
2. 一些特殊规定字符
━━━━━━━━━━━━━━━━━━━━━━━━━━
字符 作用
──────────────────────────
\n 换行
\f 清屏并换页
\r 回车
\t Tab符
\xhh 表示一个ASCII码用16进表示, 其中hh是1到2个16进制数
━━━━━━━━━━━━━━━━━━━━━━━━━━
char c, s[20], *p;
int a=1234, *i;
float f=3.141592653589;
double x=0.12345678987654321;
p="How do you do";
strcpy(s, "Hello, Comrade");
*i=12;
c='\x41';
printf("a=%d\n", a); /*结果输出十进制整数a=1234*/
printf("a=%6d\n", a); /*结果输出6位十进制数a= 1234*/
printf("a=%06d\n", a); /*结果输出6位十进制数a=001234*/
printf("a=%2d\n", a); /*a超过2位, 按实际值输出a=1234*/
printf("*i=%4d\n", *i); /*输出4位十进制整数*i= 12*/
printf("*i=%-4d\n", *i); /*输出左对齐4位十进制整数*i=12*/
printf("i=%p\n", i); /*输出地址i=06E4*/
printf("f=%f\n", f); /*输出浮点数f=3.141593*/
printf("f=6.4f\n", f); /*输出6位其中小数点后4位的浮点数f=3.1416*/
printf("x=%lf\n", x); /*输出长浮点数x=0.123457*/
printf("x=%18.16lf\n", x);/*输出18位其中小数点后16位的长浮点数x=0.1234567898765432*/
printf("c=%c\n", c); /*输出字符c=A*/
printf("c=%x\n", c); /*输出字符的ASCII码值c=41*/
printf("s[]=%s\n", s); /*输出数组字符串s[]=Hello, Comrade*/
printf("s[]=%6.9s\n", s);/*输出最多9个字符的字符串s[]=Hello,Co*/
printf("s=%p\n", s); /*输出数组字符串首字符地址s=FFBE*/
printf("*p=%s\n", p); /* 输出指针字符串p=How do you do*/
printf("p=%p\n", p); /*输出指针的值p=0194*/
上面结果中的地址值在不同计算机上可能不同。
2008年7月25日星期五
字体颜色渐变消失
<script language="JavaScript">
var col = new Array();
col[15] = '#000000';
col[14] = '#111111';
col[13] = '#222222';
col[12] = '#333333';
col[11] = '#444444';
col[10] = '#555555';
col[9] = '#666666';
col[8] = '#777777';
col[7] = '#888888';
col[6] = '#999999';
col[5] = '#AAAAAA';
col[4] = '#BBBBBB';
col[3] = '#CCCCCC';
col[2] = '#DDDDDD';
col[1] = '#EEEEEE';
col[0] = '#FFFFFF';
var i = col.length;
function Over()
{
if (i>=0) {i--;td.style.color=col[i];}
setTimeout('Over()',100);//渐变
}
</script>
<body>
<table><tbody><tr><td id="td" onmouseover="Over()">鼠标放上看效果</td></tr></tbody></table>
</body>
var col = new Array();
col[15] = '#000000';
col[14] = '#111111';
col[13] = '#222222';
col[12] = '#333333';
col[11] = '#444444';
col[10] = '#555555';
col[9] = '#666666';
col[8] = '#777777';
col[7] = '#888888';
col[6] = '#999999';
col[5] = '#AAAAAA';
col[4] = '#BBBBBB';
col[3] = '#CCCCCC';
col[2] = '#DDDDDD';
col[1] = '#EEEEEE';
col[0] = '#FFFFFF';
var i = col.length;
function Over()
{
if (i>=0) {i--;td.style.color=col[i];}
setTimeout('Over()',100);//渐变
}
</script>
<body>
<table><tbody><tr><td id="td" onmouseover="Over()">鼠标放上看效果</td></tr></tbody></table>
</body>
2008年7月24日星期四
2008年7月21日星期一
自制硝化细菌
自制硝化细菌
硝化细菌,孝母菌,乳酸菌,枯草菌4菌开缸具体步骤。
4菌开缸——培养的方法:
a、首先,咱们要准备好各种器材和菌种。器材按照上面的要求在鱼店购买。菌种就要多跑几个地方了,其中:
硝化菌要在鱼店里买质量可靠的干粉状的,实在买不到就算了,我们可以慢慢的培养;
酵母菌去商场里买那些发面用的纯酵母粉;《安其酵母》
乳酸菌就用活性酸奶来替代,记得买那些号称有多少多少亿个有益菌的、没有经过灭菌处理的名牌酸奶,
枯草菌就要使用从药店里买来的一种小儿消化药——“妈咪爱”。2元一袋。
b、然后,就应该给咱们的装了100升已经晒好的水的鱼缸来个大扫除,把鱼缸、过滤器、过滤棉、玻璃环、活性炭(或麦饭石)、水泵、气泵、加热棒、沙子、石头、草等等东西通通洗干净然后用高锰酸钾浸泡十几分钟,消消毒,然后安装在合适的位置,然后在缸里加入新水,打开气泵、水泵、加热棒什么的,用十万分之三的高锰酸钾消毒,浸泡、擦洗鱼缸。此时可以顺便用开水把鱼缸水温升到28度左右;
c、接着直接投放三片捻碎的维生素C或高级水质安定剂,终止高锰酸钾的反应。此时就可以用这些淡红色或黄褐色的水投菌开缸了。这些颜色几天内就分解完毕了,不用理会。
d、这时,可以把干粉硝化菌(10克)、纯酵母粉一汤匙(5-10克)、活性酸奶一汤匙(5-10克)以及“妈咪爱”一、两小袋(1-2克)用缸里的温水尽量完全化开,把比较清澈的部分倒回缸里,把剩下的残渣扔掉或倒入过滤槽这些不明显的地方都行。这样,咱们就完成了“播种”的过程;这个时候的鱼缸通常是一片雾蒙蒙的,甚至是伸手不见五指,这是菌种在飘荡,没关系,几天内就会清澈的;此时也可以按照太原斑竹的办法先行发酵,然后投菌。
e、下面,当然是给细菌们找食物啦。既然缸里有100升的水,那么就放养4条5-6厘米长的小鱼吧!它们是闯缸的先锋,所以必须身强力壮、不怕死。小鱼进入鱼缸之前要用十万分之三的高锰酸钾溶液浸泡10分钟消毒,避免带着病菌进入鱼缸;然后咱们就等待吧。假如水质在第二天浑浊了,就适当换点水。就这样等待 3天,不用喂。
f、这3天里,通常会逐渐清澈,有时也有复混出现,可以适当换水。
g、第4天,假如水质变的清澈无比(有时侯第2天就水清了,但还是要等待到第4天再操作,有时要到第7天,总之等到第4天,一般水会清澈很多),那么水系统就开始了良好的历程!这时要继续测试一下微生物过滤系统的应变能力。只要投喂就可以了。投喂量控制在2-3分钟内吃完为好。然后继续等待3天;期间稍有浑浊要仔细观察,只要没有腥臭味散发出来就不必换水;
h、第7天,假如水质清澈无比,这时我们可以把比较娇贵的鱼请进鱼缸了。先换点水,然后少放几条,少量喂食(1分钟内吃完),观察3、4天,再继续放另外一批,食物也逐渐增加点。
i、假如想更加稳妥些,那么在第7天可以多投放些食物或创缸鱼,然后继续等待3-4天,此时的水质更加稳定了。也就可以把你心爱的鱼买回来了。就这样每3-4天可以增加一批新鱼,直到达到标准。
j、新鱼买回来要在小缸里饲养几天,可以观察一下是否有病虫害,并适当消毒后才能搬进主缸,搬家时必须把两个缸的水质调节成一样的,方法很简单,用一根气泵用的气管把主缸的水缓慢的导入小缸里,并不断排掉小缸里的水,直至两个缸的水温、水质几乎一样;然后就可以把新鱼捞入主缸了。这个叫“过水”。
k、就这样我们以后每个星期给鱼缸换1/5到1/4的水,配合“定时”、“定量”、“定点”的喂食、换水、洗沙等工作,就可以获得长期稳定的“好”水了!到这里我们就完成了“硝化系统”的建设了。
这时,鱼的粪便和食物残渣会在几十个小时内被分解干净,配合良好的维护工作,水质就能长期保持良好状态了,这个过程叫“氧化分解”过程。
但是,这样的“好”水里仍然有些潜在的“半有害物质”(就是硝酸盐)的存在,假如它们长期积聚过多就会危害鱼们,因此必须要通过换水来稀释它们,维持“好”水的稳定。良好的维护的意义就在此了
硝化细菌,孝母菌,乳酸菌,枯草菌4菌开缸具体步骤。
4菌开缸——培养的方法:
a、首先,咱们要准备好各种器材和菌种。器材按照上面的要求在鱼店购买。菌种就要多跑几个地方了,其中:
硝化菌要在鱼店里买质量可靠的干粉状的,实在买不到就算了,我们可以慢慢的培养;
酵母菌去商场里买那些发面用的纯酵母粉;《安其酵母》
乳酸菌就用活性酸奶来替代,记得买那些号称有多少多少亿个有益菌的、没有经过灭菌处理的名牌酸奶,
枯草菌就要使用从药店里买来的一种小儿消化药——“妈咪爱”。2元一袋。
b、然后,就应该给咱们的装了100升已经晒好的水的鱼缸来个大扫除,把鱼缸、过滤器、过滤棉、玻璃环、活性炭(或麦饭石)、水泵、气泵、加热棒、沙子、石头、草等等东西通通洗干净然后用高锰酸钾浸泡十几分钟,消消毒,然后安装在合适的位置,然后在缸里加入新水,打开气泵、水泵、加热棒什么的,用十万分之三的高锰酸钾消毒,浸泡、擦洗鱼缸。此时可以顺便用开水把鱼缸水温升到28度左右;
c、接着直接投放三片捻碎的维生素C或高级水质安定剂,终止高锰酸钾的反应。此时就可以用这些淡红色或黄褐色的水投菌开缸了。这些颜色几天内就分解完毕了,不用理会。
d、这时,可以把干粉硝化菌(10克)、纯酵母粉一汤匙(5-10克)、活性酸奶一汤匙(5-10克)以及“妈咪爱”一、两小袋(1-2克)用缸里的温水尽量完全化开,把比较清澈的部分倒回缸里,把剩下的残渣扔掉或倒入过滤槽这些不明显的地方都行。这样,咱们就完成了“播种”的过程;这个时候的鱼缸通常是一片雾蒙蒙的,甚至是伸手不见五指,这是菌种在飘荡,没关系,几天内就会清澈的;此时也可以按照太原斑竹的办法先行发酵,然后投菌。
e、下面,当然是给细菌们找食物啦。既然缸里有100升的水,那么就放养4条5-6厘米长的小鱼吧!它们是闯缸的先锋,所以必须身强力壮、不怕死。小鱼进入鱼缸之前要用十万分之三的高锰酸钾溶液浸泡10分钟消毒,避免带着病菌进入鱼缸;然后咱们就等待吧。假如水质在第二天浑浊了,就适当换点水。就这样等待 3天,不用喂。
f、这3天里,通常会逐渐清澈,有时也有复混出现,可以适当换水。
g、第4天,假如水质变的清澈无比(有时侯第2天就水清了,但还是要等待到第4天再操作,有时要到第7天,总之等到第4天,一般水会清澈很多),那么水系统就开始了良好的历程!这时要继续测试一下微生物过滤系统的应变能力。只要投喂就可以了。投喂量控制在2-3分钟内吃完为好。然后继续等待3天;期间稍有浑浊要仔细观察,只要没有腥臭味散发出来就不必换水;
h、第7天,假如水质清澈无比,这时我们可以把比较娇贵的鱼请进鱼缸了。先换点水,然后少放几条,少量喂食(1分钟内吃完),观察3、4天,再继续放另外一批,食物也逐渐增加点。
i、假如想更加稳妥些,那么在第7天可以多投放些食物或创缸鱼,然后继续等待3-4天,此时的水质更加稳定了。也就可以把你心爱的鱼买回来了。就这样每3-4天可以增加一批新鱼,直到达到标准。
j、新鱼买回来要在小缸里饲养几天,可以观察一下是否有病虫害,并适当消毒后才能搬进主缸,搬家时必须把两个缸的水质调节成一样的,方法很简单,用一根气泵用的气管把主缸的水缓慢的导入小缸里,并不断排掉小缸里的水,直至两个缸的水温、水质几乎一样;然后就可以把新鱼捞入主缸了。这个叫“过水”。
k、就这样我们以后每个星期给鱼缸换1/5到1/4的水,配合“定时”、“定量”、“定点”的喂食、换水、洗沙等工作,就可以获得长期稳定的“好”水了!到这里我们就完成了“硝化系统”的建设了。
这时,鱼的粪便和食物残渣会在几十个小时内被分解干净,配合良好的维护工作,水质就能长期保持良好状态了,这个过程叫“氧化分解”过程。
但是,这样的“好”水里仍然有些潜在的“半有害物质”(就是硝酸盐)的存在,假如它们长期积聚过多就会危害鱼们,因此必须要通过换水来稀释它们,维持“好”水的稳定。良好的维护的意义就在此了
2008年7月16日星期三
video chat
1. http://code.google.com/p/openmeetings/
openmeetings
Multi-Language Cross-Platform Customizable Video-Conferencing and Collaboration
2. http://blog.csdn.net/lizzz/archive/2008/01/26/2066846.aspx
Red5+OpenOffice+OpenMeetings架设视频会议网络
3. http://osflash.org/red5
Red5 : Open Source Flash Server
4. http://www.red5chat.com/
Open source video chat,open source webcam chat Red5 Video chat
Features of Red5 Video chat:
-- No plugin to be installed: Chat clients do not need to install ANY plugins, software or ActiveX since the solution is based on Flash 9 player !
-- Video webcam: webcam live streaming through FLASH player: no plugin to be installed
-- Audio chat: Audio/micro live streaming through FLASH player: no plugin to be installed
-- Private Messages: send private messages to selected users
-- Talkie Walkie function: 1 person can talk at the same time
-- Registration process: Users must register before enter the video chat !
-- No duplicate entries: user cannot open 2 chats with the same nickname
-- Info user: you can get infos about a selected users
-- Colors text: you can change the appareance/colors of the chat text
-- Full customized design: you can easily change the chat design such colors, texts, layout etc...
-- Multi langage chat: you can easily translate the chat to your langage
-- admin users: you can login as ADMIN user and get FULL right on the chat !
-- is watching me feature: you can know WHO is watching at your webcam !
Kick/Ban functions
-- Kick or Ban functions: you can kick an user or ban it from the chat
-- Microphone level: shows the level of the microphone activity for Audio adjustment.
-- login/password recover: users can retrieve login/password if they have forgotten
-- Bad words filter: users cannot send messages containing badwords
-- Full documented source code: the applications comes with FULL documented code source, so you can re-compile it and change it as you wnat: you can change colors, outlines, graphics or add new featutes !
-- Based on RED5/Flash: the Video Flash Chat is based on Open source solutions: RED5, a FREE alternative to Flash Media Server and Flash, which allows you to easily modify the layout of the application.
-- 4 webcams: You can choose between viewing 1 or 4 webcams at once !
-- Invite for chat: Invitation for private chat
-- Smileys: emoticons included
-- Ignore function: you can choose to ignore an user
-- Video talk function: Push video messages
-- Rooms: Room managment
5. http://mirror.optus.net/sourceforge/
sourceforge website mirror
openmeetings
Multi-Language Cross-Platform Customizable Video-Conferencing and Collaboration
2. http://blog.csdn.net/lizzz/archive/2008/01/26/2066846.aspx
Red5+OpenOffice+OpenMeetings架设视频会议网络
3. http://osflash.org/red5
Red5 : Open Source Flash Server
4. http://www.red5chat.com/
Open source video chat,open source webcam chat Red5 Video chat
Features of Red5 Video chat:
-- No plugin to be installed: Chat clients do not need to install ANY plugins, software or ActiveX since the solution is based on Flash 9 player !
-- Video webcam: webcam live streaming through FLASH player: no plugin to be installed
-- Audio chat: Audio/micro live streaming through FLASH player: no plugin to be installed
-- Private Messages: send private messages to selected users
-- Talkie Walkie function: 1 person can talk at the same time
-- Registration process: Users must register before enter the video chat !
-- No duplicate entries: user cannot open 2 chats with the same nickname
-- Info user: you can get infos about a selected users
-- Colors text: you can change the appareance/colors of the chat text
-- Full customized design: you can easily change the chat design such colors, texts, layout etc...
-- Multi langage chat: you can easily translate the chat to your langage
-- admin users: you can login as ADMIN user and get FULL right on the chat !
-- is watching me feature: you can know WHO is watching at your webcam !
Kick/Ban functions
-- Kick or Ban functions: you can kick an user or ban it from the chat
-- Microphone level: shows the level of the microphone activity for Audio adjustment.
-- login/password recover: users can retrieve login/password if they have forgotten
-- Bad words filter: users cannot send messages containing badwords
-- Full documented source code: the applications comes with FULL documented code source, so you can re-compile it and change it as you wnat: you can change colors, outlines, graphics or add new featutes !
-- Based on RED5/Flash: the Video Flash Chat is based on Open source solutions: RED5, a FREE alternative to Flash Media Server and Flash, which allows you to easily modify the layout of the application.
-- 4 webcams: You can choose between viewing 1 or 4 webcams at once !
-- Invite for chat: Invitation for private chat
-- Smileys: emoticons included
-- Ignore function: you can choose to ignore an user
-- Video talk function: Push video messages
-- Rooms: Room managment
5. http://mirror.optus.net/sourceforge/
sourceforge website mirror
2008年7月4日星期五
优秀的J2ME网站集锦
http://java.sun.com/javame/
http://www.theserverside.com/
http://www.onhandset.com/
http://billday.com/j2me/
http://java.sun.com/j2me/index.jsp
SUN公司J2ME平台的官方站点,许多权威资料都可以在此找到。
http://jcp.org/en/jsr/tech?listBy=1&listByType=platform
J2ME平台的所有JSR规范,这是jcp的官方站点。
http://www.microjava.com
非常全面的j2me开发站点,内容丰富,包括各种示例,还能找到许多设备的资料。
http://www.onjava.com/topics/java/Wireless_Java
O'Reilly onjava的j2me版,以文章教程为主。
http://www.corej2me.com/
以书籍为主的j2me站点
http://www.wirelessdevnet.com/
又一个教程/下载都很丰富的j2me开发站点
http://www.mobilegd.com/
主要以J2ME游戏开发为主的站点
中文:相对于英文站点,国内专注于J2ME的技术站点还特别少,重点推荐以下站点:
http://www-128.ibm.com/developerworks/cn/java/index.html
IBM开发者社区也有不少不错的J2ME教程。
http://j2me1.motorola.com.cn/index_ch.asp
MOTO的中文开发站点,可以下载到moto的SDK
各大手机厂商的开发站点:
Nokia: http://www.forum.nokia.com
Moto: http://www.motocoder.com
Sony-Ericcson: http://developer.sonyericsson.com/site/global/home/p_home.jsp
http://java.sun.com/
Java Software 网站,其中有最新的 Java 技术、产品信息、新闻和功能信息。
http://java.sun.com/products/jdk/1.2/index.html
JDK 1.2 产品和下载页
http://java.sun.com/docs
Java 平台文档提供对白皮书、Java 教程和其它文档的访问。
http://developer.java.sun.com/
Java 开发人员连接网站(需要免费注册)。其它技术信息、新闻和功能;用户论坛;支持信息及其它。
http://java.sun.com/products/
Java 技术产品和 API
http://www.j2meforums.com
J2ME论坛
jacky推荐
open source j2me UI API
http://j2me-mwt.sourceforge.net/
http://www.sourceforge.net/projects/microewt
http://www.synclast.com/ui_api.jsp
J2ME & Gaming - eBook
MIDlet Game Development Kit - MGDK
Open Source J2ME Isometric Engine - isoj2me
Open Source J2ME Game - Bomber
http://www.j2mepolish.org/cms/
Antenna
http://bbs.zdnet.com.cn/viewthread.php?tid=109474&highlight=j2me
Antenna与j2me打包
http://q.yesky.com/group/200195
http://www.theserverside.com/
http://www.onhandset.com/
http://billday.com/j2me/
http://java.sun.com/j2me/index.jsp
SUN公司J2ME平台的官方站点,许多权威资料都可以在此找到。
http://jcp.org/en/jsr/tech?listBy=1&listByType=platform
J2ME平台的所有JSR规范,这是jcp的官方站点。
http://www.microjava.com
非常全面的j2me开发站点,内容丰富,包括各种示例,还能找到许多设备的资料。
http://www.onjava.com/topics/java/Wireless_Java
O'Reilly onjava的j2me版,以文章教程为主。
http://www.corej2me.com/
以书籍为主的j2me站点
http://www.wirelessdevnet.com/
又一个教程/下载都很丰富的j2me开发站点
http://www.mobilegd.com/
主要以J2ME游戏开发为主的站点
中文:相对于英文站点,国内专注于J2ME的技术站点还特别少,重点推荐以下站点:
http://www-128.ibm.com/developerworks/cn/java/index.html
IBM开发者社区也有不少不错的J2ME教程。
http://j2me1.motorola.com.cn/index_ch.asp
MOTO的中文开发站点,可以下载到moto的SDK
各大手机厂商的开发站点:
Nokia: http://www.forum.nokia.com
Moto: http://www.motocoder.com
Sony-Ericcson: http://developer.sonyericsson.com/site/global/home/p_home.jsp
http://java.sun.com/
Java Software 网站,其中有最新的 Java 技术、产品信息、新闻和功能信息。
http://java.sun.com/products/jdk/1.2/index.html
JDK 1.2 产品和下载页
http://java.sun.com/docs
Java 平台文档提供对白皮书、Java 教程和其它文档的访问。
http://developer.java.sun.com/
Java 开发人员连接网站(需要免费注册)。其它技术信息、新闻和功能;用户论坛;支持信息及其它。
http://java.sun.com/products/
Java 技术产品和 API
http://www.j2meforums.com
J2ME论坛
jacky推荐
open source j2me UI API
http://j2me-mwt.sourceforge.net/
http://www.sourceforge.net/projects/microewt
http://www.synclast.com/ui_api.jsp
J2ME & Gaming - eBook
MIDlet Game Development Kit - MGDK
Open Source J2ME Isometric Engine - isoj2me
Open Source J2ME Game - Bomber
http://www.j2mepolish.org/cms/
Antenna
http://bbs.zdnet.com.cn/viewthread.php?tid=109474&highlight=j2me
Antenna与j2me打包
http://q.yesky.com/group/200195
2008年7月1日星期二
isafer 和apache冲突
APACHE 官方文档:
Win32DisableAcceptEx 指令
说明 使用accept()代替AcceptEx()接受网络链接
语法 Win32DisableAcceptEx
默认值 AcceptEx()是默认的,使用这个指令将禁用它。
作用域 server config
状态 MPM
模块 mpm_winnt
兼容性 仅在 Apache 2.0.49 及以后的版本中可用
AcceptEx()是一个微软的WinSock2 API ,通过使用BSD风格的accept() API提供了性能改善。一些流行的
Windows产品,比如防病毒软件或虚拟专用网络软件,会干扰AcceptEx()的正确操作。如果你遇到类似于如下的错误:
[error] (730038)An operation was attempted on something that is not a
socket.: winnt_accept: AcceptEx failed. Attempting to recover.
你就需要使用这个指令来禁止使用AcceptEx() 。
關掉 AcceptEx() 的方式只要在 httpd.conf 找到 區段,加入
Win32DisableAcceptEx 就可以了。
Win32DisableAcceptEx #加入這一行
ThreadsPerChild 250
MaxRequestsPerChild 0
然後重新啟動 Apache
Win32DisableAcceptEx 指令
说明 使用accept()代替AcceptEx()接受网络链接
语法 Win32DisableAcceptEx
默认值 AcceptEx()是默认的,使用这个指令将禁用它。
作用域 server config
状态 MPM
模块 mpm_winnt
兼容性 仅在 Apache 2.0.49 及以后的版本中可用
AcceptEx()是一个微软的WinSock2 API ,通过使用BSD风格的accept() API提供了性能改善。一些流行的
Windows产品,比如防病毒软件或虚拟专用网络软件,会干扰AcceptEx()的正确操作。如果你遇到类似于如下的错误:
[error] (730038)An operation was attempted on something that is not a
socket.: winnt_accept: AcceptEx failed. Attempting to recover.
你就需要使用这个指令来禁止使用AcceptEx() 。
關掉 AcceptEx() 的方式只要在 httpd.conf 找到
Win32DisableAcceptEx 就可以了。
Win32DisableAcceptEx #加入這一行
ThreadsPerChild 250
MaxRequestsPerChild 0
然後重新啟動 Apache
2008年6月27日星期五
red5 + php
http://www.cnblogs.com/HappyQQ/archive/2008/05/31/1211078.html
Open Source Flash
http://www.openstudio.fr/jQuery-Multimedia-Portfolio.html
This plugin for jQuery will automatically detect the extension of each media and apply the adapted player.
Open Source Flash
http://www.openstudio.fr/jQuery-Multimedia-Portfolio.html
This plugin for jQuery will automatically detect the extension of each media and apply the adapted player.
2008年6月24日星期二
howto备份和移植PLONE
plone站点数据史保存在什么地方,怎样备份和移植plone站点?
Plone站点所有内容是保存在 Data.fs 文件理,这个文件位于 var 目录 (具体定位可以搜索 Data.fs文件). 这个数据库也通常作为zope的对象数据库 (ZODB)。
这个文件是一个完整的数据库,可以通过简单的COPY来作备份。备份时不必停下plone站点,但如果是访问量非常大的站点,有可能在备份期间,有数据更新,这时可以通过 repozo.py script 来进行自动调度备份。
如果你要移植plone站点,在作Data.fs 备份的同时,你还要备份 Products 目录,并且为避免麻烦,要确保各产品的版本在移植后是一致的。移植时,将 Data.fs 文件拷贝过去,然后将产品COPY过去。
提示:在从Windows移植Plone到LInux 时必须保证产品文件的权限有执行权限(我自己在移植时因为忽略了这点,结果产品移植就是不成功,为此在网上搜索了三天资料未果,结果还是自己仔细比对分析,发现时权限的问题),否则你的产品就不会出现在plone的可添加产品列表中。
Plone站点所有内容是保存在 Data.fs 文件理,这个文件位于 var 目录 (具体定位可以搜索 Data.fs文件). 这个数据库也通常作为zope的对象数据库 (ZODB)。
这个文件是一个完整的数据库,可以通过简单的COPY来作备份。备份时不必停下plone站点,但如果是访问量非常大的站点,有可能在备份期间,有数据更新,这时可以通过 repozo.py script 来进行自动调度备份。
如果你要移植plone站点,在作Data.fs 备份的同时,你还要备份 Products 目录,并且为避免麻烦,要确保各产品的版本在移植后是一致的。移植时,将 Data.fs 文件拷贝过去,然后将产品COPY过去。
提示:在从Windows移植Plone到LInux 时必须保证产品文件的权限有执行权限(我自己在移植时因为忽略了这点,结果产品移植就是不成功,为此在网上搜索了三天资料未果,结果还是自己仔细比对分析,发现时权限的问题),否则你的产品就不会出现在plone的可添加产品列表中。
2008年6月19日星期四
FileZilla源代码分析
分析版本:
FileZilla_3.0.11_src.tar.bz2
FileZilla客户端实现分析
http://davidripple.blogchina.com/davidripple/2482012.html
FileZilla_3.0.11_src.tar.bz2
FileZilla客户端实现分析
http://davidripple.blogchina.com/davidripple/2482012.html
2008年6月16日星期一
Mg2 分析
mg2
|-includes
|-exif.php
|-mg2_functions.php
|-mg2_version.php
|-mg2admin_functions.php
|-skins
|-admin.php 管理入口
|-index.php 首页前端入口
|-md2_install.php 安装页面入口
|-upgrade.php 升级页面入口 ,用来升级到 0.5.0
md2_install.php
1-1) 判断是否已经安装,即是否存在文件mg2_settings.php
1-2) 判断是否有当前目录和pictures目录的读写权限。前者用于存放配置文件mg2_settings.php,后者用于存放上传的图片。
1-3) 判断系统的几个主要文件是否存在,确认系统能正常工作;
1-4) 判断GD库的版本是否大于等于2;
2-1) 判断语言包目录是否存在,让用户选择安装语言;
3-1) 保存各项具体配置;
3-2) 将各项配置信息统一写到文件mg2_settings.php中;
判断是否已经安装,通过判断文件mg2_settings.php 是否是一个文件。
------------------------------
if (is_file("mg2_settings.php")) {
......
------------------------------
判断是否有 pictures 目录的读写权限
------------------------------
@rmdir("pictures/x");
if (@mkdir("pictures/x")) {
@rmdir("pictures/x");
} else {echo "ERROR: Cannot write to 'pictures' folder. Chmod 'pictures' to 777 before continuing!";exit();}
------------------------------
|-includes
|-exif.php
|-mg2_functions.php
|-mg2_version.php
|-mg2admin_functions.php
|-skins
|-admin.php 管理入口
|-index.php 首页前端入口
|-md2_install.php 安装页面入口
|-upgrade.php 升级页面入口 ,用来升级到 0.5.0
md2_install.php
1-1) 判断是否已经安装,即是否存在文件mg2_settings.php
1-2) 判断是否有当前目录和pictures目录的读写权限。前者用于存放配置文件mg2_settings.php,后者用于存放上传的图片。
1-3) 判断系统的几个主要文件是否存在,确认系统能正常工作;
1-4) 判断GD库的版本是否大于等于2;
2-1) 判断语言包目录是否存在,让用户选择安装语言;
3-1) 保存各项具体配置;
3-2) 将各项配置信息统一写到文件mg2_settings.php中;
判断是否已经安装,通过判断文件mg2_settings.php 是否是一个文件。
------------------------------
if (is_file("mg2_settings.php")) {
......
------------------------------
判断是否有 pictures 目录的读写权限
------------------------------
@rmdir("pictures/x");
if (@mkdir("pictures/x")) {
@rmdir("pictures/x");
} else {echo "ERROR: Cannot write to 'pictures' folder. Chmod 'pictures' to 777 before continuing!";exit();}
------------------------------
2008年6月12日星期四
2008年6月11日星期三
系统变慢的三种原因和处理方法
http://hehe2.net/linuxhowto/3-reasons-why-your-system-might-be-slow/
1. CPU 资源被占用 --> top => renice 20 26210 => kill 26210
2. 物理内存几乎被用完 --> free -m => top => shutdown the program that’s using the most memory.
3. 大量的IO操作 --> top => atop => ionice -p30956 -n7
1. CPU 资源被占用 --> top => renice 20 26210 => kill 26210
2. 物理内存几乎被用完 --> free -m => top => shutdown the program that’s using the most memory.
3. 大量的IO操作 --> top => atop => ionice -p30956 -n7
2008年6月10日星期二
Build with Visual Studio Express 2008, JGE , PSP
http://www.jetcube.eu/archives/2008/02/entry_74.html
Build with Visual Studio Express 2008, JGE , PSP
Build with Visual Studio Express 2008, JGE , PSP
离线安装Visual C++ Express
0.下载安装.Net Framework 2.0
http://www.microsoft.com/downloads/info.aspx?na=90&p=&SrcDisplayLang=zh-cn&SrcCategoryId=&SrcFamilyId=0856eacb-4362-4b0d-8edd-aab15c5e04f5&u=http%3a%2f%2fdownload.microsoft.com%2fdownload%2f5%2f6%2f7%2f567758a3-759e-473e-bf8f-52154438565a%2fdotnetfx.exe
1.直接下载Microsoft .NET Framework 2.0 语言包 - 简体中文(langpack.exe):http://go.microsoft.com/fwlink/?LinkId=54024&clcid=0x804
2.安装langpack.exe
3.直接下载安装文件客户端(vcsetup.exe):http://go.microsoft.com/fwlink/?Linkid=51410&clcid=0x804
4.直接下载Microsoft Visual C++ 2005 Express Edition - CHS(Ixpvc.exe):http://go.microsoft.com/fwlink/?LinkId=51417&clcid=0x804
5.解压缩vcsetup.exe和Ixpvc.exe到某个目录。
6.运行解压缩出来的setup.exe安装。
7.下载并安装SP1:http://download.microsoft.com/download/7/7/3/7737290f-98e8-45bf-9075-85cc6ae34bf1/vs80sp1-kb926748-x86-intl.exe
8.下载并安装 PSDK platform SDK
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/XPSP2FULLInstall.htm
or iso image
http://download.microsoft.com/download/9/7/a/97a5ac16-69ae-4672-b93e-40d66d77b278/5.2.3790.2075.51.PlatformSDK_Svr2003R2_rtm.img
or
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/XPSP2FULLInstall.htm
P.S Express版本与Visual Studio个版本之间的功能差异比较详见:http://msdn2.microsoft.com/en-us/library/hs24szh9(vs.80).aspx
http://www.microsoft.com/downloads/info.aspx?na=90&p=&SrcDisplayLang=zh-cn&SrcCategoryId=&SrcFamilyId=0856eacb-4362-4b0d-8edd-aab15c5e04f5&u=http%3a%2f%2fdownload.microsoft.com%2fdownload%2f5%2f6%2f7%2f567758a3-759e-473e-bf8f-52154438565a%2fdotnetfx.exe
1.直接下载Microsoft .NET Framework 2.0 语言包 - 简体中文(langpack.exe):http://go.microsoft.com/fwlink/?LinkId=54024&clcid=0x804
2.安装langpack.exe
3.直接下载安装文件客户端(vcsetup.exe):http://go.microsoft.com/fwlink/?Linkid=51410&clcid=0x804
4.直接下载Microsoft Visual C++ 2005 Express Edition - CHS(Ixpvc.exe):http://go.microsoft.com/fwlink/?LinkId=51417&clcid=0x804
5.解压缩vcsetup.exe和Ixpvc.exe到某个目录。
6.运行解压缩出来的setup.exe安装。
7.下载并安装SP1:http://download.microsoft.com/download/7/7/3/7737290f-98e8-45bf-9075-85cc6ae34bf1/vs80sp1-kb926748-x86-intl.exe
8.下载并安装 PSDK platform SDK
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/XPSP2FULLInstall.htm
or iso image
http://download.microsoft.com/download/9/7/a/97a5ac16-69ae-4672-b93e-40d66d77b278/5.2.3790.2075.51.PlatformSDK_Svr2003R2_rtm.img
or
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/XPSP2FULLInstall.htm
P.S Express版本与Visual Studio个版本之间的功能差异比较详见:http://msdn2.microsoft.com/en-us/library/hs24szh9(vs.80).aspx
PSP websites
4 + 5 应该是比较好的开发环境
1. http://www.psp-hacks.com/
2.
PSP 3.71m 开发环境的建立
http://www.xici.net/b902738/d63863130.htm
3.
TOPOC
http://hi.baidu.com/topoc
4. Minimalist PSPSDK for Windows, 应该是当前最好的编译工具集了。可以仿照打造 Ezx/LJ的工具集
http://sourceforge.net/project/showfiles.php?group_id=223830
5. JGE++
http://code.google.com/p/jge/
6.
http://www.jetcube.eu/
1. http://www.psp-hacks.com/
2.
PSP 3.71m 开发环境的建立
http://www.xici.net/b902738/d63863130.htm
3.
TOPOC
http://hi.baidu.com/topoc
4. Minimalist PSPSDK for Windows, 应该是当前最好的编译工具集了。可以仿照打造 Ezx/LJ的工具集
http://sourceforge.net/project/showfiles.php?group_id=223830
5. JGE++
http://code.google.com/p/jge/
6.
http://www.jetcube.eu/
2008年6月8日星期日
PSP2000 Hello world
1. PSP2000 3.60 M33
2. devkitProUpdater-1.4.7.exe 安装到 D:\devkitPro
3. 开始 --> 所有程序 --> devkitPro --> MSys
4. cd /d
5. mkdir /d/PSP
6. cd /d/PSP
7. mkdir HelloPSP2K
8. cd HelloPSP2K
9. vi main.c
10 vi Makefile
11. export PATH=$PATH:/d/devkitPro/devkitPSP/bin
12. make
13. 查看生成的文件
$ ls
EBOOT.PBP Makefile PARAM.SFO hello.elf hello.prx main.c main.o
14. 连接PSP2000到电脑,假设 盘符为 F盘
15. 将文件复制到PSP2000上(F:\PSP\GAME),创建目录 F:\PSP\GAME\hello
将文件:EBOOT.PBP hello.elf hello.prx PARAM.SFO 复制到目录 F:\PSP\GAME\hello
16. 断开USB连接
17. 在游戏下将可以看到 Hello PSP这个新的目录项
18. 运行 Hello PSP , 在屏幕左上角将出现 Hello PSP 字样
至此,终于将PSP2000的开发和运行环境搭建完毕。
2. devkitProUpdater-1.4.7.exe 安装到 D:\devkitPro
3. 开始 --> 所有程序 --> devkitPro --> MSys
4. cd /d
5. mkdir /d/PSP
6. cd /d/PSP
7. mkdir HelloPSP2K
8. cd HelloPSP2K
9. vi main.c
/// Hello PSP - My First App for the PSP
#include <pspkernel.h>
#include <pspdebug.h>
PSP_MODULE_INFO("Hello PSP", 0, 1, 0);
PSP_HEAP_SIZE_KB(20480);
// Exit callback
int exit_callback(int arg1, int arg2, void *common)
{
sceKernelExitGame();
return 0;
}
// Callback thread
int CallbackThread(SceSize args, void *argp)
{
int cbid;
cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
sceKernelRegisterExitCallback(cbid);
sceKernelSleepThreadCB();
return 0;
}
// Sets up the callback thread and returns its thread id
int SetupCallbacks(void)
{
int thid = 0;
thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
if(thid >= 0)
{
sceKernelStartThread(thid, 0, 0);
}
return thid;
}
int main()
{
pspDebugScreenInit();
SetupCallbacks();
pspDebugScreenPrintf("Hello PSP");
sceKernelSleepThread();
return 0;
}
10 vi Makefile
TARGET = hello
OBJS = main.o
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Hello PSP
PSPSDK=$(shell psp-config --pspsdk-path)
BUILD_PRX=1
PSP_FW_VERSION=371
include $(PSPSDK)/lib/build.mak
11. export PATH=$PATH:/d/devkitPro/devkitPSP/bin
12. make
13. 查看生成的文件
$ ls
EBOOT.PBP Makefile PARAM.SFO hello.elf hello.prx main.c main.o
14. 连接PSP2000到电脑,假设 盘符为 F盘
15. 将文件复制到PSP2000上(F:\PSP\GAME),创建目录 F:\PSP\GAME\hello
将文件:EBOOT.PBP hello.elf hello.prx PARAM.SFO 复制到目录 F:\PSP\GAME\hello
16. 断开USB连接
17. 在游戏下将可以看到 Hello PSP这个新的目录项
18. 运行 Hello PSP , 在屏幕左上角将出现 Hello PSP 字样
至此,终于将PSP2000的开发和运行环境搭建完毕。
2008年6月5日星期四
ARM Linux 中断分析
ARM体系结构中,把复位、中断、快速中断等都看作‘异常’,当这些‘异常’发生时,CPU会到固定地址处去找指令,他们对应的地址如下:
地址 异常类型 进入时的工作模式
0x00000000 Reset Supervisor
0x00000004 Und Undefined
0x00000008 Soft interupt Supervisor
0x0000000c Abort(prefetch) Abort
0x00000010 Abort(data) Abort
0x00000014 Reserved Reserved
0x00000018 IRQ IRQ
0x0000001c FIQ FIQ
首先要明确的一点就是,无论内存地址空间是如何映射的,以上这些地址都不会变,比如当有快速中断发生时,ARM将铁定到0X0000001C这个地址处取指令。这也是BOOTLOADER把操作系统引导以后,内存必须重映射的原因!否则操作系统不能真正接管整套系统!
LINUX启动以后要初始化这些区域,初始化代码在main.c中的start_kernel()中,具体是调用函数trap_ini()来实现的。如下面所示(具体可参照entry-armv.S):
.LCvectors: swi SYS_ERROR0
b __real_stubs_start + (vector_undefinstr - __stubs_start)
ldr pc, __real_stubs_start + (.LCvswi - __stubs_start)
b __real_stubs_start + (vector_prefetch - __stubs_start)
b __real_stubs_start + (vector_data - __stubs_start)
b __real_stubs_start + (vector_addrexcptn - __stubs_start)
b __real_stubs_start + (vector_IRQ - __stubs_start)
b __real_stubs_start + (vector_FIQ - __stubs_start)
ENTRY(__trap_init)
stmfd sp!, {r4 - r6, lr}
adr r1, .LCvectors @ set up the vectors
ldmia r1, {r1, r2, r3, r4, r5, r6, ip, lr}
stmia r0, {r1, r2, r3, r4, r5, r6, ip, lr}
add r2, r0, #0x200
adr r0, __stubs_start @ copy stubs to 0x200
adr r1, __stubs_end
1: ldr r3, [r0], #4
str r3, [r2], #4
cmp r0, r1
blt 1b
LOADREGS(fd, sp!, {r4 - r6, pc})
以上可以看出这个函数初始化了中断向量,实际上把相应的跳转指令拷贝到了对应的地址。
当发生中断时,不管是从用户模式还是管理模式调用的,最终都要调用do_IRQ():
__irq_usr: sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ save r0 - r12
ldr r4, .LCirq
add r8, sp, #S_PC
ldmia r4, {r5 - r7} @ get saved PC, SPSR
stmia r8, {r5 - r7} @ save pc, psr, old_r0
stmdb r8, {sp, lr}^
alignment_trap r4, r7, __temp_irq
zero_fp
1: get_irqnr_and_base r0, r6, r5, lr
movne r1, sp
adrsvc ne, lr, 1b
@
@ routine called with r0 = irq number, r1 = struct pt_regs *
@
bne do_IRQ @ 调用do_IRQ来实现具体的中断处理
mov why, #0
get_current_task tsk
b ret_to_user
对于以上代码,在很多文章中都有过分析,这里不再赘述。
Linux每个中断通过一个结构irqdesc来描述,各中断的信息都在这个结构中得以体现:
struct irqdesc {
unsigned int nomask : 1; /* IRQ does not mask in IRQ */
unsigned int enabled : 1; /* IRQ is currently enabled */
unsigned int triggered: 1; /* IRQ has occurred */
unsigned int probing : 1; /* IRQ in use for a probe */
unsigned int probe_ok : 1; /* IRQ can be used for probe */
unsigned int valid : 1; /* IRQ claimable */
unsigned int noautoenable : 1; /* don't automatically enable IRQ */
unsigned int unused :25;
void (*mask_ack)(unsigned int irq); /* Mask and acknowledge IRQ */
void (*mask)(unsigned int irq); /* Mask IRQ */
void (*unmask)(unsigned int irq); /* Unmask IRQ */
struct irqaction *action;
/*
* IRQ lock detection
*/
unsigned int lck_cnt;
unsigned int lck_pc;
unsigned int lck_jif;
};
在具体的ARM芯片中会有很多的中断类型,每一种类型的中断用以上结构来表示:
struct irqdesc irq_desc[NR_IRQS]; /* NR_IRQS根据不同的MCU会有所区别*/
在通过request_irq()函数注册中断服务程序的时候,将会把中断向量和中断服务程序对应起来。
我们来看一下request_irq的源码:
int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
unsigned long irq_flags, const char * devname, void *dev_id)
{
unsigned long retval;
struct irqaction *action;
if (irq >= NR_IRQS || !irq_desc[irq].valid || !handler ||
(irq_flags & SA_SHIRQ && !dev_id))
return -EINVAL;
action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
if (!action) /* 生成action结构*/
return -ENOMEM;
action->handler = handler;
action->flags = irq_flags;
action->mask = 0;
action->name = devname;
action->next = NULL;
action->dev_id = dev_id;
retval = setup_arm_irq(irq, action); /*把中断号irq和action 对应起来*/
if (retval)
kfree(action);
return retval;
}
其中第一个参数irq就是中断向量,第二个参数即是要注册的中断服务程序。很多同仁可能疑惑的是,我们要注册的中断向量号是怎么确定的呢?这要根据具体芯片的中断控制器,比如三星的S3C2410,需要通过读取其中的中断状态寄存器,来获得是哪个设备发生了中断:
if defined(CONFIG_ARCH_S3C2410)
#include
.macro disable_fiq
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mov r4, #INTBASE @ virtual address of IRQ registers
ldr irqnr, [r4, #0x8] @ read INTMSK 中断掩码寄存器
ldr irqstat, [r4, #0x10] @ read INTPND 中断寄存器
bics irqstat, irqstat, irqnr
bics irqstat, irqstat, irqnr
beq 1002f
mov irqnr, #0
1001: tst irqstat, #1
bne 1002f @ found IRQ
add irqnr, irqnr, #1
mov irqstat, irqstat, lsr #1
cmp irqnr, #32
bcc 1001b
1002:
.endm
.macro irq_prio_table
.endm
以上代码也告诉了我们,中断号的确定,其实是和S3C2410手册中SRCPND寄存器是一致的,即:
/* Interrupt Controller */
#define IRQ_EINT0 0 /* External interrupt 0 */
#define IRQ_EINT1 1 /* External interrupt 1 */
#define IRQ_EINT2 2 /* External interrupt 2 */
#define IRQ_EINT3 3 /* External interrupt 3 */
#define IRQ_EINT4_7 4 /* External interrupt 4 ~ 7 */
#define IRQ_EINT8_23 5 /* External interrupt 8 ~ 23 */
#define IRQ_RESERVED6 6 /* Reserved for future use */
#define IRQ_BAT_FLT 7
#define IRQ_TICK 8 /* RTC time tick interrupt */
#define IRQ_WDT 9 /* Watch-Dog timer interrupt */
#define IRQ_TIMER0 10 /* Timer 0 interrupt */
#define IRQ_TIMER1 11 /* Timer 1 interrupt */
#define IRQ_TIMER2 12 /* Timer 2 interrupt */
#define IRQ_TIMER3 13 /* Timer 3 interrupt */
#define IRQ_TIMER4 14 /* Timer 4 interrupt */
#define IRQ_UART2 15 /* UART 2 interrupt */
#define IRQ_LCD 16 /* reserved for future use */
#define IRQ_DMA0 17 /* DMA channel 0 interrupt */
#define IRQ_DMA1 18 /* DMA channel 1 interrupt */
#define IRQ_DMA2 19 /* DMA channel 2 interrupt */
#define IRQ_DMA3 20 /* DMA channel 3 interrupt */
#define IRQ_SDI 21 /* SD Interface interrupt */
#define IRQ_SPI0 22 /* SPI interrupt */
#define IRQ_UART1 23 /* UART1 receive interrupt */
#define IRQ_RESERVED24 24
#define IRQ_USBD 25 /* USB device interrupt */
#define IRQ_USBH 26 /* USB host interrupt */
#define IRQ_IIC 27 /* IIC interrupt */
#define IRQ_UART0 28 /* UART0 transmit interrupt */
#define IRQ_SPI1 29 /* UART1 transmit interrupt */
#define IRQ_RTC 30 /* RTC alarm interrupt */
#define IRQ_ADCTC 31 /* ADC EOC interrupt */
#define NORMAL_IRQ_OFFSET 32
这些宏定义在文件irqs.h中,大家可以看到它的定义取自S3C2410的文档。
总结: linux在初始化的时候已经把每个中断向量的地址准备好了!就是说添加中断服务程序的框架已经给出,当某个中断发生时,将会到确定的地址处去找指令,所以我们做驱动程序时,只需要经过request_irq()来挂接自己编写的中断服务程序即可。
另:对于快速中断,linux在初始化时是空的,所以要对它挂接中断处理程序,就需要单独的函数set_fiq_handler()来实现,此函数在源文件fiq.c中,有兴趣的读者可进一步研究。
地址 异常类型 进入时的工作模式
0x00000000 Reset Supervisor
0x00000004 Und Undefined
0x00000008 Soft interupt Supervisor
0x0000000c Abort(prefetch) Abort
0x00000010 Abort(data) Abort
0x00000014 Reserved Reserved
0x00000018 IRQ IRQ
0x0000001c FIQ FIQ
首先要明确的一点就是,无论内存地址空间是如何映射的,以上这些地址都不会变,比如当有快速中断发生时,ARM将铁定到0X0000001C这个地址处取指令。这也是BOOTLOADER把操作系统引导以后,内存必须重映射的原因!否则操作系统不能真正接管整套系统!
LINUX启动以后要初始化这些区域,初始化代码在main.c中的start_kernel()中,具体是调用函数trap_ini()来实现的。如下面所示(具体可参照entry-armv.S):
.LCvectors: swi SYS_ERROR0
b __real_stubs_start + (vector_undefinstr - __stubs_start)
ldr pc, __real_stubs_start + (.LCvswi - __stubs_start)
b __real_stubs_start + (vector_prefetch - __stubs_start)
b __real_stubs_start + (vector_data - __stubs_start)
b __real_stubs_start + (vector_addrexcptn - __stubs_start)
b __real_stubs_start + (vector_IRQ - __stubs_start)
b __real_stubs_start + (vector_FIQ - __stubs_start)
ENTRY(__trap_init)
stmfd sp!, {r4 - r6, lr}
adr r1, .LCvectors @ set up the vectors
ldmia r1, {r1, r2, r3, r4, r5, r6, ip, lr}
stmia r0, {r1, r2, r3, r4, r5, r6, ip, lr}
add r2, r0, #0x200
adr r0, __stubs_start @ copy stubs to 0x200
adr r1, __stubs_end
1: ldr r3, [r0], #4
str r3, [r2], #4
cmp r0, r1
blt 1b
LOADREGS(fd, sp!, {r4 - r6, pc})
以上可以看出这个函数初始化了中断向量,实际上把相应的跳转指令拷贝到了对应的地址。
当发生中断时,不管是从用户模式还是管理模式调用的,最终都要调用do_IRQ():
__irq_usr: sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ save r0 - r12
ldr r4, .LCirq
add r8, sp, #S_PC
ldmia r4, {r5 - r7} @ get saved PC, SPSR
stmia r8, {r5 - r7} @ save pc, psr, old_r0
stmdb r8, {sp, lr}^
alignment_trap r4, r7, __temp_irq
zero_fp
1: get_irqnr_and_base r0, r6, r5, lr
movne r1, sp
adrsvc ne, lr, 1b
@
@ routine called with r0 = irq number, r1 = struct pt_regs *
@
bne do_IRQ @ 调用do_IRQ来实现具体的中断处理
mov why, #0
get_current_task tsk
b ret_to_user
对于以上代码,在很多文章中都有过分析,这里不再赘述。
Linux每个中断通过一个结构irqdesc来描述,各中断的信息都在这个结构中得以体现:
struct irqdesc {
unsigned int nomask : 1; /* IRQ does not mask in IRQ */
unsigned int enabled : 1; /* IRQ is currently enabled */
unsigned int triggered: 1; /* IRQ has occurred */
unsigned int probing : 1; /* IRQ in use for a probe */
unsigned int probe_ok : 1; /* IRQ can be used for probe */
unsigned int valid : 1; /* IRQ claimable */
unsigned int noautoenable : 1; /* don't automatically enable IRQ */
unsigned int unused :25;
void (*mask_ack)(unsigned int irq); /* Mask and acknowledge IRQ */
void (*mask)(unsigned int irq); /* Mask IRQ */
void (*unmask)(unsigned int irq); /* Unmask IRQ */
struct irqaction *action;
/*
* IRQ lock detection
*/
unsigned int lck_cnt;
unsigned int lck_pc;
unsigned int lck_jif;
};
在具体的ARM芯片中会有很多的中断类型,每一种类型的中断用以上结构来表示:
struct irqdesc irq_desc[NR_IRQS]; /* NR_IRQS根据不同的MCU会有所区别*/
在通过request_irq()函数注册中断服务程序的时候,将会把中断向量和中断服务程序对应起来。
我们来看一下request_irq的源码:
int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
unsigned long irq_flags, const char * devname, void *dev_id)
{
unsigned long retval;
struct irqaction *action;
if (irq >= NR_IRQS || !irq_desc[irq].valid || !handler ||
(irq_flags & SA_SHIRQ && !dev_id))
return -EINVAL;
action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
if (!action) /* 生成action结构*/
return -ENOMEM;
action->handler = handler;
action->flags = irq_flags;
action->mask = 0;
action->name = devname;
action->next = NULL;
action->dev_id = dev_id;
retval = setup_arm_irq(irq, action); /*把中断号irq和action 对应起来*/
if (retval)
kfree(action);
return retval;
}
其中第一个参数irq就是中断向量,第二个参数即是要注册的中断服务程序。很多同仁可能疑惑的是,我们要注册的中断向量号是怎么确定的呢?这要根据具体芯片的中断控制器,比如三星的S3C2410,需要通过读取其中的中断状态寄存器,来获得是哪个设备发生了中断:
if defined(CONFIG_ARCH_S3C2410)
#include
.macro disable_fiq
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mov r4, #INTBASE @ virtual address of IRQ registers
ldr irqnr, [r4, #0x8] @ read INTMSK 中断掩码寄存器
ldr irqstat, [r4, #0x10] @ read INTPND 中断寄存器
bics irqstat, irqstat, irqnr
bics irqstat, irqstat, irqnr
beq 1002f
mov irqnr, #0
1001: tst irqstat, #1
bne 1002f @ found IRQ
add irqnr, irqnr, #1
mov irqstat, irqstat, lsr #1
cmp irqnr, #32
bcc 1001b
1002:
.endm
.macro irq_prio_table
.endm
以上代码也告诉了我们,中断号的确定,其实是和S3C2410手册中SRCPND寄存器是一致的,即:
/* Interrupt Controller */
#define IRQ_EINT0 0 /* External interrupt 0 */
#define IRQ_EINT1 1 /* External interrupt 1 */
#define IRQ_EINT2 2 /* External interrupt 2 */
#define IRQ_EINT3 3 /* External interrupt 3 */
#define IRQ_EINT4_7 4 /* External interrupt 4 ~ 7 */
#define IRQ_EINT8_23 5 /* External interrupt 8 ~ 23 */
#define IRQ_RESERVED6 6 /* Reserved for future use */
#define IRQ_BAT_FLT 7
#define IRQ_TICK 8 /* RTC time tick interrupt */
#define IRQ_WDT 9 /* Watch-Dog timer interrupt */
#define IRQ_TIMER0 10 /* Timer 0 interrupt */
#define IRQ_TIMER1 11 /* Timer 1 interrupt */
#define IRQ_TIMER2 12 /* Timer 2 interrupt */
#define IRQ_TIMER3 13 /* Timer 3 interrupt */
#define IRQ_TIMER4 14 /* Timer 4 interrupt */
#define IRQ_UART2 15 /* UART 2 interrupt */
#define IRQ_LCD 16 /* reserved for future use */
#define IRQ_DMA0 17 /* DMA channel 0 interrupt */
#define IRQ_DMA1 18 /* DMA channel 1 interrupt */
#define IRQ_DMA2 19 /* DMA channel 2 interrupt */
#define IRQ_DMA3 20 /* DMA channel 3 interrupt */
#define IRQ_SDI 21 /* SD Interface interrupt */
#define IRQ_SPI0 22 /* SPI interrupt */
#define IRQ_UART1 23 /* UART1 receive interrupt */
#define IRQ_RESERVED24 24
#define IRQ_USBD 25 /* USB device interrupt */
#define IRQ_USBH 26 /* USB host interrupt */
#define IRQ_IIC 27 /* IIC interrupt */
#define IRQ_UART0 28 /* UART0 transmit interrupt */
#define IRQ_SPI1 29 /* UART1 transmit interrupt */
#define IRQ_RTC 30 /* RTC alarm interrupt */
#define IRQ_ADCTC 31 /* ADC EOC interrupt */
#define NORMAL_IRQ_OFFSET 32
这些宏定义在文件irqs.h中,大家可以看到它的定义取自S3C2410的文档。
总结: linux在初始化的时候已经把每个中断向量的地址准备好了!就是说添加中断服务程序的框架已经给出,当某个中断发生时,将会到确定的地址处去找指令,所以我们做驱动程序时,只需要经过request_irq()来挂接自己编写的中断服务程序即可。
另:对于快速中断,linux在初始化时是空的,所以要对它挂接中断处理程序,就需要单独的函数set_fiq_handler()来实现,此函数在源文件fiq.c中,有兴趣的读者可进一步研究。
订阅:
博文 (Atom)