随笔 - 16  文章 - 4 评论 - 23 trackbacks - 0

几种负载均衡算法


几种负载均衡算法

本地流量管理技术主要有一下几种负载均衡算法:

静态负载均衡算法包括:轮询,比率,优先权

动态负载均衡算法包括: 最少连接数,最快响应速度,观察方法,预测法,动态性能分配,动态服务器补充,服务质量,服务类型,规则模式。

静态负载均衡算法

◆轮询(Round Robin):顺序循环将请求一次顺序循环地连接每个服务器。当其中某个服务器发生第二到第7 层的故障,BIG-IP 就把其从顺序循环队列中拿出,不参加下一次的轮询,直到其恢复正常。

◆比率(Ratio):给每个服务器分配一个加权值为比例,根椐这个比例,把用户的请求分配到每个服务器。当其中某个服务器发生第二到第7 层的故障,BIG-IP 就把其从服务器队列中拿出,不参加下一次的用户请求的分配, 直到其恢复正常。

◆优先权(Priority):给所有服务器分组,给每个组定义优先权,BIG-IP 用户的请求,分配给优先级最高的服务器组(在同一组内,采用轮询或比率算法,分配用户的请求);当最高优先级中所有服务器出现故障,BIG-IP 才将请求送给次优先级的服务器组。这种方式,实际为用户提供一种热备份的方式。

动态负载均衡算法

◆最少的连接方式(Least Connection):传递新的连接给那些进行最少连接处理的服务器。当其中某个服务器发生第二到第7 层的故障,BIG-IP 就把其从服务器队列中拿出,不参加下一次的用户请求的分配, 直到其恢复正常。

◆最快模式(Fastest):传递连接给那些响应最快的服务器。当其中某个服务器发生第二到第7 层的故障,BIG-IP 就把其从服务器队列中拿出,不参加下一次的用户请求的分配,直到其恢复正常。

◆观察模式(Observed):连接数目和响应时间以这两项的最佳平衡为依据为新的请求选择服务器。当其中某个服务器发生第二到第7 层的故障,BIG-IP就把其从服务器队列中拿出,不参加下一次的用户请求的分配,直到其恢复正常。

◆预测模式(Predictive):BIG-IP利用收集到的服务器当前的性能指标,进行预测分析,选择一台服务器在下一个时间片内,其性能将达到最佳的服务器相应用户的请求。(被BIG-IP 进行检测)

◆动态性能分配(Dynamic Ratio-APM):BIG-IP 收集到的应用程序和应用服务器的各项性能参数,动态调整流量分配。

◆动态服务器补充(Dynamic Server Act.):当主服务器群中因故障导致数量减少时,动态地将备份服务器补充至主服务器群。

◆服务质量(QoS):按不同的优先级对数据流进行分配。

◆服务类型(ToS): 按不同的服务类型(在Type of Field中标识)负载均衡对数据流进行分配。

◆规则模式:针对不同的数据流设置导向规则,用户可自行。

负载均衡对应本地的应用交换,大家可以通过对上述负载均衡算法的理解, 结合实际的需求来采用合适你的负载均衡算法,我们常用到的一般是最少连接数、最快反应、或者轮询,决定选用那种算法, 主要还是要结合实际的需求。

服务器负载均衡算法有很多(持续性的和非持续性的),包括轮循算法、最少连接算法、响应时间算法、散列算法、最少连接失误算法,链路带宽算法等等。此外实际服务器(Real Server)可以被分配不同的加权值来调整被分配的流量。比如性能高的大型服务器可配置较大的加权值,而为性能较低的小型服务器设置较小的加权值。为了避免服务器因过载而崩溃,可为实际服务器指定最大连接阈值来避免该服务器过载。任何服务器可被指定为另一台服务器的备份服务器或溢出服务器,从而进一步保证了应用可用性。     非持续性算法(Non-Persistent):一个客户端的不同的请求可能被分配到一个实际服务组中的不同的实服务器上进行处理。主要有轮循算法、最少连接算法、响应速度算法等。    -轮循算法(Round Robin):说明:    每一次来自网络的请求轮流分配给内部中的每台服务器,从1至N然后重新开始。举例:    此种均衡算法适合于服务器组中的所有服务器都有相同的软硬件配置并且平均服务请求相对均衡的情况;     -最少连接算法(Least Connection):说明:    客户端的每一次请求服务在服务器停留的时间都可能会有较大的差异,随着工作时间的加长,如果采用简单的轮循或随机均衡算法,每一台服务器上的连接进程可能会产生极大的不同,这样的结果并不会达到真正的负载均衡。最少连接数均衡算法对内部中有负载的每一台服务器都有一个数据记录,记录的内容是当前该服务器正在处理的连接数量,当有新的服务连接请求时,将把当前请求分配给连接数最少的服务器,使均衡更加符合实际情况,负载更加均衡。

此种负载均衡算法适合长时间处理的请求服务。     -响应速度算法(Response Time):说明:    负载均衡设备对内部各服务器发出一个探测请求(例如Ping),然后根据内部中各服务器对探测请求的最快响应时间来决定哪一台服务器来响应客户端的服务请求。举例:    此种均衡算法能较好地反映服务器的当前运行状态,但最快响应时间仅仅指的是负载均衡设备与服务器间的最快响应时间,而不是客户端与服务器间的最快响应时间。    持续性算法(Persistent):    从一个特定的客户端发出的请求都被分配到一个实服务组中的同一个实服务器上进行处理。主要包括:A.基于IP的算法-Persistent IP (pi):基于用户IP地址来选择服务器。-Hash IP (hi) :基于用户IP地址的HASH值,来选择服务器-Consistent Hash IP (chi):B.基于报头/请求的算法-Hash Header (hh):基于用户请求报中HTTP报头来选择服务器;-Persistent Hostname (ph) :基于用户请求报中HTTP报头的Hostname的HASH值,来选择服务器;-Persistent URL (pu):基于对URI Tag 和值的静态对应关系来选择服务器。-SSL Session ID (sslsid):基于SSL会话ID来选择服务器。C.基于Cookie的算法-Persistent Cookie (pc) : 选择服务器基于用户请求包用Cookie Name / Value 的静态对应关系; -Hash Cookie (hc) :选择服务器基于用户请求包用Cookie Name / Value 的Hash 值对应关系;-Insert Cookie (ic) :选择服务器基于负载均衡器 向服务器响应包中插入Cookie;-Re-write Cookie (rc):选择服务器基于负载均衡器向服务器响应包中重写Cookie值。(必须为重写指定Cookie值的偏移量)

 

文章来自:http://blog.19lou.com/16117492/viewspace-4823477 

posted @ 2010-07-08 15:46 pcxpt.exe 阅读(312) 评论(1) 编辑
  

  服务器负载均衡算法有很多(持续性的和非持续性的),包括轮循算法、最少连接算法、响应时间算法、散列算法、最少连接失误算法,链路带宽算法等等。此外实际服务器(Real Server)可以被分配不同的加权值来调整被分配的流量。比如性能高的大型服务器可配置较大的加权值,而为性能较低的小型服务器设置较小的加权值。为了避免服务器因过载而崩溃,可为实际服务器指定最大连接阈值来避免该服务器过载。任何服务器可被指定为另一台服务器的备份服务器或溢出服务器,从而进一步保证了应用可用性。

    非持续性算法(Non-Persistent):
一个客户端的不同的请求可能被分配到一个实际服务组中的不同的实服务器上进行处理。主要有轮循算法、最少连接算法、响应速度算法等。
    -轮循算法(Round Robin):
说明:
    每一次来自网络的请求轮流分配给内部中的每台服务器,从1至N然后重新开始。
 
举例:
    此种均衡算法适合于服务器组中的所有服务器都有相同的软硬件配置并且平均服务请求相对均衡的情况;
    -最少连接算法(Least Connection):
说明:
    客户端的每一次请求服务在服务器停留的时间都可能会有较大的差异,随着工作时间的加长,如果采用简单的轮循或随机均衡算法,每一台服务器上的连接进程可能会产生极大的不同,这样的结果并不会达到真正的负载均衡。最少连接数均衡算法对内部中有负载的每一台服务器都有一个数据记录,记录的内容是当前该服务器正在处理的连接数量,当有新的服务连接请求时,将把当前请求分配给连接数最少的服务器,使均衡更加符合实际情况,负载更加均衡。
 
举例:此种均衡算法适合长时间处理的请求服务。
 
    -响应速度算法(Response Time):
说明:
    负载均衡设备对内部各服务器发出一个探测请求(例如Ping),然后根据内部中各服务器对探测请求的最快响应时间来决定哪一台服务器来响应客户端的服务请求。
 
举例:
    此种均衡算法能较好地反映服务器的当前运行状态,但最快响应时间仅仅指的是负载均衡设备与服务器间的最快响应时间,而不是客户端与服务器间的最快响应时间。
 
 
    持续性算法(Persistent):
    从一个特定的客户端发出的请求都被分配到一个实服务组中的同一个实服务器上进行处理。主要包括:
A.基于IP的算法
-Persistent IP (pi):基于用户IP地址来选择服务器。
-Hash IP (hi) :基于用户IP地址的HASH值,来选择服务器
-Consistent Hash IP (chi):
B.基于报头/请求的算法
-Hash Header (hh):基于用户请求报中HTTP报头来选择服务器;
-Persistent Hostname (ph) :基于用户请求报中HTTP报头的Hostname的HASH值,来选择服务器;
-Persistent URL (pu):基于对URI Tag 和值的静态对应关系来选择服务器。
-SSL Session ID (sslsid):基于SSL会话ID来选择服务器。
C.基于Cookie的算法
-Persistent Cookie (pc) : 选择服务器基于用户请求包用Cookie Name / Value 的静态对应关系;
-Hash Cookie (hc) :选择服务器基于用户请求包用Cookie Name / Value 的Hash 值对应关系;
-Insert Cookie (ic) :选择服务器基于负载均衡器 向服务器响应包中插入Cookie;
-Re-write Cookie (rc):选择服务器基于负载均衡器向服务器响应包中重写Cookie值。(必须为重写指定Cookie值的偏移量)

 

 文章来源:http://huangkun.blog.51cto.com/190289/33696

posted @ 2010-07-08 15:41 pcxpt.exe 阅读(139) 评论(0) 编辑

一篇UI规范文件

这是一个UI模板规范,在做B/S版应用程序时比较适用,其实这样的东西算不上什么正规的规范,只是为了适应我们现在面对的开发环境和组织流程做的一些权宜的努力,和解决了一些与程序沟通和接口的问题,尽量避免误会和摩擦。

一 适用环境和对象
二 必要性
三 技术原则
四 代码编写规范
五 页面模版使用规范

 

一 适用环境和对象
本规范适用基于浏览器的B/S版软件项目开发工作。开发流程中的模版页面编写和模版文件套用工作必须遵照此规范执行。适用对象为开发编码人员、UI设计人员、模版编写人员、界面测试人员等。
基于客户端的C/S版软件开发工作不适用本技术规范。

二 必要性
本规范旨在制订开发编码人员和UI模版编写人员之间在工作交叉部分的技术标准,使他们遵循同一操作规范,利于交叉工作的平缓顺利交接。以标准化方式,提高沟通和技术协作的水平,提高工作效率。减少和改变责任不明,任务不清,和由此产生的信息沟通不畅、反复修改、重复劳动、效率低下的现象。

三 技术原则
代码规范化书写
代码规范化书写实现了脚本整体风格的一致,保证了同一个人不同时期写的脚本风格保持一致,以及同一个工作组中不同的开发人员编写的脚本风格保持一致。因为开发不可能在孤立中进行,所以代码规范化书写是项目组人员合作沟通的前提。

数据层、结构层、表现层分离
数据内容就是页面实际要传达的真正信息,包含数据、文档或者图片等。这里强调的“真正”,是指纯粹的数据信息本身。把信息内容以一种合适的方式格式化,简言之就是页面排版,例如:分成标题、作者、章、节、段落和列表等,使内容更加具有逻辑性,条理清晰易读易懂,叫做“结构(Structure)” 虽然定义了结构,但是内容还是相同的样式没有改变,例如标题字体没有变大,正文的颜色也没有变化,没有背景,没有修饰。所有这些用来改变内容外观的东西,称之为“表现(Presentation)” “表现”的作用使内容看上去漂亮、赏心悦目、打动人心!

  所有HTML和XHTML页面就是由“结构、表现和行为”这三方面组成的。抽象一点理解,内容是基础层,然后是附加上去结构层和表现层,人对页面内容的交互及操作效果叫做“行为(Behavior)”,

对于数据、结构与表现相分离,最早是在软件开发架构理论中提出来的。UI设计师设计出页面模版,程序员负责内容数据的嵌入,数据可能是从数据库中提取出来,也可能是静态写入的提示性文字,最后形成一个新的页面展示给软件操作者。模版文件的结构利用HTML+XHTML标签来定义,而所有涉及表现的东西通通剥离出来,把它放到一个单独的文件里,这个单独的文件就是CSS。

  数据、结构与表现相分离的好处是:
程序员不需要过多的思考页面显示问题,而只需要根据模版效果把数据放入模版相应的位置。界面的结构和表现由UI设计师负责。填入结构的数据自觉套用设计好了的表现效果。最后呈现一个实现功能的完整界面。
表现层的分离保持整个软件界面视觉的一致性,使改版也变得非常简单,修改样式表就可以了;
由于结构清晰,数据层相对独立,对数据的集成、更新、处理和再利用也更加方便灵活;

四 代码编写规范

(一)目录结构及命名规则

目录结构规范
1、目录建立的原则:以最少的层次提供最清晰简便的访问结构。
2、根目录一般只存放index.htm以及其他必须的系统文件
3、在根目录中原则上应该按照系统的栏目结构,给每一个栏目开设一个目录,根据需要在每一个栏目的目录中开设一个images 和media 的子目录用以放置此栏目专有的图片和多媒体文件,如果这个栏目的内容特别多,又分出很多下级栏目,可以相应的再开设其他目录。根目录下的images用于存放各页面都要使用的公用图片,子目录下的images目录存放本栏目页面使用的私有图片
4、所有JS,ASP,PHP等脚本存放在根目录下的scripts目录
5、所有CGI程序存放在根目录下的cgi-bin目录
6、所有CSS文件存放在根目录下style目录
7、每个语言版本存放于独立的目录。例如:简体中文gb
8、所有flash, avi, ram, quicktime 等多媒体文件存放在根目录下的media目录
9、temp 子目录放客户提供的各种文字图片等等原始资料,以时间为名称开设目录,将客户陆续提供的资料归类整理。

文件和目录命名规范
1、文件命名的原则:以最少的字母达到最容易理解的意义。
2、每一个目录中包含的缺省html 文件,文件名统一用index.htm
3、文件名称统一用小写的英文字母、数字和下划线的组合,不得包含汉字、空格和特殊字符
4、尽量按单词的英语翻译为名称。例如:feedback(信息反馈),aboutus(关于我们) 不到万不得已不要以拼音作为目录名称
5、多个同类型文件使用英文字母加数字命名,字母和数字之间用_分隔。例如:news_01.htm。注意,数字位数与文件个数成正比,不够的用0补齐。例如共有200条新闻,其中第18条命名为news_018.htm

图片的命名规范
1、名称分为头尾两两部分,用下划线隔开。
2、头部分表示此图片的大类性质。例如: 放置在页面顶部的广告、装饰图案等长方形的图片我们取名:banner ;标志性的图片我们取名为:logo ;在页面上位置不固定并且带有链接的小图片我们取名为button ;在页面上某一个位置连续出现,性质相同的链接栏目的图片我们取名:menu ;装饰用的照片我们取名:pic ;不带链接表示标题的图片我们取名:title 依照此原则类推。
3、尾部分用来表示图片的具体含义,用英文字母表示。例如:banner_sohu.gif banner_sina.gif menu_aboutus.gif menu_job.gif title_news.gif logo_police.gif logo_national.gif pic_people.jpg pic_hill.jpg.

4、有onmouse效果的图片,两张分别在原有文件名后加"_on"和"_off"命名

其它文件命名规范
1、js的命名原则以功能的英语单词为名。例如:广告条的js文件名为:ad.js
2、所有的CGI文件后缀为cgi。所有CGI程序的配置文件为config.cgi

(二) html编写规则
  
一般原则
1、在编写模版文件,排布结构表格之前,要思考一个最佳方案,表格的嵌套尽量控制在三层以内;要考虑程序套用的可实现性、通用性、灵活性、预见性,所有内容均采用积木式组织,可替换和删除,并对总体结构不会造成破坏性影响
2、尽量避免 <colspan> <rowspan> 两个标记,经验表明,这两个标记会带来许多麻烦
3、一个网页要尽量避免用整个一张大表格,所有的内容都嵌套在这个大表格之内。因为浏览器在解释页面元素时,是以表格为单位逐一显示,如果一张网页是嵌套在一个大表格之内,那么很可能造成的后果就是,当浏览者敲入网址,他要先面对一片空白很长时间,然后所有的网页内容同时出现。如果必须这样做,请使用 <tbody>标记,以便能够使这个大表格分块显示
4、排版中经常会遇到需要进行首行缩进的处理,不要使用全角空格来达到效果,规范的做法是在样式表中定义 p { text-indent: 2em; } 然后给每一段加上 <p> 标记,注意,一般情况下,请不要省略 </p> 结束标记
5、原则上,我们禁止用 <img width=? height=?> 来人为干预图片显示的尺寸,而且建议 <img> 标签中不要带上width 和height 两个属性,这是因为制作过程中,图片往往需要反复的修改,这样可以避免人为干预图片显示的尺寸,尽可能的发挥浏览器自身的功能;但是这样的一个副作用是当网页还未加载图片时,不会留出图片的站位大小,可能会造成网页在加载过程中抖动(如果图片是插在一个固定大小的表格里的,不会有这个现象),尤其是当图片的尺寸较大时,这种现象会很明显,所以当预料到这种会明显导致网页抖动的情况会发生时,务必在最后给 <img>附上 width 和 height 属性
6、为了最大程度的发挥浏览器自动排版的功能,在一段完整的文字中尽量不要使用<br> 来人工干预分段
7、不同语种的文字之间应该有一个半角空格,但避头的符号之前和避尾的符号之后除外,汉字之间的标点要用全角标点,英文字母和数字周围的括号应该使用半角括号
8、为贯彻结构层和表现层分离的原则,严禁使用传统的HTML3.2/4.0控制表现的标签,例如<font>,<b>,还有本意用于结构后来被滥用于控制表现的标签,例如:<h1>,<table>等。所有的字号都应该用样式表来实现,禁止在页面中出现 <font size= > 标记,<b> </b> <h1> </h1>标记,严禁在结构页面写表现标签
9、不要在网页中连续出现多于一个的也尽量少使用全角空格(英文字符集下,全角空格会变成乱码),空白应该尽量使用 text-indent, padding, margin, hspace, vspace 以及透明的gif 图片来实现。
10、中英文混排时,我们尽可能的将英文和数字定义为verdana 和arial 两种字体
11、行距建议用百分比来定义,常用的两个行距的值是line-height:120%/150%
12、系统中的路径全部采用相对路径
13、为保证系统和浏览器的兼容性,当设置背景图片时,要坚持用双引号。
14、“网页大小”为网页的所有文件大小的总和,包括HTML文件和所有的嵌入的对象。页面大小保持在34K以下为合适

代码规则
head区标识(head区是指首页HTML代码的<head>和</head>之间的内容)
1、公司版权注释
<!--
Generator: 中软融鑫
Creation Data: 2005-8-1
Original Author: 张三
-->

2、网页显示字符集
简体中文:
<META. HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=gb2312">
繁体中文:
<META. HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=BIG5">
英 语:
<META. HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
?
3、简介
<META. NAME="DESCRIPTION" CONTENT="这里填您网站的简介">?

4、网页的css文件定义,所有css文件尽量采用外部调用
<LINK href="style/style.css" rel="stylesheet" type="text/css">

5、网页标题
<title>这里是你的网页标题</title>

6、所有的javascript脚本尽量采取外部调用
<SCRIPT. LANGUAGE="javascript" SRC="script/xxxxx.js"></SCRIPT>

head区可以选择加入的标识
7、设定网页的到期时间。一旦网页过期,必须到fwq上重新调阅。
<META. HTTP-EQUIV="expires" CONTENT="Wed, 26 Feb 1997 08:21:57 GMT">

8、禁止浏览器从本地机的缓存中调阅页面内容。
<META. HTTP-EQUIV="Pragma" CONTENT="no-cache">

9、用来防止别人在框架里调用你的页面。
<META. HTTP-EQUIV="Window-target" CONTENT="_top">

10、自动跳转。
<META. HTTP-EQUIV="Refresh" CONTENT="5;URL=http://www.yahoo.com">
5指时间停留5秒。

11、网页搜索机器人向导.用来告诉搜索机器人哪些页面需要索引,哪些页面不需要索引。
<META. NAME="robots" CONTENT="none">
CONTENT的参数有all,none,index,noindex,follow,nofollow。默认是all。

12、收藏夹图标
<link rel = "Shortcut Icon" href="favicon.ico">

13、搜索关键字
<META. NAME="keywords" CONTENT="关键字1,关键字2,关键字3,...">

  head区以下的标记
1、body标记
为了保证浏览器的兼容性,必须设置页面背景
<body bgcolor="#FFFFFF">

2、table标记
在写 <table> 互相嵌套时,严格按照的规范,对于单独的一个<table>来说,<tr>,<td>各缩进两个半角空格,结束标记和开始标记平齐。<td> 中如果还有嵌套的表格,<table>也缩进两个半角空格,如果<td>中没有任何嵌套的表格,</td> 结束标记应该与 <td> 处于同一行,不要换行。
正确写法:
a\
<table width="100%"? border="0" cellspacing="0" cellpadding="0">
<tr>
<td>&nbsp;</td>
</tr>
<tr>
<td>
<table width="100%"? border="0" cellspacing="0" cellpadding="0">
<tr>
<td>&nbsp;</td>
</tr>
</table>
</td>
</tr>
</table>

b\
<td><img src=”../images/sample.gif”></td>

 错误写法
a\
<table width="100%"? border="0" cellspacing="0" cellpadding="0">
<tr>
<td>&nbsp;</td>
</tr>
<tr>
<td><table width="100%"? border="0" cellspacing="0" cellpadding="0">
<tr>
<td>&nbsp;</td>
</tr>
</table>
</td>
</tr>
</table>

  b\
<td><img src=”../images/sample.gif”>
</td>
这是因为浏览器认为换行相当于一个半角空格,以上不规范的写法相当于无意中增加一个半角空格,如果确实有必要增加一个半角空格,也应该这样写:
<td><img src=”../images/sample.gif”> </td>

于同一个级别的 <table> 一定是左首对齐的,另外不允许没有任何内容的空的单元格存在,高度大于等于12px 的单元格应该 在 <td> 和 </td> 之间写一个&nbsp;,如果高度小于12px, 则应该 在 <td> 和 </td> 之间插入一个1*1 大小的透明的gif 图片,这是因为某些浏览器认为空单元格非法而不会予以解释。如果代码顺序较乱,在DW中可以通过command->apply souce formatting进行重新整理!

3、Width 和height标记
一般情况下只有一列的表格,width 写在<table> 的标签内,只有一行的表格,height 写在 <table> 的标签内,多行多列的表格,width 和height 写在第一行或者第一列的 <td> 标签内。总之遵循一条原则:不出现多于一个的控制同一个单元格大小的height 和width, 保证任何一个width 和height 都是有效的,也就是改动代码中任何一个width 和height 的数值,都应该在浏览器中看到变化。
a、只一列的表格的width标记
<table width="100%"? border="0" cellspacing="0" cellpadding="0">
<tr>
<td>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
</tr>
</table>
b、只一行的表格的height标记
<table width="100%" height="30"? border="0" cellpadding="0" cellspacing="0">
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table>
c、多行多列表格的width和height标记
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="100" height="30">&nbsp;</td>
<td width="200">&nbsp;</td>
<td width="300">&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table>

4、table的width属性

为遵循页面结构灵活性、通用性原则,table的width属性原则上全部写成100%或者不写width属性,不推荐写成其他非100%宽度属性。留空显示效果通过其给外部td施加style的padding属性实现。

 <table width="100%"? border="1" cellspacing="0" cellpadding="0">
 <tr>
  <td width="200" bgcolor="#FF0000" style="padding:20px; ">
    <table width="100%" border="1" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF">
    <tr>
     <td>table宽度100%</td>
    </tr>
     <tr>
      <td>&nbsp;</td>
      </tr>
    </table>
  </td>
  <td>&nbsp;</td>
  </tr>
</table>

需要说明的是这里td的style虽然是css的写法,但不属于表现层的内容,而是属于结构层的内容,所以可以直接写在html标记中间。

5、数据列表表格代码写法
表格外加上一个<div>,并对<div>赋一个id,即<div id =list>,然后通过样式表对这个id下的所有html元素进行控制,
用<th>表示表头
设置每列宽度的位置在表头对应的<th>中,其中列表项中,字数最多或者字数不定的一项不设置宽度。
宽度的值依据列表项内容的多少来定,2个字的30px,三个字40px,时间、年月日(比如2004-11-11)80-120px,
类似于标题的列表项,表格对齐方式为左对齐(align=left),时间,人名一般居中对齐,数据一般右对齐(align=right)。
对齐页面内容时不要用div来对齐,直接在td 或th中写align=…
表头文字一般不折行,方法是在<th>中加上nowrap,或者通过样式表来控制

<table width="100%" border="0" cellspacing="0" cellpadding="0">
  <tr>
   <th width="30" nowrap>选择</th>
   <th align="left" nowrap>标题</th>
   <th width="80" nowrap>发表人</th>
   <th width="120" nowrap>时间</th>
   <th width="40" nowrap>大小</th>
  </tr>
  <tr>
   <td>&nbsp;</td>
   <td align="left">&nbsp;</td>
   <td align="center">&nbsp;</td>
   <td align="center">&nbsp;</td>
   <td align="right">&nbsp;</td>
  </tr>
  <tr>
   <td>&nbsp;</td>
   <td align="left">&nbsp;</td>
   <td align="center">&nbsp;</td>
   <td align="center">&nbsp;</td>
   <td align="right">&nbsp;</td>
</tr>
</table>


(三) css编写规则

css文件调用写法
1、所有的CSS的尽量采用外部调用,特殊情况才允许使用内置html写法。
<LINK href="style/style.css" rel="stylesheet" type="text/css">

css文件结构组织
1、文件提头,css文件名称、时间、作者

2、 将不同目的和效果的CSS选择符分别编组,编组分层级使结构清晰,便于查对。并恰当地成块注释,注释要说明施加的页面文件的对象。顶级注释用*TOP*打头,次级注释不用。

 
.headtext {
 font-size: 14px;
 color: #ffffff;
 font-weight: bold;
}?
.headtext a:link {
 color: #ffffff;
 text-decoration: none;
}
.headtext a:visited {
 color: #ffffff;
 text-decoration: none;
}
.headtext a:hover {
 color: FED078;
 text-decoration:none ;
}


#clientcard {
 align:left;
}
#clientcard th {
 height:20;
 font-size: 12px;
 color: #737373;
 padding-left:10;
 font-weight: bold;
 background-attachment: fixed;
 background:url(images/dot2.gif)

background-repeat: no-repeat;
background-position: left center;
}
#clientcard td {
height:20;
font-size: 12px;
color: #FD783A;
padding-right:25;
}

3、选择符分组的顺序是重定义的最先,伪类其次,自定义最后。便于自己和他人阅读。
例如:

BODY {
margin-left: 0px;
… 
}

TD {
font-size: 12px;

}


a:link {
color:?#484848;
text-decoration: none;
}
a:visited {
color: #484848;
text-decoration: none;
}
a:hover {
color:#BD0800;
text-decoration: underline;
}


.ltreename {
font-size: 14px;

}

类和ID命名规则
1、以功能和定义对象的位置,而不是外观为类和ID命名。例如创建了一个 .smallblue 类,后来打算将文字改大,颜色变为红色,这个类名就不再有任何意义了。所以,用更有描述性的名字如 .copyright 和.info-list更加合适。

单位
1、0不用单位
2、非零值要指明单位,指定字体、边距或大小时,必须指明所用的单位
例如: padding: 0 2px 0 1em;
3、特例:line-height不需要单位

字号大小
1、为了保证不同浏览器上字号保持一致,字号像素px来定义,一般使用中文宋体12px 和14.7px 这是经过优化的字号,黑体字或者宋体字加粗时,一般选用14.7px 的字号比较合适
例如: font-size: 12px;

顺序
1、a:link a:visited a:hover a:actived 要按照规范顺序写
2、边框(border)、边距(margin)和补白(padding)的简写次序为:顺时针方向从上开始,即 Top, Right, Bottom, Left。
例如: margin: 0 1px 3px 5px;表示上边距为零,右边距为1px,依此类推。

组合选择符
1、保持CSS短小对减少下载时间非常重要。尽量为选择符分组、利用继承(inheritance)以及使用简写(shorthand)来减少冗余。

使用图片
1、css中经常遇到使用图片的情况, 图片的路径一律采用相对路径。
例如:

.hurdlename {
font-size: 14px;
color: #0B43C2;
height:25px;
font-weight: bold;
background-image: url(images/rbar_bg.gif);
background-repeat: repeat-y;
text-indent: 12px;
}

.but1{
background-image: url(../images/but1.gif);
font-size: 12px;
color: #000000;
border: 0;
width:85px;
height:26px;
cursor: hand;
}

2、使用图片替换技术时要考虑与系统和文件结构的亲和力。如果引用css的所有文件不在同一级相对路径,就会出现css指定的图片无法显示的问题。在这种情况下不支持使用图片技术。建议采用filter技术
例如:

input.buttton {
filter:progid:DXImageTransform.Microsoft.Gradient(gradienttype=0, startcolorstr=#CFD1CF, endcolorstr=#EFEFEF);
border: #B5B6B5 1px solid;
font-size: 12px;
color: #000000;
cursor: hand;
height:24px;
background:#ffffff;
}

五 页面模版使用规范

页面模版使用规范的目的是统一和约定UI设计、界面工程师与不同的程序编码人员的行为方式,光有了书写代码的规范还不能完全解决界面套用的统一性问题。因为不同的编码人员对同一个模版的理解有可能不同,再加上个人工作习惯的不同,界面套用的结果往往很容易出现差异。哪怕是每人一点点差异,都可能使软件的质量收到很大的影响。

责任分工明确
1、 UI设计、界面工程师负责界面风格的设计和软件模版的编写,并监督界面套用的效果。对软件最终的界面负责。
2、 编码工程师负责软件业务逻辑的实现,软件模版的套用。对软件的数据和程序负责。
3、现实的情况是个别编码工程师在模版套用出现偏差后,在界面工程师提出修改意见的时候拒绝修改,以开发进度、时间不够为由搪塞,甚至主观认为“这个(界面)不重要”致使界面工程师的作用得不到应有的发挥,影响软件产品质量。
4、 解决办法是各负其责。界面问题提高重视程度,并纳入开发流程和进度管理之中。

界面模版交界过程
1、 模版文件制作完成后,在提交给编码工程师时,要简要说明模版的文件的使用说明和提醒。
2、 编码工程师和界面工程师密切合作,完全理解模版使用说明。
3、对界面结构层html的table嵌套关系理解清楚并明确和程序结合的用意。有和程序不相配合的情况,进一步和界面工程师讨论,获得解决方案。不得在界面工程师不知情的情况下随意修改table结构、定位属性和嵌套关系。这样做的坏处是虽然一个人解决了暂时的显示问题,但和其他编码工程师套用的结果出现不同。也不利于界面工程师控制总体界面。
4、 对表现层的界面元素和css文件选择符的对应关系。做到心中有数,理解一个模版文件,到套用其他文件时就能够举一反三。

 5、编码工程师完全理解了界面模版后,就能够顺畅的把数据层的内容放到结构层合适的位置,并指定表现层合适的选择符属性。完成界面套用工作。

模版说明的内容
1、 总体的界面结构
2、 页面板块的布局和定位table的写法
3、 table嵌套的方式的理由
4、 不同功能的界面显示单元说明和使用方法
5、 css文件中选择符的使用说明,一般的都能理解,个别特殊的要着重说明。

Css文件的版本控制
Css文件应引入版本控制的机制,项目组中应指定专人负责css文件的上传和修改。fwq的css文件和界面工程师的css文件应该同步更新。不支持编码工程师随意添加选择符修改css文件。谁都可以改就没有标准,没有版本控制就做很难做到界面统一 

posted @ 2010-07-08 12:10 pcxpt.exe 阅读(11726) 评论(6) 编辑
类型 
TypePrefixExample
ArrayarrarrShoppingList
BooleanblnblnIsPostBack
BytebytbytPixelValue
CharchrchrDelimiter
DateTimedtmdtmStartDate
DecimaldecdecAverageHeight
DoubledbldblSizeofUniverse
IntegerintintRowCounter
LonglnglngBillGatesIncome
ObjectobjobjReturnValue
ShortshrshrAverage
SinglesngsngMaximum
StringstrstrFirstName


WebControls 
TypePrefixExample
AdRotatoradrtadrtTopAd
ButtonbtnbtnSubmit
CalendarcalcalMettingDates
CheckBoxchkchkBlue
CheckBoxListchklchklFavColors
CompareValidatorvalcvalcValidAge
CustomValidatorvalxvalxDBCheck
DataGriddgrddgrdTitles
DataListdlstdlstTitles
DropDownListdropdropCountries
HyperLinklnklnkDetails
ImageimgimgAuntBetty
ImageButtonibtnibtnSubmit
LabellbllblResults
LinkButtonlbtnlbtnSubmit
ListBoxlstlstCountries
PanelpnlpnlForm2
PlaceHolderplhplhFormContents
RadioButtonradradFemale
RadioButtonListradlradlGender
RangeValidatorvalgvalgAge
RegularExpressionvalevaleEmail_Validator
RepeaterrptrptQueryResults
RequiredFieldValidatorvalrvalrFirstName
TabletbltblCountryCodes
TableCelltblctblcGermany
TableRowtblrtblrCountry
TextBoxtxttxtFirstName
ValidationSummaryvalsvalsFormErrors
XMLxmlcxmlcTransformResults


ADO.NET 
TypePrefixExample
ConnectionconconNorthwind
CommandcmdcmdReturnProducts
ParameterparmparmProductID
DataAdapterdaddadProducts
DataReaderdtrdtrProducts
DataSetdstdstNorthWind
DataTabledtbldtblProduct
DataRowdrowdrowRow98
DataColumndcoldcolProductID
DataRelationdreldrelMasterDetail
DataViewdvwdvwFilteredProducts

posted @ 2010-07-08 12:08 pcxpt.exe 阅读(113) 评论(0) 编辑

[C#].Net生成静态页面方案汇集(转)
 


方案1:
/// <summary>
/// 传入URL返回网页的html代码
/// </summary>
/// <param name="Url">URL</param>
/// <returns></returns>
public static string getUrltoHtml(string Url)
{
errorMsg = "";
try
{
System.Net.WebRequest wReq = System.Net.WebRequest.Create(Url);
// Get the response instance.
System.Net.WebResponse wResp =wReq.GetResponse();
// Read an HTTP-specific property
//if (wResp.GetType() ==HttpWebResponse)
//{
//DateTime updated =((System.Net.HttpWebResponse)wResp).LastModified;
//}
// Get the response stream.
System.IO.Stream respStream = wResp.GetResponseStream();
// Dim reader As StreamReader = New StreamReader(respStream)
System.IO.StreamReader reader = new System.IO.StreamReader(respStream, System.Text.Encoding.GetEncoding("gb2312"));
return reader.ReadToEnd();

}
catch(System.Exception ex)
{
errorMsg = ex.Message ;
}
return "";
}

  你可以用这个函数获取网页的客户端的html代码,然后保存到.html文件里就可以了。

  方案2:

  生成单个的静态页面不是难点,难的是各个静态页面间的关联和链接如何保持完整;特别是在页面频繁更新、修改、或删除的情况下;

  像阿里巴巴的页面也全部是html的,估计用的是地址映射的功能关于地址映射可参考:http://www.easewe.com/Article/ShowArticle.aspx?article=131

  可以看看这个页面,分析一下他的“竞价倒计时”功能http://info.china.alibaba.com/news/subject/v1-s5011580.html?head=top4&Bidding=home5

  ASP.Net生成静态HTML页
  在Asp中实现的生成静态页用到的FileSystemObject对象!
  在.Net中涉及此类操作的是System.IO
  以下是程序代码 注:此代码非原创!参考别人代码

CODE:
//生成HTML页
public static bool WriteFile(string strText,string strContent,string strAuthor)
{
string path = HttpContext.Current.Server.MapPath("/news/");
Encoding code = Encoding.GetEncoding("gb2312");
// 读取模板文件
string temp = HttpContext.Current.Server.MapPath("/news/text.html");
StreamReader sr=null;
StreamWriter sw=null;
string str="";
try
{
sr = new StreamReader(temp, code);
str = sr.ReadToEnd(); // 读取文件
}
catch(Exception exp)
{
HttpContext.Current.Response.Write(exp.Message);
HttpContext.Current.Response.End();
sr.Close();
}


string htmlfilename=DateTime.Now.ToString("yyyyMMddHHmmss")+".html";
// 替换内容
// 这时,模板文件已经读入到名称为str的变量中了
str =str.Replace("ShowArticle",strText); //模板页中的ShowArticle
str = str.Replace("biaoti",strText);
str = str.Replace("content",strContent);
str = str.Replace("author",strAuthor);
// 写文件
try
{
sw = new StreamWriter(path + htmlfilename , false, code);
sw.Write(str);
sw.Flush();
}
catch(Exception ex)
{
HttpContext.Current.Response.Write(ex.Message);
HttpContext.Current.Response.End();
}
finally
{
sw.Close();
}
return true;

  此函数放在Conn.CS基类中了在添加新闻的代码中引用 注:工程名为Hover

if(Hover.Conn.WriteFilethis.Title.Text.ToString),this.Content.Text.ToString),this.Author.Text.ToString)))
{
Response.Write("添加成功");
}
else
{
Response.Write("生成HTML出错!");
}

  模板页Text.html代码

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>ShowArticle</title>
<body>
biaoti
<br>
content<br>
author
</body>
</HTML>
biaoti
<br>
content<br>
author
</body>
</HTML>

  提示添加成功后会出以当前时间为文件名的html文件!上面只是把传递过来的几个参数直接写入了HTML文件中,在实际应用中需要先添加数据库,然后再写入HTML文件

  方案3:给一个客户端参考的例子(SJ)

  它的作用在于以客户端的方式获取某个页面的代码,然后可以做为其他用途,本例是直接输出

<script>
var oXmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
oXmlHttp.open("GET","http://www.webjx.com", false);
oXmlHttp.send()
var oStream = new ActiveXObject("ADODB.Stream");
if(oStream == null)
alert("您的机器不支持ADODB.Stream.")
else
{
oStream.Type=1;
oStream.Mode=3;
oStream.Open() ;
oStream.Write(oXmlHttp.responseBody);
oStream.Position= 0;
oStream.Type= 2;
oStream.Charset="gb2312";
var result= oStream.ReadText();
oStream.Close();
oStream = null;
var aa = window.open("","")
document.write(result);
aa.document.write(result);
}
</script>

  方案4:学csdn一样。用xml保存数据,模版XSL也只有一个文件。

  使用xml来保存数据,使用xsl来定义模板并且生称数据。可以通过xsl来很方便的在客户端或者服务段显示数据。如果要生成静态叶面那更简单了。去查一下.net的xml类包问题解决。

  优点:可以方便快速转换成你想要的格式和内容。
  缺点:需要学习更多的内容,不好入门。

  方案5:

  思路

  1. 利用如Dw-Mx这样的工具生成html格式的模板,在需要添加格式的地方加入特殊标记(如$htmlformat$),动态生成文件时利用代码读取此模板,然后获得前台输入的内容,添加到此模板的标记位置中,生成新文件名后写入磁盘,写入后再向数据库中写入相关数据。
2. 使用后台代码硬编码Html文件,可以使用HtmlTextWriter类来写html文件。
优点

  1. 可以建立非常复杂的页面,利用包含js文件的方法,在js文件内加入document.write()方法可以在所有页面内加入如页面头,广告等内容。

  2. 静态html文件利用MS Windows2000的Index Server可以建立全文搜索引擎,利用asp.net可以以DataTable的方式得到搜索结果。而Win2000的Index服务无法查找xml文件的内容。如果包括了数据库搜索与Index索引双重查找,那么此搜索功能将非常强大。

  3. 节省服务器的负荷,请求一个静态的html文件比一个aspx文件服务器资源节省许多。

  缺点

  思路二: 如果用硬编码的方式,工作量非常大,需要非常多的html代码。调试困难。而且使用硬编码生成的html样式无法修改,如果网站更换样式,那么必须得重新编码,给后期带来巨大的工作量。

  因此这里采用的是第一种思路

  示列代码

  1.定义(template.htm)html模板页面

  <html>

  <head>

  <title></title>

  <meta http-equiv="Content-Type" content="text/html; charset=gb2312">

  </head>

  <body >

  <table $htmlformat[0] height="100%" border="0" width="100%" cellpadding="10" cellspacing="0" bgcolor="#eeeeee" style="border:1px solid #000000">

  <tr>

  <td width="100%" valign="middle" align="left">

  <span style="color: $htmlformat[1];font-size: $htmlformat[2]">$htmlformat[3]</span>

  </td>

  </tr>

  </table>

  </body>

  </html>

  2.asp.net代码:

  //---------------------读html模板页面到stringbuilder对象里----

  string[] format=new string[4];//定义和htmlyem标记数目一致的数组

  StringBuilder htmltext=new StringBuilder();

  try

  {

   using (StreamReader sr = new StreamReader("存放模板页面的路径和页面名"))

   {

  String line;

  while ((line = sr.ReadLine()) != null)

  {

   htmltext.Append(line);

  }

  sr.Close();

   }

  }

  catch

  {

   Response.Write("<Script>alert('读取文件错误')</Script>");

  }

  //---------------------给标记数组赋值------------

  format[0]="background="/blog/bg.jpg"";//背景图片

  format[1]= "#990099";//字体颜色

  format[2]="150px";//字体大小

  format[3]= "<marquee>生成的模板html页面</marquee>";//文字说明

  //----------替换htm里的标记为你想加的内容

  for(int i=0;i<4;i++)

  {

   htmltext.Replace("$htmlformat["+i+"]",format[i]);

  }

  //----------生成htm文件------------------――

  try

  {

   using(StreamWriter sw=new StreamWriter("存放路径和页面名",false,System.Text.Encoding.GetEncoding("GB2312")))

  {

   sw.WriteLine(htmltext);

   sw.Flush();

   sw.Close();

  }

  }

  catch

  {

  Response.Write ("The file could not be wirte:");

  }


<!--Main.Aspx-->
<%@ page language="C#" %>
<%@ import namespace=System.IO %>
<script runat="server">
protected override void OnInit (EventArgs e)
{
  int id;
  try
  {
    id = int.Parse (Request.QueryString["id"]);
  }
  catch
  {
    throw (new Exception ("页面没有指定id"));
  }
 
  string filename=Server.MapPath("statichtml_"+id+".html");
 
  //尝试读取已有文件
  Stream s = GetFileStream (filename);
  if (s != null)//如果文件存在并且读取成功
  {
    using (s)
    {
      Stream2Stream (s, Response.OutputStream);
      Response.End ();
    }
  }
 
 
  //调用Main_Execute,并且获取其输出
  StringWriter sw = new StringWriter ();
  Server.Execute ("Main_Execute.aspx", sw);
 
  string content = sw.ToString ();
 
  //输出到客户端
  Response.Write(content);
  Response.Flush();
 
  //写进文件
 
  try
  {
    using (FileStream fs = new FileStream (filename, FileMode.Create, FileAccess.Write, FileShare.Write))
    {
      using (StreamWriter streamwriter = new StreamWriter (fs, Response.ContentEncoding))
      {
        streamwriter.Write (content);
      }
    }
  }
  finally
  {
    //Response.End ();
  }
}
static public void Stream2Stream (Stream src, Stream dst)
{
  byte[] buf = new byte[4096];
  while (true)
  {
    int c = src.Read (buf, 0, buf.Length);
    if(c==0)
      return;
    dst.Write (buf, 0, c);
  }
}
public Stream GetFileStream(string filename)
{
  try
  {
    DateTime dt = File.GetLastWriteTime (filename);
    TimeSpan ts=dt - DateTime.Now;
    if(ts.TotalHours>1)
      return null;    //1小时后过期
    return new FileStream (filename, FileMode.Open, FileAccess.Read, FileShare.Read);
  }
  catch
  {
    return null;
  }
}
</script>


<!--Main_Execute.aspx-->
<%@ page language="C#" %>
<html>
<head runat="server">
  <title>Untitled Page</title>
</head>
<body>

ID:
<%=Request.QueryString["id"]%>

</body>
</html>



其中原理是这样的.
Main_Execute.aspx是生成HTML的页面.

现在用Main.aspx来对它进行缓存.
过程如下:

首先根据页面参数算出文件名.(这个例子只根据Request.QueryString["id"]来算)
尝试读取缓存的文件.如果成功,那么Response.End();
如果不成功:
使用Server.Execute来调用Main_Execute.aspx,并且获取它的结果内容.
得到内容后,立刻输出到客户端.
最后把内容写进文件里,提供给下一次做为缓存度取.

<!--Main.Aspx-->
<%@ page language="C#" %>
<%@ import namespace=System.IO %>
<script runat="server">
protected override void OnInit (EventArgs e)
{
  int id;
  try
  {
    id = int.Parse (Request.QueryString["id"]);
  }
  catch
  {
    throw (new Exception ("页面没有指定id"));
  }
 
  string filename=Server.MapPath("statichtml_"+id+".html");
 
  //尝试读取已有文件
  Stream s = GetFileStream (filename);
  if (s != null)//如果文件存在并且读取成功
  {
    using (s)
    {
      Stream2Stream (s, Response.OutputStream);
      Response.End ();
    }
  }
 
 
  //调用Main_Execute,并且获取其输出
  StringWriter sw = new StringWriter ();
  Server.Execute ("Main_Execute.aspx", sw);
 
  string content = sw.ToString ();
 
  //输出到客户端
  Response.Write(content);
  Response.Flush();
 
  //写进文件
 
  try
  {
    using (FileStream fs = new FileStream (filename, FileMode.Create, FileAccess.Write, FileShare.Write))
    {
      using (StreamWriter streamwriter = new StreamWriter (fs, Response.ContentEncoding))
      {
        streamwriter.Write (content);
      }
    }
  }
  finally
  {
    //Response.End ();
  }
}
static public void Stream2Stream (Stream src, Stream dst)
{
  byte[] buf = new byte[4096];
  while (true)
  {
    int c = src.Read (buf, 0, buf.Length);
    if(c==0)
      return;
    dst.Write (buf, 0, c);
  }
}
public Stream GetFileStream(string filename)
{
  try
  {
    DateTime dt = File.GetLastWriteTime (filename);
    TimeSpan ts=dt - DateTime.Now;
    if(ts.TotalHours>1)
      return null;    //1小时后过期
    return new FileStream (filename, FileMode.Open, FileAccess.Read, FileShare.Read);
  }
  catch
  {
    return null;
  }
}
</script>


<!--Main_Execute.aspx-->
<%@ page language="C#" %>
<html>
<head runat="server">
  <title>Untitled Page</title>
</head>
<body>

ID:
<%=Request.QueryString["id"]%>

</body>
</html>



其中原理是这样的.
Main_Execute.aspx是生成HTML的页面.

现在用Main.aspx来对它进行缓存.
过程如下:

首先根据页面参数算出文件名.(这个例子只根据Request.QueryString["id"]来算)
尝试读取缓存的文件.如果成功,那么Response.End();
如果不成功:
使用Server.Execute来调用Main_Execute.aspx,并且获取它的结果内容.
得到内容后,立刻输出到客户端.
最后把内容写进文件里,提供给下一次做为缓存度取.
posted @ 2010-07-06 09:39 pcxpt.exe 阅读(246) 评论(0) 编辑
摘要: 一 实用且必用的小脚本代码二 鼠标旁边的提示信息,类似与163登录后的页面提示效果三 如果文字过长,则将过长的部分变成省略号显示四 滚动的图片五 接收键盘指令的脚本六 让你的文本链接渐隐渐显七 类似与QQ的好友/黑名单之类的树型菜单-----推荐八 很多的脚本翻页------推荐九 DIV的透明层实现十 JSP页面自动生成html页面/或任何格式页面-----推荐十一 超级强大的表单验证-----...阅读全文
posted @ 2010-07-05 12:13 pcxpt.exe 阅读(831) 评论(2) 编辑

Socket使用方法回顾

Socket类简要介绍

socket下提供的主要类有四个,分别是socket,tcpclient,tcplistener,udpclient,他们的作用如下:

  1. Socket 含有大量方法用于网络连接,.net中的一些高级类如webrequest,tcpclient等均调用此类来进行操作
  2. TcpClient  提供客户端连接,用于创建和使用tcp网络服务
  3. TcpListener  用于从tcp网络客户端侦听连接
  4. UdpClient  为udp客户端创建连接,是tcp的备用协议,在本地网络使用

 Demo测试

这个Demo含有两个project,一个是server,一个是client,为了简洁,均采用控制台程序

image

服务端:

 

代码
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 
using System.Net.Sockets; 

namespace SocketServer 

    
class Program 
    { 
        
public static TcpListener tcpListener; 
        
private static NetworkStream networkStream; 
        
private static StreamReader streamReader; 
        
private static StreamWriter streamWriter; 
        
public static Socket socketForClient; 

        
static void Main(string[] args) 
        { 
            
try 
            { 
                tcpListener 
= new TcpListener(1234); 
                tcpListener.Start(); 
                Console.WriteLine(
"服务启动,开始监控1234端口"); 

                socketForClient 
= tcpListener.AcceptSocket(); 
                networkStream 
= new NetworkStream(socketForClient); 
                streamWriter 
= new StreamWriter(networkStream); 
                streamReader 
= new StreamReader(networkStream); 
                
try 
                { 
                    
if (socketForClient.Connected) 
                    { 
                        Console.WriteLine(
"客户端已连接"); 
                        
string strInput = streamReader.ReadLine(); 
                        Console.WriteLine(
"从客户端传入的字符串是:" + strInput); 
                        
string strOutput = strInput.ToUpper(); 
                        streamWriter.Write(strOutput); 
                        Console.WriteLine(
"转换后字符串是" + strOutput); 
                        streamWriter.Flush(); 
                    } 
                } 
                
catch (Exception ex) 
                { 
                    Console.WriteLine(
"出现异常:" + ex.Message); 
                } 
            } 
            
catch(Exception ex) 
            { 
                Console.WriteLine(
"发生异常,关闭连接"); 
                tcpListener.Stop(); 
                streamWriter.Close(); 
                streamReader.Close(); 
                networkStream.Close(); 
            } 
        } 
    } 
}

 

客户端:

 

代码
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 
using System.Net.Sockets; 

namespace SocketClient 

    
class Program 
    { 
        
public static TcpClient myclient; 
        
private static NetworkStream networkStream; 
        
private static StreamReader streamReader; 
        
private static StreamWriter streamWriter; 

        
static void Main(string[] args) 
        { 
            
try 
            { 
                
try 
                { 
                    myclient 
= new TcpClient("localhost"1234); 
                    Console.WriteLine(
"已经连接到localhost的1234端口"); 
                } 
                
catch (Exception ex) 
                { 
                    Console.WriteLine(
"未能在1234端口连接上服务器"); 
                } 
                networkStream 
= myclient.GetStream(); 
                streamReader 
= new StreamReader(networkStream); 
                streamWriter 
= new StreamWriter(networkStream); 
                Console.WriteLine(
"请输入一串小写字母:"); 
                
string strInput = Console.ReadLine(); 
                streamWriter.Write(strInput); 
                Console.WriteLine(
"正在发送消息"); 
                streamWriter.Flush(); 
                
string strServerComes = streamReader.ReadLine(); 
                Console.WriteLine(
"正在从服务端收取消息"); 
                Console.WriteLine(
"从服务端收到的消息是:" + strServerComes); 
            } 
            
catch(Exception ex) 
            { 
                Console.WriteLine(
"发生异常,关闭连接"); 
                streamReader.Close(); 
                streamWriter.Close(); 
                networkStream.Close(); 
            } 
        } 
    } 
}

 

 

image 

image

在windows 7 中需要安全设置。

posted @ 2010-07-01 10:23 pcxpt.exe 阅读(304) 评论(1) 编辑
 

写的一个XML操作类,包括读取/插入/修改/删除。

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml;

namespace PuTianCheng
{
    /// <summary>
    /// XmlHelper 的摘要说明
    /// </summary>
    public class XmlHelper
    {
        public XmlHelper()
        {
        }

        /// <summary>
        /// 读取数据
        /// </summary>
        /// <param name="path">路径</param>
        /// <param name="node">节点</param>
        /// <param name="attribute">属性名,非空时返回该属性值,否则返回串联值</param>
        /// <returns>string</returns>
        /**************************************************
         * 使用示列:
         * XmlHelper.Read(path, "/Node", "")
         * XmlHelper.Read(path, "/Node/Element[@Attribute='Name']", "Attribute")
         ************************************************/
        public static string Read(string path, string node, string attribute)
        {
            string value = "";
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(path);
                XmlNode xn = doc.SelectSingleNode(node);
                value = (attribute.Equals("") ? xn.InnerText : xn.Attributes[attribute].Value);
            }
            catch { }
            return value;
        }

        /// <summary>
        /// 插入数据
        /// </summary>
        /// <param name="path">路径</param>
        /// <param name="node">节点</param>
        /// <param name="element">元素名,非空时插入新元素,否则在该元素中插入属性</param>
        /// <param name="attribute">属性名,非空时插入该元素属性值,否则插入元素值</param>
        /// <param name="value">值</param>
        /// <returns></returns>
        /**************************************************
         * 使用示列:
         * XmlHelper.Insert(path, "/Node", "Element", "", "Value")
         * XmlHelper.Insert(path, "/Node", "Element", "Attribute", "Value")
         * XmlHelper.Insert(path, "/Node", "", "Attribute", "Value")
         ************************************************/
        public static void Insert(string path, string node, string element, string attribute, string value)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(path);
                XmlNode xn = doc.SelectSingleNode(node);
                if (element.Equals(""))
                {
                    if (!attribute.Equals(""))
                    {
                        XmlElement xe = (XmlElement)xn;
                        xe.SetAttribute(attribute, value);
                    }
                }
                else
                {
                    XmlElement xe = doc.CreateElement(element);
                    if (attribute.Equals(""))
                        xe.InnerText = value;
                    else
                        xe.SetAttribute(attribute, value);
                    xn.AppendChild(xe);
                }
                doc.Save(path);
            }
            catch { }
        }

        /// <summary>
        /// 修改数据
        /// </summary>
        /// <param name="path">路径</param>
        /// <param name="node">节点</param>
        /// <param name="attribute">属性名,非空时修改该节点属性值,否则修改节点值</param>
        /// <param name="value">值</param>
        /// <returns></returns>
        /**************************************************
         * 使用示列:
         * XmlHelper.Insert(path, "/Node", "", "Value")
         * XmlHelper.Insert(path, "/Node", "Attribute", "Value")
         ************************************************/
        public static void Update(string path, string node, string attribute, string value)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(path);
                XmlNode xn = doc.SelectSingleNode(node);
                XmlElement xe = (XmlElement)xn;
                if (attribute.Equals(""))
                    xe.InnerText = value;
                else
                    xe.SetAttribute(attribute, value);
                doc.Save(path);
            }
            catch { }
        }

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="path">路径</param>
        /// <param name="node">节点</param>
        /// <param name="attribute">属性名,非空时删除该节点属性值,否则删除节点值</param>
        /// <param name="value">值</param>
        /// <returns></returns>
        /**************************************************
         * 使用示列:
         * XmlHelper.Delete(path, "/Node", "")
         * XmlHelper.Delete(path, "/Node", "Attribute")
         ************************************************/
        public static void Delete(string path, string node, string attribute)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(path);
                XmlNode xn = doc.SelectSingleNode(node);
                XmlElement xe = (XmlElement)xn;
                if (attribute.Equals(""))
                    xn.ParentNode.RemoveChild(xn);
                else
                    xe.RemoveAttribute(attribute);
                doc.Save(path);
            }
            catch { }
        }
    }
}

==================================================

XmlFile.xml:
<?xml version="1.0" encoding="utf-8"?>
<Root />

==================================================

使用方法:

string xml = Server.MapPath("XmlFile.xml");
//插入元素
//XmlHelper.Insert(xml, "/Root", "Studio", "", "");
//插入元素/属性
//XmlHelper.Insert(xml, "/Root/Studio", "Site", "Name", "小路工作室");
//XmlHelper.Insert(xml, "/Root/Studio", "Site", "Name", "丁香鱼工作室");
//XmlHelper.Insert(xml, "/Root/Studio", "Site", "Name", "谱天城工作室");
//XmlHelper.Insert(xml, "/Root/Studio/Site[@Name='谱天城工作室']", "Master", "", "红尘静思");
//插入属性
//XmlHelper.Insert(xml, "/Root/Studio/Site[@Name='小路工作室']", "", "Url", "http://www.wzlu.com/");
//XmlHelper.Insert(xml, "/Root/Studio/Site[@Name='丁香鱼工作室']", "", "Url", "http://www.luckfish.net/");
//XmlHelper.Insert(xml, "/Root/Studio/Site[@Name='谱天城工作室']", "", "Url", "http://www.putiancheng.com/");
//修改元素值
//XmlHelper.Update(xml, "/Root/Studio/Site[@Name='谱天城工作室']/Master", "", "RedDust");
//修改属性值
//XmlHelper.Update(xml, "/Root/Studio/Site[@Name='谱天城工作室']", "Url", "http://www.putiancheng.net/");
//XmlHelper.Update(xml, "/Root/Studio/Site[@Name='谱天城工作室']", "Name", "PuTianCheng Studio");
//读取元素值
//Response.Write("<div>" + XmlHelper.Read(xml, "/Root/Studio/Site/Master", "") + "</div>");
//读取属性值
//Response.Write("<div>" + XmlHelper.Read(xml, "/Root/Studio/Site", "Url") + "</div>");
//读取特定属性值
//Response.Write("<div>" + XmlHelper.Read(xml, "/Root/Studio/Site[@Name='丁香鱼工作室']", "Url") + "</div>");
//删除属性
//XmlHelper.Delete(xml, "/Root/Studio/Site[@Name='小路工作室']", "Url");
//删除元素
//XmlHelper.Delete(xml, "/Root/Studio", "");

posted @ 2010-07-01 10:02 pcxpt.exe 阅读(425) 评论(1) 编辑

提高 .NET 应用 XML 处理性能的几点开发经验(转载)

          把这二周做的一个 .NET 应用性能优化的实践经验分享出来,记录的同时也请大家踊跃发言,分享更多。由于业务特点、整体架构设计和外围系统等因素,这个应用的性能瓶颈主要是由于 XML 相关处理造成的,其中包括大 XML 数据(50M 以上)的解析和查询、从外围系统下载 XML 数据、B/S 结构中的并发处理快速响应要求等。通过本次实践,对 .NET Framework 提供的 XML 处理有了更加深入的研究和理解,并做了一些验证并实施。最终结果还是很理想的,主要降低服务器 CPU 利用率的目标也达到,从之前的 50% 以上 (双核机器,实际上单个核心已经饱和)降低到 10% 左右,有些业务可降到 5% 左右。

 

          首先列下我所了解的 XML 处理方式有哪些。 在 .NET Framework 3.5 中,如果不使用其它的解析器(如 vtd-xml)的话,主要会有以下 4 种:

 

基于 XML Dom 的 Document 树处理方式

          主要使用的方法或属性有 Load、LoadXml、OuterXMl、InnerXml、SelectNodes (XPath 查询)等。

 

C#代码 复制代码
  1. XmlDocument doc = new XmlDocument();   
  2.   
  3. doc.Load("data.xml");   
  4.   
  5. XmlNodeList children = doc DocumentElement.SelectNodes("*");   
  6.   
  7. XmlNodeList allauthors = doc.SelectNodes("//authors/author");   
  8.   
  9. foreach (XmlNode node in allauthors)   
  10. {   
  11.     // handle node.   
  12. }  

 

基于 XML Dom 的准 SAX 处理方式

          主要使用的方法或属性有 LoadXml、CreateNavigator、Select (XPath 查询)、MoveNext 等。这里之所以说是“准 SAX 方式”,是因为这里虽然具备了单向向前和只读以及标签触发的性质,但这毕竟是在使用的 Xml Dom 的前提下,也就是必须要有构造 Document 树(LoadXml 方法调用)的过程。

 

C#代码 复制代码
  1. XmlDocument dom = new XmlDocument();   
  2.   
  3. dom.Load("data.xml");   
  4.   
  5. XPathNavigator nav = dom.CreateNavigator();   
  6.   
  7. nav.MoveToRoot();   
  8.   
  9. string xpath = @"//Rows[OneColumn = 'SomeValue']";   
  10.   
  11. XPathNodeIterator ite = nav.Select(xpath, null);   
  12.   
  13. while (ite.MoveNext())   
  14. {   
  15.     // handle ite.Current.Value.   
  16. }  

 

基于 XmlTextReader 的 SAX 处理方式

          主要使用的方法或属性有 Read、LocalName、ReadString 等。这种方法与 SAX 处理模型一致,单向向前、标签触发、无需 Dom 树支持。

 

C#代码 复制代码
  1. xmlReader = new XmlTextReader("data.xml");   
  2.   
  3. while (xmlReader.Read())   
  4. {   
  5.     switch (xmlReader.LocalName)   
  6.     {   
  7.         case "OneColumn":   
  8.         {   
  9.             // handle xmlReader.ReadString().   
  10.   
  11.             break;   
  12.         }   
  13.         case "OtherColumn":   
  14.         {   
  15.             // handle "OtherColumn" element.   
  16.   
  17.             break;   
  18.         }           
  19.         default:   
  20.         {   
  21.             break;   
  22.         }   
  23.     }   
  24. }  

 

          需要注意的是,在使用这种 XmlTextReader 拉模型的处理方式时,很少会使用以 XML 文件作为数据源来构造 XmlTextReader 对象的,更多方式会使用流来构造,因此也可以想到,很容易使用这种流加上单向向前推进的方式来实现 XML 数据的加载、解析加处理的并行处理,可以提高整体性能,这在后面还会提到。

 

基于 Linq to XML 的处理方式

          这是 .NET Framework 3.5 提供的新特性,与上面 3 种方式截然不同,它使用 XDocument 作为底层数据结构支持,使用 Linq to Entity 对集合的扩展框架直接查询 XDocument 内容,可以附加条件并排顺序、分组等,并通过延迟加载、处理的方式来减少不必要的操作,提高性能。主要会使用这些方法或属性 Load、Descendants、Element().Value、Select、Where、Order 等。

 

C#代码 复制代码
  1. private void InitData()   
  2. {   
  3.     XDocument xdom = XDocument.Load("data.xml");   
  4.   
  5.     // Query rows by "OonColumn" value equal "SomeValue"   
  6.     var data = from d in xdom.Descendants("Rows")   
  7.                where d.Element("OneColumn").Value == "SomeValue"  
  8.                orderby d.Element("OneColumn").Value   
  9.                select d;   
  10.   
  11.     BuildColumnDropDownList(data, "OneColumn"this.DropDownList1);   
  12.     BuildColumnDropDownList(data, "TwoColumn"this.DropDownList2);   
  13.   
  14.     var subData = data.Skip(this.pageIndex * 20).Take(20);  // Paging.   
  15.   
  16.     this.Repeater1.DataSource = subData;   
  17.     this.Repeater1.DataBind();   
  18. }   
  19.   
  20. private void BuildColumnDropDownList(IOrderedEnumerable<XElement> data, string columnName, DropDownList dropDownList)   
  21. {   
  22.     if (data == null)   
  23.         throw new ArgumentNullException("data");   
  24.   
  25.     if (string.IsNullOrEmpty(columnName))   
  26.         throw new ArgumentNullException("columnName");   
  27.   
  28.     if (dropDownList == null)   
  29.         throw new ArgumentNullException("dropDownList");   
  30.   
  31.     var colData = from irx in data.Descendants(columnName)   
  32.                   group irx by irx.Value into g   
  33.                   orderby g.Key   
  34.                   select g.Key;   
  35.   
  36.     dropDownList.DataSource = colData.ToArray();   
  37.     dropDownList.DataBind();   
  38. }  

 

          上面的 4 种处理方法各有利弊,选择出相对较高性能的处理方法不是绝对的,这需要考虑具体的 XML 处理特点和设计。下面列出我了解的一些会影响 XML 处理性能的关键点,欢迎讨论、补充。

 

  1. 要处理的 XML 数据量大小。可以以 1M 大小为界线。
  2. 如果采用构建 XML Dom 树的方式,那么 XML 源是否每次都变化。也就是说是否每次处理 XML 数据都需要通过 Load 来重新构建 Dom 树,即 Dom 树是否可以缓存。典型的如查询类业务,所查询的源是不变的,但每次都要重查,这样就可以一次加载 Dom 树并缓存。
  3. 程序内部存储 XML 数据的方式。是采用 Dom 树(XmlDocument 类型)还是采用 XML 字符串(String 类型),实际上采用哪种方式都可以,但关键是要统一,不能某些模块使用 XmlDocument,某些模块使用 String,原因也很简单,InnerXML 或 OuterXML、LoadXml 都不是免费的午餐,每次调用(成对)都无谓的浪费些资源。

 

          结合上面列出的关键点,把已有的 4 种方法来一一对比。

 

          首先是 XML 数据量的事,根据测试和验证发现,数据量大小直接影响 Dom 树的解析、构造性能(主要是 CPU、Memory 利用率和响应时间),即 Load、LoadXML 方法,可见除了第三种“基于 XmlTextReader 的 SAX 处理方式”之外,其它的 3 种处理方式都有明确的 Load 动作。验证结果表明 1M 大小的 XML 数据量基本可以定做一个分界线,如果要处理的数据量大于 1M,则应该选择基于 XMLTextReader 的 SAX 处理方式来处理数据。

 

          但是,通过验证也发现,虽然 XmlTextReader 省略了 Dom 树解析过程,但也正因为它没有树型关系,因而造成了用  XmlTextReader 遍历 XML 的性能不如用 XmlDocument 的性能好。 因此,如果业务属于可以一次构造 Dom 树并缓存,留作后面多次使用的话(如查询场景),还是推荐使用生成 Dom 树的处理方式,第二种“基于 XML Dom 的准 SAX 处理方式”,虽然首次加载会吃力。

 

          对于 5M 以下数据量的 XML 处理,这里验证发现最好的选择就是 Linq to XML 了 ,呵呵,延迟加载的设计让 Linq 构造很快,而且在真正解析、查询、过滤时性能表现也满意。

 

          关于大 XML 数据的并行处理。 实际上,对于基于 XMLTextReader 的 SAX 处理方式来讲,如果输入的 XML 数据源是流形式的,则 XML 加载可以与 SAX 解析并行,而且往往也的确是可以设计成这样的,因为很难想象一个 30、40M 的 XML 数据先全都加载进内存,然后再开始 XmlTextReader 的 while(reader.MoveNext) 过程,上面也说了。在我所涉及的这个应用中,这个很大的 XML 数据是通过 HTTP GET 请求从外围系统中下载过来的,这样的场景下,我们就可以使用并行的方式来处理,即边下载边解析。

 

C#代码 复制代码
  1. using(WebClient client = new WebClient())   
  2. {   
  3.     // string content = client.DownloadString(@"http://server.foo/get_xml?id=123");   
  4.     // StringReader sr = new StringReader(content);   
  5.     // XmlTextReader reader = new XmlTextReader(new MemoryStream(ASCIIEncoding.Default.GetBytes(content)));   
  6.   
  7.     WebRequest request = HttpWebRequest.Create(@"http://server.foo/get_xml?id=123");   
  8.   
  9.     XmlTextReader reader = new XmlTextReader(request.GetResponse().GetResponseStream());   
  10.   
  11.     while (xmlReader.Read())   
  12.     {   
  13.         // handle read.   
  14.     }   
  15. }  
 

          当然了,这种并行可行性和设计还要看具体的业务场景,具体分析。如果能并行必然会很好。

 

          最后想说的是,SQL Server 数据库也提供了 XQuary 的方式来处理 XML 数据,允许直接从关系型数据库中存储的 XML 数据直接返回 DataSource。不过以前试验过,性能不理想,SQL Server 内存涨幅较大,而且响应时间也不靠谱。这点还想请教哪位高人指点~~

          忘记了说,尽量始终不要使用“基于 XML Dom 的 Document 树处理方式”来处理 XML,尽量选择其它 3 种方式。尤其是在 XML 数据比较大时。

 

作者:lzy.je
出处:http://lzy.javaeye.com
本文版权归作者所有,只允许以摘要和完整全文两种形式转载,不允许对文字进行裁剪。未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

 

         

posted @ 2010-06-22 10:44 pcxpt.exe 阅读(299) 评论(1) 编辑
摘要: ASP.NET框架设计(四)-----类型(下)我们常常会问“这个对象是什么类型的?”之类的问题,但其中的“类型”又是由什么组成的呢?类型也是由一系列的成员组成的,它包含:常量、字段、方法、属性、事件等等。在我们讨论这些类型成员前我们先谈谈这些成员的可访问性。我们先来看看一些用于成员可访问性的修饰符CLR术语C#术语说明Privateprivate成...阅读全文
posted @ 2009-11-30 15:28 pcxpt.exe 阅读(437) 评论(0) 编辑
仅列出标题  下一页