迈克尔的HANDBOOK
===========================================================
===========================================================

http://jiri.name

OR

http://markchina.blogspot.com


okone96 发表于:2008.11.20 12:04 ::分类: ( 随笔 ) ::阅读:(457次) :: 评论 (0)
===========================================================
===========================================================
meta是用来在HTML文档中模拟HTTP协议的响应头报文。meta 标签用于网页的<head>与</head>中,meta 标签的用处很多。meta 的属性有两种:name和http-equiv。name属性主要用于描述网页,对应于content(网页内容),以便于搜索引擎机器人查找、分类(目前几乎所有的搜索引擎都使用网上机器人自动查找meta值来给网页分类)。这其中最重要的是description(站点在搜索引擎上的描述)和keywords(分类关键词),所以应该给每页加一个meta值。比较常用的有以下几个:   name 属性   1、<meta name="Generator" content="">用以说明生成工具(如Microsoft FrontPage 4.0)等;   2、<meta name="KEYWords" content="">向搜索引擎说明你的网页的关键词;   3、<meta name="DEscription" content="">告诉搜索引擎你的站点的主要内容;   4、<meta name="Author" content="你的姓名">告诉搜索引擎你的站点的制作的作者;   5、<meta name="Robots" content="all|none|index|noindex|follow|nofollow">   其中的属性说明如下:   设定为all:文件将被检索,且页面上的链接可以被查询;   设定为none:文件将不被检索,且页面上的链接不可以被查询;   设定为index:文件将被检索;   设定为follow:页面上的链接可以被查询;   设定为noindex:文件将不被检索,但页面上的链接可以被查询;   设定为nofollow:文件将不被检索,页面上的链接可以被查询。   http-equiv属性   1、<meta http-equiv="Content-Type" content="text/html";charset=gb_2312-80">   和 <meta http-equiv="Content-Language" content="zh-CN">用以说明主页制作所使用的文字以及语言;   又如英文是ISO-8859-1字符集,还有BIG5、utf-8、shift-Jis、Euc、Koi8-2等字符集;   2、<meta http-equiv="Refresh" content="n;url=http://yourlink">定时让网页在指定的时间n内,跳转到页面http;//yourlink;   3、<meta http-equiv="Expires" content="Mon,12 May 2001 00:20:00 GMT">可以用于设定网页的到期时间,一旦过期则必须到服务器上重新调用。需要注意的是必须使用GMT时间格式;   4、<meta http-equiv="Pragma" content="no-cache">是用于设定禁止浏览器从本地机的缓存中调阅页面内容,设定后一旦离开网页就无法从Cache中再调出;   5、<meta http-equiv="set-cookie" content="Mon,12 May 2001 00:20:00 GMT">cookie设定,如果网页过期,存盘的cookie将被删除。需要注意的也是必须使用GMT时间格式;   6、<meta http-equiv="Pics-label" content="">网页等级评定,在IE的internet选项中有一项内容设置,可以防止浏览一些受限制的网站,而网站的限制级别就是通过meta属性来设置的;   7、<meta http-equiv="windows-Target" content="_top">强制页面在当前窗口中以独立页面显示,可以防止自己的网页被别人当作一个frame页调用;   8、<meta http-equiv="Page-Enter" content="revealTrans(duration=10,transtion=50)">和<meta http-equiv="Page-Exit" contect="revealTrans(duration=20,transtion=6)">设定进入和离开页面时的特殊效果,这个功能即FrontPage中的“格式/网页过渡”,不过所加的页面不能够是一个frame页面。
okone96 发表于:2008.09.02 11:44 ::分类: ( 操作系统 ) ::阅读:(506次) :: 评论 (0)
===========================================================
===========================================================

<body marginwidth="0" marginheight="0" oncontextmenu="return false" ondragstart="return false" onselectstart ="return false" onselect="document.selection.empty()" oncopy="document.selection.empty()" onbeforecopy="return false">

function copyText(){
var targetText = document.getElementById('url');
var clipeText = targetText.createTextRange();
clipeText.execCommand("Copy");
alert("复制成功,请粘贴到你的QQ/MSN上推荐给你的好友!rnrn内容如下:rn" + clipeText.text);

}


okone96 发表于:2007.12.21 12:43 ::分类: ( WEB2.0 ) ::阅读:(638次) :: 评论 (0)
===========================================================
===========================================================

原因:因为linux下,jdk的字符集里缺汉子编码给他补上,字符集文件自己找或与我联系都可以,以下是解决办法。

环境:
JDK1.5(JDK版本很重要,如果是1.4.2版本的话,JRE目录下的字体配置文件不大一样)
RedHat4.0
Tomcat5.0

解决方法:
1.确认%JavaHome%/jre/lib/fonts目录下存在zysong.ttf
2.在%JavaHome%/jre/lib/fonts目录下执行"ttmkfdir -o fonts.dir"命令,重新生成fonts.dir文件
3.确认/usr/share/fonts/zh_CN/TrueType目录存在,如果不存在则mkdir创建
4.确认/usr/share/fonts/zh_CN/TrueType目录下存在zysong.ttf
5.在%JavaHome%/jre/lib目录下,执行 cp fontconfig.RedHat.3.properties.src fontconfig.properties
6.重新启动tomcat,大功告成!


okone96 发表于:2007.11.06 14:54 ::分类: ( JAVA ) ::阅读:(989次) :: 评论 (0)
===========================================================
===========================================================

看看下面两条,功能是随机得到数据表中的10条记录,效率可能是个问题,但是已经很方便了。

mysql: select * from tablename order by rand() limit 10
sqlserver: select top 10 * from tablename order by NEWID()


okone96 发表于:2007.10.29 12:14 ::分类: ( 数据库 ) ::阅读:(1375次) :: 评论 (3)
===========================================================
===========================================================

mysql 创建 数据库时指定编码很重要,很多开发者都使用了默认编码,但是我使用的经验来看,制定数据库的编码可以很大程度上避免倒入导出带来的乱码问题。

我们遵循的标准是,数据库,表,字段和页面或文本的编码要统一起来
很多mysql数据库工具(除了phpmyadmin,我偶尔用,功能强速度慢)都不支持创建时指定数据库编码,当然可以改my.ini来解决这个问题,但是需要重新启动mysql,
不过用下面的语句会更有效

GBK: create database test2 DEFAULT CHARACTER SET gbk COLLATE gbk_chinese_ci;

UTF8: CREATE DATABASE `test2` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci


okone96 发表于:2007.10.25 17:48 ::分类: ( 数据库 ) ::阅读:(3816次) :: 评论 (2)
===========================================================
===========================================================

http://www.itpub.net/869350.html
http://blog.csdn.net/junnef/archive/2005/12/23/560251.aspx

呵呵 中文排序原来这么简单

Comparator cmp = Collator.getInstance(java.util.Locale.CHINA);
Collections.sort(list,cmp);


okone96 发表于:2007.10.12 19:08 ::分类: ( java技巧程序 ) ::阅读:(776次) :: 评论 (0)
===========================================================
===========================================================

用load data infile 来装载数据时出现乱码了,使用load 时 必须 数据库 表 字段的编码和 文件编码一致,但是数据库已经有数据不想重建,用命令修改编码是个不错的选择,下面是修改的方法。试过修改my.ini里character_set_database = uft8,但似乎不起作用。

1.如果安装mysql的编码已不能更改,很多朋友是购买虚拟主机建立网站,无权更改MYSQL的安装编码,这一关我们可以跳过,因为只要后面的步聚正确,一样能解决乱码问题
2.修改数据库编码,如果是数据库编码不正确: 可以在phpmyadmin 执行如下命令: ALTER DATABASE `test` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin
以上命令就是将test数据库的编码设为utf8
3.修改表的编码:ALTER TABLE `category` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin
以上命令就是将一个表category的编码改为utf8
4.修改字段的编码:
ALTER TABLE `test` CHANGE `dd` `dd` VARCHAR( 45 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL
以上命令就是将test表中 dd的字段编码改为utf8


okone96 发表于:2007.10.09 11:21 ::分类: ( 数据库 ) ::阅读:(1970次) :: 评论 (0)
===========================================================
===========================================================

HashTable和HashMap的六点区别

HashTable的应用非常广泛,HashMap是新框架中用来代替HashTable的类,也就是说建议使用HashMap,不要使用HashTable。可能你觉得HashTable很好用,为什么不用呢?这里简单分析他们的区别。

1.HashTable的方法是同步的,HashMap未经同步,所以在多线程场合要手动同步HashMap这个区别就像Vector和ArrayList一样。

2.HashTable不允许null值(key和value都不可以),HashMap允许null值(key和value都可以)。

3.HashTable有一个contains(Object value),功能和containsValue(Object value)功能一样。

4.HashTable使用Enumeration,HashMap使用Iterator。

以上只是表面的不同,它们的实现也有很大的不同。

5.HashTable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。

6.哈希值的使用不同,HashTable直接使用对象的hashCode,代码是这样的:
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
而HashMap重新计算hash值,而且用与代替求模:
int hash = hash(k);
int i = indexFor(hash, table.length);

static int hash(Object x) {
  int h = x.hashCode();

  h += ~(h << 9);
  h ^= (h >>> 14);
  h += (h << 4);
  h ^= (h >>> 10);
  return h;
}
static int indexFor(int h, int length) {
  return h & (length-1);
}
以上只是一些比较突出的区别,当然他们的实现上还是有很多不同的,比如
HashMap对null的操作。


okone96 发表于:2007.10.08 19:23 ::分类: ( java技巧程序 ) ::阅读:(1150次) :: 评论 (0)
===========================================================
===========================================================

虽然不是什么深奥东西,但我觉得给了我们一个取得信息操作信息的思路。

public static String getMACAddress() {
String address = "";
String os = System.getProperty("os.name");
System.out.println(os);
if (os != null && os.startsWith("Windows")) {
try {
ProcessBuilder pb = new ProcessBuilder("ipconfig", "/all");
Process p = pb.start();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
if (line.indexOf("Physical Address") != -1) {
int index = line.indexOf(":");
address = line.substring(index + 1);
break;
}
}
br.close();
return address.trim();
} catch (IOException e) {
}
}
return address;
}


okone96 发表于:2007.10.08 18:57 ::分类: ( java技巧程序 ) ::阅读:(998次) :: 评论 (0)
===========================================================
===========================================================

http://dev.mysql.com/doc/refman/5.1/zh/optimization.html#insert-speed

http://dev.mysql.com/doc/refman/5.1/zh/sql-syntax.html#load-data


okone96 发表于:2007.10.08 18:28 ::分类: ( 数据库 ) ::阅读:(824次) :: 评论 (0)
===========================================================
===========================================================

1、创建保存备份文件的路径/mysqldata
#mkdir /mysqldata
2、创建/usr/sbin/bakmysql文件
#vi /usr/sbin/bakmysql
输入
rq=` date +%Y%m%d `
tar zcvf /mysqldata/mysql$rq.tar.gz /var/lib/mysql
或者写成
a=$(date +%Y%m%d)

mysqldump shequ -uroot -p123456 | gzip >/opt/baofeng_paihangbang/backup/mysql_$a.shequ.sql.tar.gz


/var/lib/mysql是你数据库文件的目录,部分用户是/usr/local/mysql/data,每个人可能不同
/mysqldata/表示保存备份文件的目录,这个每个人也可以根据自己的要求来做。
3、修改文件属性,使其可执行
# chmod +x /usr/sbin/bakmysql
4、修改/etc/crontab
#vi /etc/crontab
在下面添加
01 3 * * * root /usr/sbin/bakmysql
表示每天3点钟执行备份
5、重新启动crond
# /etc/rc.d/init.d/crond restart
完成。
这样每天你在/mysqldata可以看到这样的文件
mysql20040619.tar.gz
你直接下载就可以了。
在tar命令执行前,停止数据库服务进程或锁定数据库,
否则恢复数据时,会出现数据库损坏的情形,运气好时可修复,运气不好时就不可以了。


okone96 发表于:2007.09.27 15:11 ::分类: ( 数据库 ) ::阅读:(935次) :: 评论 (0)
===========================================================
===========================================================
 

okone96 发表于:2007.09.05 18:37 ::分类: ( 随笔 ) ::阅读:(852次) :: 评论 (1)
===========================================================
===========================================================

网上找了半天,都不够简单明了,我自己总结以下:

把你的本地主机用户的ssh公匙文件写入到远程主机用户的~/.ssh/authorized_keys文件中,具体方法
假设本地主机localhost,远程主机remote

一,在localhost主机里的用户

运行 ssh-keygen -t rsa
结果如下
Generating public/private rsa key pair.

Enter file in which to save the key (/home/.username/ssh/id_rsa):#回车

Enter passphrase (empty for no passphrase):#回车

Enter same passphrase again:#回车

Your identification has been saved in /home/.username /.ssh/id_rsa.

Your public key has been saved in /home/.username /.ssh/id_rsa.pub.

The key fingerprint is:

38:25:c1:4d:5d:d3:89:bb:46:67:bf:52:af:c3:17:0c username@localhost

Generating RSA keys:

Key generation complete.
会在用户目录~/.ssh/产生两个文件,id_rsa,id_rsa.pub

二,把id_rsa.pub文件拷贝到remote主机的用户目录下

cat id_rsa.pub >~/.ssh/authorized_keys
就可以了

这样localhost主机的用户就可以通过ssh而不用密码登陆remote主机

在测试当中发现经常出现以下错误:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
1f:a3:2b:b5:27:0c:5c:7b:89:27:ff:ab:cd:ba:31:66.
Please contact your system administrator.
Add correct host key in /root/.ssh/known_hosts to get rid of this message.
Offending key in /root/.ssh/known_hosts:6
RSA host key for 60.28.15.234 has changed and you have requested strict checking.
Host key verification failed.

解决办法是把known_hosts文件删掉就可以了


okone96 发表于:2007.09.04 12:55 ::分类: ( 操作系统 ) ::阅读:(858次) :: 评论 (0)
===========================================================
===========================================================
http://www.dada.net/blogeye
okone96 发表于:2007.09.02 16:27 ::分类: ( 随笔 ) ::阅读:(369次) :: 评论 (0)
===========================================================
===========================================================
RSS 2.0规范

RSS是 Really Simple Syndication的缩写(对rss2.0而言,是这三个词的缩写,对rss1.0而言则是RDF Site Summary的缩写,1.0与2.0走的是两个体系)
  RSS 基于XML,所有的 RSS 必须遵循w3c网站上公布的XML 1.0 规范。
  在一个RSS文档中,根元素是<rss>,带有一个必备属性version,用以指明该文档遵循的rss规范,如果rss文档遵循本规范,则version值必须是2.0。
  <rss>元素只有一个子元素,包含关于频道的一些信息。频道(channel)是整个blog,项(item)指一篇文章或日志(也有称这为post)。

RSS2.0元素channel的子元素列表


元素(Element)描述(Description)值域重要性举例(Example)
title频道名称必备GoUpstate.com News Headlines
link频道的URL必备http://www.goupstate.com/
Description频道的描述必备The latest news from GoUpstate.com, a Spartanburg Herald-Journal Web site.
language频道文章所用语言,可用netscape或w3c推荐的列表可选en-us
copyright频道内容的版权说明可选Copyright 2002, Spartanburg Herald-Journal
managingEditor责任编辑的email可选geo@herald.com (George Matesky)
webMaster负责频道技术事务的网站管理员email可选betty@herald.com (Betty Guernsey)
pubDate频道内容发布日期,格式遵循RFC822格式(年份可为2们或4位)可选Sat, 07 Sep 2002 00:00:01 GMT
lastBuildDate频道内容最后的修改日期可选Sat, 07 Sep 2002 09:42:31 GMT
category指定频道所属的一个或几个类别可选<category>Newspapers</category>
generator生成该频道的程序名可选MightyInHouse Content System v2.3
docs指向该RSS文件所用格式说明的URL可选http://blogs.law.harvard.edu/tech/rss
cloudAllows processes to register with a cloud to be notified of updates to the channel, implementing a lightweight publish-subscribe protocol for RSS feeds. More info here.可选<cloud domain="rpc.sys.com" port="80" path="/RPC2" registerProcedure="pingMe" protocol="soap"/>
ttl有效期,用以指明该频道可被缓存的最长时间分钟为单位可选<ttl>60</ttl>
image指定一个 GIF或JPEG或PNG图片,用以与频道一起显示可选
rating这个频道的分级(主要指成人、限制、儿童等)可选
textInput指定一个text输入框供用户输入,具体信息及功能未定。可选
skipHours提示新闻聚合器,那些小时时段它可以跳过。可选
skipDays提示新闻聚合器,那些天它可以跳过。可选

RSS2.0元素channel的子元素image的子元素列表


元素(Element)描述(Description)值域重要性举例(Example)
url图片的url必备
title图片的标题,用于http的alt属性必备
link网站的url(实际中常以频道的url代替)必备
width图片的宽度(象素为单位)最大144,默认88可选
height图片的高度(象素为单位)最大400,默认31可选
description用于link的title属性可选

RSS2.0元素channel的子元素cloud的子元素列表


元素(Element)描述(Description)值域重要性举例(Example)
domainCloud程序所在机器的域名或IP地址radio.xmlstoragesystem.com
port访问clound程序所通过的端口80
path程序所在路径(不一定是真实路径)/RPC2
registerProcedure注册的可提供的服务或过程xmlStorageSystem.rssPleaseNotify
protocol协议xml-rpc, soap , http-post 之一xml-rpc

RSS2.0元素channel的子元素textInput的子元素列表


元素(Element)描述(Description)值域重要性举例(Example)
titleSubmit按钮的标签必备
description解释text输入区必备
nameText area对象的名字必备
link处理提交的请求的cgi程序必备

关于item的内容,请看基于XML-RPC的BloggerAPI学习.
说明:
  rss2.0要求<link>和<url>的值的非常部分开头,须是在IANA注册过的,如http://或https://或ftp://等。
  一个rss文件中,可以包括没有这儿定义的元素,只要它是在某个命名空间被定义过。
  一个常见问题是与的区别,两者在有些情况下是相同的,但前者可指几某个长文中的某个位置(即所谓的页内锚点吧)。


okone96 发表于:2007.08.08 10:47 ::分类: ( 操作系统 ) ::阅读:(432次) :: 评论 (0)
===========================================================
===========================================================
因为每次从txt文件读取一个u开始的汉字的时候,程序认为它就是一个普通的字符串序列,所以我们必须把它转换成我们需要的utf编码的字符序列,这里用到了java.util.property类里的一个方法来把不同的字符串转换为utf需要的字符串序列,
方法如下:

package com.community.test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;

public class test {


public static void main(String args[]) {
try {

char []inc=new char[1024];
char []outc=new char[6];

//文件内容为u8584
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("d:/log/test.txt"))));

String line = "";
while ((line = br.readLine()) != null) {
inc=getChars(line);
String temp=loadConvert(inc,0,inc.length,outc);
System.out.println(line);
System.out.println(temp);

}

br.close();
} catch (Exception e) {
e.printStackTrace();
}
}

public static char[] getChars(String s) {
char c[]=new char[s.length()];
for (int i = 0; i < s.length(); i++) {
c[i]=s.charAt(i);
}
return c;
}

private static String loadConvert (char[] in, int off, int len, char[] convtBuf) {
if (convtBuf.length < len) {
int newLen = len * 2;
if (newLen < 0) {
newLen = Integer.MAX_VALUE;
}
convtBuf = new char[newLen];
}
char aChar;
char[] out = convtBuf;
int outLen = 0;
int end = off + len;

while (off < end) {
aChar = in[off++];
if (aChar == '\') {
aChar = in[off++];
if(aChar == 'u') {
// Read the xxxx
int value=0;
for (int i=0; i<4; i++) {
aChar = in[off++];
switch (aChar) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
value = (value << 4) + aChar - '0';
break;
case 'a': case 'b': case 'c':
case 'd': case 'e': case 'f':
value = (value << 4) + 10 + aChar - 'a';
break;
case 'A': case 'B': case 'C':
case 'D': case 'E': case 'F':
value = (value << 4) + 10 + aChar - 'A';
break;
default:
throw new IllegalArgumentException(
"Malformed \uxxxx encoding.");
}
}
out[outLen++] = (char)value;
} else {
if (aChar == 't') aChar = ' ';
else if (aChar == 'r') aChar = ' ';
else if (aChar == 'n') aChar = ' ';
else if (aChar == 'f') aChar = 'f';
out[outLen++] = aChar;
}
} else {
out[outLen++] = (char)aChar;
}
}
return new String (out, 0, outLen);
}
}

输出:

\u8584


okone96 发表于:2007.08.06 18:43 ::分类: ( JAVA ) ::阅读:(1483次) :: 评论 (0)
===========================================================
===========================================================

eclipse 有启动参数里设置jvm大小,因为eclipse运行时自己也需要jvm,所以eclipse.ini里设置的jvm大小不是具体某个程序运行时所用jvm的大小,这和具体程序运行的jvm大小无关。

那么怎么才能设置某个程序的jvm大小呢(当然控制台运行的话不会存在这个问题,如:java -Xms256m -Xmx1024m classname,这样就可以把当前程序的jvm大小给设定)?

因为eclipse里默认的一个程序的jvm配置为:-Xms8m -Xmx128m,所以我们的处理耗内存比较大时需要手动调整一下,以便不会内存溢出。具体的设置方法为:

选中被运行的类,点击菜单‘run->run...’,选择(x)=Argument标签页下的vm arguments框里输入 -Xmx512m, 保存运行就ok了


okone96 发表于:2007.08.06 16:49 ::分类: ( Eclipse ) ::阅读:(5307次) :: 评论 (10)
===========================================================
===========================================================

-clean
-vmargs
-Xms40m
-Xmx512m
-Xverify:none
-XX:+UseParallelGC
-XX:permSize=20M
-XX:MaxNewSize=32M
-XX:NewSize=32M

后面5个参数,按不清楚,知道的请说明一下谢谢。


okone96 发表于:2007.08.06 16:47 ::分类: ( Eclipse ) ::阅读:(867次) :: 评论 (0)
===========================================================
===========================================================


共同点:
ServerSocket serverSocket = new ServerSocket(80);
sokcet s = serverSocket.accept();

区别:
1 原始:(线程池)
每来一个请求分配新的一个线程来处理,继续等待下一个请求,这个过程中每一个线程一直等待数据的到来。这种情况导致随并发量多 线程数增加,系统消耗比较大
2 select(2个线程)
每来一个请求则把s给select,继续等待下一个请求。来数据时select里copy一个套接字,来处理缓冲区数据(这个过程很耗时),因当时的条件所限制select里只能放64个套接字,也就是说并发最大量为64. 一个线程处理接受,另一个进程处理套接字处理数据
3 poll(2个线程)
每来一个请求把s给poll(push进去),继续等待下一个请求,来数据时从push里弹出套接字(不用copy了),处理缓冲区的数据。支持并发可以数千个。
一个线程处理接受,另一个进程处理套接字处理数据
4 epoll(2个线程)
每来一个请求把s给epoll(push进去),来数据时缓存,需要处理数据时,把缓冲区的数据和套接字一起返回,这样节省了readBuffer的时间,效率更高
一个线程处理接受,另一个进程处理套接字处理数据

下面深入讲一下epoll模型和iocp模型的异同之处

目前国内的网游研发,在服务器使用的开发平台方面,win和linux的比例各占多少,我一时半会也没有准确数据,但从我了解的这么多公司情况来看,用win系统的还是比较多一点,这些企业一般都是比较单纯的网游公司,而用linux的则多数是一些传统的互联网公司,比如网易和腾讯。

网游服务器用win还是linux,向来都是大家关注的话题。我想,原因可能很多,但此处不想过多论述这个问题,为避免多费口舌,我还是明确表明一下自己的观点:我是推荐用linux作开发的,虽然我也是刚转来作linux平台下的开发。

那么,说具体一点。但凡作过比较深入的网络编程的人,都会知道,在win平台下,高效的IO模型是IOCP,而在linux底下则是epoll。那么,epoll与iocp之间到底有哪些异同之处呢?

首先,我们看一下它们相同的地方。

两者都是处理异步IO的高效模型,这种高效,除了“异步处理”这个共同的特征之外,二者都可以通过指针携带应用层数据:在IOCP里,应用层数据可以通过单句柄数据和单IO数据来与IOCP底层通信;而在epoll里,可以通过epoll_data里的"void *ptr"来传递。这是一种很重要的思想,也是它们高效的原因所在:当事件的通知到来时,它不仅告诉你发生了什么样的事件,还同时告诉这次事件所操作的数据是哪些。

那么,epoll和iocp到底又有什么不同呢?

以我目前粗浅的使用经验来看,至少可以得到以下结论:

1.iocp是在IO操作完成之后,才通过get函数返回这个完成通知的;而epoll则不是在IO操作完成之后才通知你,它的工作原理是,你如果想进行IO操作时,先向epoll查询是否可读或可写,如果处于可读或可写状态后,epoll会通过epoll_wait函数通知你,此时你再进行进一步的recv或send操作。

2.在1的基础上,我们其实可以看到,epoll仅仅是一个异步事件的通知机制,其本身并不作任何的IO读写操作,它只负责告诉你是不是可以读或可以写了,而具体的读写操作,还要应用层自己来作;但iocp的封装就要多一些,它不仅会有完成之后的事件通知,更重要的是,它同时封装了一部分的IO控制逻辑。从这一点上来看,iocp的封装似乎更全面一点,但是,换个角度看,epoll仅提供这种机制也是非常好的,它保持了事件通知与IO操作之间彼此的独立性,使得epoll的使用更加灵活。


okone96 发表于:2007.08.02 11:04 ::分类: ( JAVA ) ::阅读:(1156次) :: 评论 (0)
自我介绍
切换风格
新闻聚合
博客日历
文章归档...
最新发表...
最新评论...
最多阅读文章...
最多评论文章...
博客统计...
Blog信息
网站链接...