通常地,大多数Web站点的设计目标都是:以最易接受的方式,为访问者提供即时的信息访问。在过去的几年中,越来越多的黑客、病毒和蠕虫带来的安全问题严 重影响了网站的可访问性,尽管Apache服务器也常常是攻击者的目标,然而微软的Internet信息服务(IIS) Web服务器才是真正意义上的众矢之的。

  高级教育机构往往无法在构建充满活力、界面友好的网站还是构建高安全性的网站之间找到平衡点。另外,它们现在必须致力于提高网站安全性以面对缩减中的技术预算 (其实许多它们的私有部门也面临着相似的局面)。

  正因为如此,我在这里将为预算而头疼的大学IT经理们提供一些技巧,以帮助他们保护他们的IIS服务器。虽然主要是面对大学里的IT专业人员 的,但是这些技巧也基本上适用于希望通过少量的财政预算来提高安全性的IIS管理人员。实际上,这里面的一些技巧对拥有强大预算的IIS管理人员也是非常 有用的。

  首先,开发一套安全策略

  保护Web服务器的第一步是确保网络管理员清楚安全策略中的每一项制度。如果公司高层没有把服务器的安全看作是必须被保护的资产,那么保护工 作是完全没有意义的。这项工作需要长期的努力。如果预算不支持或者它不是长期IT战略的一部分,那么花费大量时间保护服务器安全的管理员将得不到管理层方 面的重要支持。

  网络管理员为各方面资源建立安全性的直接结果是什么呢?一些特别喜欢冒险的用户将会被关在门外。那些用户随后会抱怨公司的管理层,管理层人员又会去质问网络管理员究竟发生了什么。那么,网络管理员没办法建立支持他们安全工作的文档,因此,冲突发生了。

  通过标注Web服务器安全级别以及可用性的安全策略,网络管理员将能够从容地在不同的操作系统上部署各种软件工具。

  IIS安全技巧

  微软的产品一向是众矢之的,因此IIS服务器特别容易成为攻击者的靶子。搞清楚了这一点后,网络管理员必须准备执行大量的安全措施。我将要为你们提供的是一个清单,服务器操作员也许会发现这是非常有用的。

  1. 保持Windows升级:

  你必须在第一时间及时地更新所有的升级,并为系统打好一切补丁。考虑将所有的更新下载到你网络上的一个专用的服务器上,并在该机器上以Web的形式将文件发布出来。通过这些工作,你可以防止你的Web服务器接受直接的Internet访问。

  2. 使用IIS防范工具:

  这个工具有许多实用的优点,然而,请慎重的使用这个工具。如果你的Web服务器和其他服务器相互作用,请首先测试一下防范工具,以确定它已经被正确的配置,保证其不会影响Web服务器与其他服务器之间的通讯。

  3. 移除缺省的Web站点:

  很多攻击者瞄准inetpub这个文件夹,并在里面放置一些偷袭工具,从而造成服务器的瘫痪。防止这种攻击最简单的方法就是在IIS里将缺省 的站点禁用。然后,因为网虫们都是通过IP地址访问你的网站的 (他们一天可能要访问成千上万个IP地址),他们的请求可能遇到麻烦。将你真实的Web站点指向一个背部分区的文件夹,且必须包含安全的NTFS权限。

  4. 如果你并不需要FTP和SMTP服务,请卸载它们:

  进入计算机的最简单途径就是通过FTP访问。FTP本身就是被设计满足简单读/写访问的,如果你执行身份认证,你会发现你的用户名和密码都是通过明文的形式在网络上传播的。SMTP是另一种允许到文件夹的写权限的服务。通过禁用这两项服务,你能避免更多的黑客攻击。

  5. 有规则地检查你的管理员组和服务:

  有一天我进入我们的教室,发现在管理员组里多了一个用户。这意味着这时某个人已经成功地进入了你的系统,他或她可能冷不丁地将炸弹扔到你的系 统里,这将会突然摧毁你的整个系统,或者占用大量的带宽以便黑客使用。黑客同样趋向于留下一个帮助服务,一旦这发生了,采取任何措施可能都太晚了,你只能 重新格式化你的磁盘,从备份服务器恢复你每天备份的文件。因此,检查IIS服务器上的服务列表并保持尽量少的服务必须成为你每天的任务。你应该记住哪个服 务应该存在,哪个服务不应该存在。Windows 2000 Resource Kit带给我们一个有用的程序,叫作tlist.exe,它能列出每种情况运行在svchost 之下的服务。运行这个程序可以寻找到一些你想要知道的隐藏服务。给你一个提示:任何含有daemon几个字的服务可能不是Windows本身包含的服务, 都不应该存在于IIS服务器上。

  6. 严格控制服务器的写访问权限:

  这听起来很容易,然而,在大学校园里,一个Web服务器实际上是有很多"作者"的。教职人员都希望让他们的课堂信息能被远程学生访问。职 员们则希望与其他的职员共享他们的工作信息。服务器上的文件夹可能出现极其危险的访问权限。将这些信息共享或是传播出去的一个途径是安装第2个服务器以提 供专门的共享和存储目的,然后配置你的Web服务器来指向共享服务器。这个步骤能让网络管理员将Web服务器本身的写权限仅仅限制给管理员组。

7. 设置复杂的密码:

  我最近进入到教室,从事件察看器里发现了很多可能的黑客。他或她进入了实验室的域结构足够深,以至于能够对任何用户运行密码破解工具。如果有 用户使用弱密码 (例如"password"或是 changeme"或者任何字典单词),那么黑客能快速并简单的入侵这些用户的账号。

  8. 减少/排除Web服务器上的共享:

  如果网络管理员是唯一拥有Web服务器写权限的人,就没有理由让任何共享存在。共享是对黑客最大的诱惑。此外,通过运行一个简单的循环批处理文件,黑客能够察看一个IP地址列表,利用\\命令寻找Everyone/完全控制权限的共享。

  9. 禁用TCP/IP协议中的NetBIOS:

  这是残忍的。很多用户希望通过UNC路径名访问Web服务器。随着NETBIOS被禁用,他们便不能这么做了。另一方面,随着NETBIOS 被禁用,黑客就不能看到你局域网上的资源了。这是一把双刃剑,如果网络管理员部署了这个工具,下一步便是如何教育Web用户如何在NETBIOS失效的情 况下发布信息。

  10. 使用TCP端口阻塞:

  这是另一个残忍的工具。如果你熟悉每个通过合法原因访问你服务器的TCP端口,那么你可以进入你网络接口卡的属性选项卡,选择绑定的 TCP/IP协议,阻塞所有你不需要的端口。你必须小心的使用这一工具,因为你并不希望将自己锁在Web服务器之外,特别是在当你需要远程登陆服务器的情 况下。

  11. 仔细检查*.bat和*.exe 文件: 每周搜索一次*.bat

  和*.exe文件,检查服务器上是否存在黑客最喜欢,而对你来说将是一场恶梦的可执行文件。在这些破坏性的文件中,也许有一些是*.reg文 件。如果你右击并选择编辑,你可以发现黑客已经制造并能让他们能进入你系统的注册表文件。你可以删除这些没任何意义但却会给入侵者带来便利的主键。

  12. 管理IIS目录安全:

  IIS目录安全允许你拒绝特定的IP地址、子网甚至是域名。作为选择,我选择了一个被称作WhosOn的软件,它让我能够了解哪些IP地址正 在试图访问服务器上的特定文件。WhosOn列出了一系列的异常。如果你发现一个家伙正在试图访问你的cmd.exe,你可以选择拒绝这个用户访问Web 服务器。当然,在一个繁忙的Web站点,这可能需要一个全职的员工!然而,在内部网,这真的是一个非常有用的工具。你可以对所有局域网内部用户提供资源, 也可以对特定的用户提供。

  13. 使用NTFS安全:

  缺省地,你的NTFS驱动器使用的是EVERYONE/完全控制权限,除非你手工关掉它们。关键是不要把自己锁定在外,不同的人需要不同的权 限,管理员需要完全控制,后台管理账户也需要完全控制,系统和服务各自需要一种级别的访问权限,取决于不同的文件。最重要的文件夹是System32,这 个文件夹的访问权限越小越好。在Web服务器上使用NTFS权限能帮助你保护重要的文件和应用程序。

  14.管理用户账户:

  如果你已经安装IIS,你可能产生了一个TSInternetUser账户。除非你真正需要这个账户,否则你应该禁用它。这个用户很容易被渗透,是黑客们的显著目标。为了帮助管理用户账户,确定你的本地安全策略没有问题。IUSR用户的权限也应该尽可能的小。

  15. 审计你的Web服务器:

  审计对你计算机的性能有着较大的影响,因此如果你不经常察看的话,还是不要做审计了。如果你真的能用到它,请审计系统事件并在你需要的时候加 入审计工具。如果你正在使用前面提到的WhosOn工具,审计就不那么重要了。缺省地,IIS总是纪录访问, WhosOn 会将这些纪录放置在一个非常容易易读的数据库中,你可以通过Access或是 Excel打开它。如果你经常察看异常数据库,你能在任何时候找到服务器的脆弱点。

  总结

  上述所有IIS技巧和工具(除了WhosOn以外)都是Windows自带的。不要忘记在测试你网站可达性之前一个一个的使用这些技巧和工具。如果它们一起被部署,结果可能让你损失惨重,你可能需要重启,从而遗失访问。

  最后的技巧: 登陆你的Web服务器并在命令行下运行netstat -an。观察有多少IP地址正尝试和你的端口建立连接,然后你将有一大堆的调查和研究要做了。

最近为了封BT,几乎把NBO的网络论坛找遍了,用NBAR (Network-Based Application Recognition)网络应用识别

  NBAR是一种动态能在四到七层寻找协议的技术,它不但能做到普通ACL能做到那样控制静态的TCP UDP的报,也能做到控制一般ACLs不能做到动态的端口的那些协议(如BT)之类.

  我就说说过程:

  1到http://www.cisco.com/pcgi-bin/tablebuild.pl/pdlm 下载bittorrent.pdlm,(要CCO的)

  2放到TFTP,然后用copy tftp disk2(大多数应该是flash)

  拷到路由器中,

  route7206#conf t

  Enter configuration commands, one per line. End with CNTL/Z.

  route7206(config)#ip nbar pdlm bittorrent.pdlm

  route7206(config)#

  !

  ip nbar pdlm bittorrent.pdlm

  !

  1.) 创建一个 a class-map and policy map 并且把它应用到相应的端口:

  得到关于BT的部分是

  class-map match-all bittorrent

  match protocol bittorrent

  !

  !

  policy-map bittorrent-policy

  class bittorrent

  drop

  !

  interface GigabitEthernet0/2

  description CONNECT INSIDE

  ip address 192.168.168.1 255.255.255.252 secondary

  ip address 192.168.21.1 255.255.255.0

  ip nat inside

  service-policy input bittorrent-policy

  service-policy output bittorrent-policy

  duplex full

  speed 1000

  media-type rj45

  no negotiation auto

  我实验了一下,这样的话,BT就不能下载,呵呵

  感觉目前这样的技术比较好,我正在实验去掉EMULE的方法.

  QQ:7581276 MAIL:lh@hutc.zj.cn [请转贴时保留我的EMAIL]

用过DOS的人对参数并不陌生,DOS下的很多程序都有参数,尽管是枯燥的英文字母,但功能却非常强大。Ghost是一个典型的支持参数的DOS程序,充分利用它的参数,我们可以更好地控制Ghost。让它们更好地为我们工作,前面几个例子,我们就使用了Ghost的参数做出了一张自动备份和恢复硬盘数据的自启动光盘。正是因为Ghost参数众多,功能强大,我们才有必要把一些最最常用的参数列出,供大家平时参考使用。

  小提示

  ★参数(Parameter)是程序提供给我们一些隐藏选项,通过添加参数,可以实现正常启动程序无法实现或者能够实现,但需要很多步骤才能够实现的功能,可以给我们带来很多的方便。

  ★参数与程序、参数与参数之间用空格符分隔。  

  ★我们可以把Ghost的参数写入到一些BAT文件中,并通过控制语句来用它更方便地克隆和恢复我们的系统。

  1.磁盘对磁盘拷贝

  图形界面: Disk To Disk

  参数例子: ghost -clone,mode=copy,src=1,dst=2 -sure -fx

  参数功能: 拷贝磁盘一的全部内容到磁盘二,不必询问,完成后退出Ghost。

  2.把磁盘上的所有内容备份成映像文件

  图形界面: Disk To Image

  参数例子: ghost -clone,mode=dump,src=1,dst=d:\Win98sys.gho -z3 -sure -fx

  参数功能: 备份机器第一块硬盘上的全部内容到另一台硬盘d:\Win98sys.gho文件中,高压缩,不必询问,完成后退出Ghost。

  3.从备份的映像文件复原到磁盘

  图形界面: Disk From Image

  参数例子: ghost -clone,mode=load,src=d:\Win98sys.gho,dst=1 -sure -fx

  参数功能: 从备份在另一块硬盘d:\Win98sys.gho的映像文件复原到第一块硬盘上,不必询问,完成后退出Ghost。

  4.分区对分区拷贝

  图形界面: Partition To Partition

  参数例子: ghost -clone,mode=pcopy,src=1:1,dst=2:1 -sure -fx

  参数功能: 拷贝第一块硬盘第一个分区上的所有内容到第二块硬盘的第一个分区上,不必询问,完成后退出Ghost。

  5.把分区内容备份成映像文件

  图形界面: Partition To Image

  参数例子: ghost -clone,mode=pdump,src=1:1,dst=d:\Win98sys.gho -z9 -sure -fx

  参数功能: 备份第一块硬盘第一分区到d:\Win98sys.gho,采用最高压缩率,不必询问,完成后退出Ghost。

6.从备份的映像文件克隆到分区

  图形界面: Partition From Image

  参数例子: ghost -clone,mode=pload,src=d:\Win98sys.gho:1,dst=1:1 -sure -fx

  参数功能: 把d:\Win98sys.gho中的第一个分区内存克隆到第一块硬盘第一分区上,不必询问,完成后退出Ghost。

  7.平行端口电缆线直接连接电脑客户机

  图形界面: LPT/Slave

  参数例子: ghost -lps

  参数功能: 启动客户机 (两台电脑必须同时执行Ghost)。

  8.平行端口电缆线直接连接服务机

  图形界面: LPT/Master

  参数例子: ghost -lpm -clone,mode=dump,src=1,dst=c:\Win98sys.gho -sure -fx

  参数功能: 将服务机第一块硬盘上的内容备份到客户机c:\Win98sys.gho文件中,不必询问,完成后退出Ghost。

  9.硬盘间直接克隆

  参数例子:ghost -clone,mode=copy,src=1,dst=2 -sure

  参数功能:在内部模式拷贝第一块硬盘到第二块硬盘,无需提示,直接克隆。

  10.网络备份

  参数例子:ghost -nbm -clone,mode=dump,src=2,dst=c:\xxxx.gho

  参数功能:由NetBIOS模式连接到正在进行ghost\slave的网络远程个人电脑并备份本机第二块硬盘到远程硬盘C:\xxxx.gho成一映像压缩文件。

  小提示

  该远程客户机必须使用ghost -nbs命令来启动。

  11.将映像文件克隆到硬盘

  参数例子:ghost -clone,mode=load,src=e:\savdsk.gho,dst=1

  参数功能:读入E:\SAVEDSK.gho文件,并把它克隆到第一块硬盘上。

  12.将第二个分区备份为映像文件(还原)

  参数例子:ghost -clone,mode=pdump,src=1:2,dst=g:\imgs\part2.gho

  参数功能:备份第一块硬盘的第二分区到g:\imgs\part2.gho映像文件。

  参数例子:ghost -clone,mode=pload,src=g:\imgs\part2.gho:2,dst=1:2

  参数功能:载入(恢复)映像文件内的第二分区到内部硬盘第一块硬盘的第二分区。

  13.不同硬盘不同分区复制

  参数例子:ghost -clone,mode=pcopy,src=1:2,dst=2:1

  参数功能:拷贝第一块硬盘的第二分区到第二块硬盘的第一分区。

  14.还原到第二块硬盘并调整分区大小

  参数例子:ghost -clone,mode=load,src=g:\imgs\2prtdisk.gho,dst=2,sze1=60P,sze2=40P

  参数功能:克隆g:\imgs\2prtdisk.gho映像文件到第二块硬盘, 并重整按60%和40%大小分配分区大小。

15.还原到第一块硬盘并调整分区大小

  参数例子:ghost -clone,mode=load,src=e:\imgs\3prtdisk.gho,dst=1,sze1=450M,sze2=1599M,sze3=2047M

  参数功能:克隆e:\imgs\3prtdisk.gho映像文件到第一块硬盘, 并重整分区大小为: 第一分区450MB,第二分区1599MB,第三分区2047MB。

  16.保留第一分区,其他不分配

  参数例子:ghost -clone,mode=copy,src=1,dst=2,sze1=F,sze2=V,sze3=V

  参数功能:拷贝有三个分区的第一块硬盘到第二块硬盘并保持第一分区与来源大小相同,但是其他分区所剩余空间保留不予分配。

  17.还原到最后的分区并调整分区大小

  参数例子:ghost -clone,mode=load,src=g:\imgs\2prtdisk.gho,dst=1,szeL

  参数功能:载入映像文件到磁盘最后的分区并按照容量重整其大小,第一分区则利用剩余的空间。

  18.从参数文件读取

  参数例子:GHOST.EXE @(参数文件)

  参数功能:GHOST命令行参数可从参数文件读取并执行(注意参数文件是文本格式的)。

  小提示

  参数文件中可以以文本格式编写包含任何Ghost命令行参数,除了-AFILE=和-DFILE= 参数外。

  19.备份并自动分割

  参数例子:ghost -sure -clone,mode=pdump,src=1:1,dst=system.gho -span -split=630

  参数功能:它的作用是把第一块硬盘第一分区信息备份到当前文件夹下的system.gho中,如果生成的system.gho大于630MB,则会分割生成的GHO文件,这个参数在备份大的分区,并把它们烧录到650MB的CD-R上时非常有用。

  20.备份并加密

  参数例子:ghost -sure -pwd,666888 -clone,mode=pdump,src=1:1,dst=system.gho

  参数功能:该语句的作用是把第一块硬盘第一分区信息备份到当前文件夹下的system.gho中,并且以666888作为生成后GHO文件的密码,以便加密。以后用Ghost恢复system.gho文件,或者用Ghost Explorer来释放其中的文件时,都必须输入密码,否则无法恢复或释放文件,从而起到了保密的作用。如果输入ghost -sure -pwd -clone,mode=pdump,src=1:1,dst=system.gho,即-pwd后面不带密码,则Ghost在制作GHO文件前会询问用户加密GHO的密码,你必须记牢。给GHO文件加密后,别人就无法随意查看或恢复我们的文件了。

在WAP中经常要遇到网址编码转换的问题,在ASP解决起来还是比较麻烦,但是在C#中做起来就容易多了,今天整理了一下,用ASP.NET做了一个例子,代码如下:

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace study
{
/// <summary>
/// UrlEncode_ 的摘要说明。
/// </summary>
public class UrlEncode_ : System.Web.UI.Page
{
private void Page_Load(object sender, System.EventArgs e)
{
string strName="刘德华";
string strEncodeNameGB2312=System.Web.HttpUtility.UrlEncode(strName,System.Text.Encoding.GetEncoding("GB2312")).ToUpper();
string strDecodeGB2312=System.Web.HttpUtility.UrlDecode(strEncodeNameGB2312,System.Text.Encoding.GetEncoding("GB2312"));
//如果设定为默认编码则 System.Text.Encoding.Default

Response.Write( "网址编码过的文字(GB2312):"+ strEncodeNameGB2312 +"<br>" );
Response.Write( "经过解码的文字为(GB2312):"+ strDecodeGB2312 +"<p></p>" );

string strEncodeNameUTF8=System.Web.HttpUtility.UrlEncode(strName,System.Text.Encoding.GetEncoding("utf-8")).ToUpper();
string strDecodeUTF8=System.Web.HttpUtility.UrlDecode(strEncodeNameUTF8,System.Text.Encoding.GetEncoding("utf-8"));

Response.Write( "网址编码过的文字(UTF8):"+ strEncodeNameUTF8 +"<br>" );
Response.Write( "经过解码的文字为(UTF8):"+ strDecodeUTF8 +"<br>" );
}

#region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// 设计器支持所需的方法 – 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion
}
}

备注
GetEncoding 方法依赖于基础平台支持大部分代码页。但是,对于下列情况提供系统支持:默认编码,即在执行此方法的计算机的区域设置中指定的编码;Little- Endian Unicode (UTF-16LE);Big-Endian Unicode (UTF-16BE);Windows 操作系统 (windows-1252);UTF-7;UTF-8;ASCII 以及 GB18030(简体中文)。

详见MSDN:ms-help://MS.MSDNQTR.2003FEB.2052/cpref/html/frlrfsystemtextencodingclassgetencodingtopic2.htm

1.不要为了寂寞去恋爱,时间是个魔鬼,天长日久,如果你是个多情的人,即使不爱对方,到时候也会产生感情,到最后你怎么办?

2.不要为了负责而去结婚。要知道,不爱对方却和对方结婚是最不负责的。即使当时让对方很伤心,但是总比让他几年甚至一辈子伤心强。

3.不管多大多老,不管家人朋友怎么催,都不要随便对待婚姻,婚姻不是打牌,重新洗牌要付出巨大代价。

4.感情的事基本上没有谁对谁错,他(她)要离开你,总是你有什么地方不能令他满足,回头想想过去在一起的日子,总是美好的。当然,卑劣的感情骗子也有,他们的花言巧语完全是为了骗取对方和自己上床,这样的人还是极少数。

5.和一个生活习惯有很多差异的人恋爱不要紧,结婚要慎重,想想你是否可以长久忍受彼此的不同。

6.有人说恋爱要找自己喜欢的人,结婚要找喜欢自己的人,都是片面的。恋人不喜欢自己有什么可恋的?老婆自己不喜欢怎么过一辈子?

7.真爱一个人,就要尽量让他,他说了你就会,那么双方就有激情了。

8.在要求对方必须是处女的时候,想想自己是不是处男,如果是,你可以,如果不是,你凭什么?

9.不要随便和别人上床,否则将来遇到一个真爱但他洁身自好有原则的男人,你会后悔当年的所做所为。

10.不要因为自己长相不如对方而放弃追求的打算,长相只是一时的印象,真正决定能否结合主要取决于双方的性格。我见过的帅哥配丑女,丑女配帅哥的太多了。
11.女人要学会扮靓自己,不要拿朴素来做挡箭牌,不要拿家务做借口,不懂时尚,你就不是一个完整的女人。

12.恋爱的时间能长尽量长。这最少有两点好处:一,充分,尽可能长的享受恋爱的愉悦,婚姻和恋爱的感觉是很不同的。二,两人相处时间越长,越能检验彼此是否真心,越能看出两人性格是否合得来。这样婚后的感情就会牢固得多。

13.男人不坏,女人不爱,这坏不是指心肠狠毒,自私无情什么的。而是指油嘴滑舌,花言巧语。一般的好男人以为说情话是油嘴滑舌,轻浮肉麻的表现,所以不愿去做。对别人这样说是不对,可是对自己老婆,就要油嘴滑舌一点。为什么不能做个心好嘴滑的男人呢?

14.离婚率高至少反映了好坏不同的两点:好的一点是人们的观念已经趋向人性化,不再为封建思想而禁锢自己,坏的一点是对于婚姻的轻率。没想好结什么婚?

15.都说婚姻是爱情的坟墓,那是因为婚前已经往去坟墓的路上走着。就算不结婚也会在坟墓前分手。为什么不先分手就一头钻进坟墓呢?

16.只会读书的女人是一本字典,再好人们也只会在需要的时候去翻看一下,只会扮靓的女人只是一具花瓶,看久了也就那样。服饰美容是做好一个女人的必要条件,不是充要条件。你还需要多看书。这样你会发现生活更加美好。

17.平平淡淡才是真,没错,可那应该是激情过后的平淡,然后再起激情,再有平淡。激情平淡应呈波浪形交替出现。光有平淡无激情的生活有什么意思?只要你真心爱他,到死你也会有激情的。

18.你爱他吗?爱就告诉他,何必把思念之苦藏在心底深处。怕样子,地位,身份不相配?别怕,爱一个人是美好的。

19.老婆和老妈掉进了河里,我先救老妈,因为是老妈给了我生命,我找不到任何理由丢下她不管。老婆如果没救上来,我可以再给她陪葬,在墓里继续我们的爱情。

20.草率地结了婚已经是错了,再也不要草率地去离婚。先试试看,真的不行 再离也不迟。

22.魅力是什么?魅力不是漂亮,漂亮的女人不一定能吸引我,端庄幽雅的女人我才喜欢。所以你不用担心自己不够漂亮。

23.初恋都让人难忘,觉得美好。为什么?不是因为他(她)很漂亮或很帅,也不是因为得不到的就是好的,而是因为人初涉爱河时心里异常纯真,绝无私心杂 念,只知道倾己所有去爱对方。而以后的爱情都没有这么纯洁无瑕了。纯真是人世间最为可贵的东西。我们渴求的就是她。

24.初恋的人大多都不懂爱,所以初恋失败的多。成功的少。结婚应该找个未婚的,因为谁都喜欢原装。而恋爱,还是找个恋爱过的人才好。因为经历过恋爱的人才知道什么是爱,怎么去爱。

25.男人有钱就变坏,是的,很多男人这样,不过,一有钱就变坏的男人就算没钱,也好不到哪里去。

26.一个男人能不能给你安全感,完全不取决于他的身高,而取决于他的心高。高大而窝囊的男人我见过不少。矮小而昂扬的男人我也见过。一个男人要心高气傲,这样才像男人。当然,前提是要有才华。

27.天长地久有没有?当然有!为什么大多数人不相信有?因为他们没有找到人生旅途中最适合自己的那一个。也就是冥冥中注定的那一个。为什么找不到?茫茫 人海,人生如露,要找到最合适自己的那一个谈何容易?你或许可以在40岁时找到上天注定的那一个,可是你能等到40岁吗?在20多岁时找不到,却不得不结 婚,在三四十岁时找到却不得不放弃。这就是人生的悲哀。

28.为什么生活中很少见到传说中天长地久,可歌可泣的爱情故事?因为这样的感情非常可贵,可贵的东西是那么好见到的吗?金子钻石容易见到吗?

29.恋爱时感性点,过日子理性点,穿衣服性感点。

30.性感是什么?坦胸露乳么?那路边没穿衣服的女丐性感不?性感不是仅仅指衣服穿得少,而是该种性别焕发出来的与另一种性别迥然不同的特质。一个衣着讲究,端庄优雅的女人我一样觉得很性感。

31.一般的男人穿西服喜欢衬衣上系条领带,束得紧紧的,我却喜欢不系领带,敞开最上的扣子,我觉得这样更性感。

32.从前失恋之时,我都会恨她,恨她为什么这么薄情寡义,听到有关她的不好的消息,我都会偷着乐,现在不了,现在即使失去她,我也会祝福她,衷心希望她能过得很好。她过得不好我会很难过。这也是喜欢和爱的一个区别。

33.和聪明的人恋爱会很快乐,因为他们幽默,会说话,但也时时存在着危机,因为这样的人很容易变心。和老实的人恋爱会很放心,但生活却也非常得乏味。

34.女人不要太好强,有的女人自尊心过强。是别人的错她态度很强硬,是自己的错她同样态度很强硬。她总以为去求别人是下贱的表现,她是永远不会求男人 的。这样的女人很令人头疼。聪明的女人会知道什么时候该坚强,什么时候该示弱。好强应该对外人,对爱的人这么好强你还要不要他呵护你啊?

35.男人大多爱嫖妓,**的愉悦当然是一原因,还有一个更大的原因就是,和妓女相处会感觉非常的愉快,想说什么话就说什么话,想干什么就干什么,而且妓女会撒娇,这让男人感觉自己更像男人,那么,女人为什么不能在床上扮演一个妓女呢?

36.要看一个人有没有内涵,内看谈吐,外看着装。还可以看写字。谈吐可以看出一个人的学识和修养。着装可以看出一个人的品位,写字可以看出一个人的性格。

37.想知道一个人爱不爱你,就看他和你在一起有没有活力,开不,有就是爱,没有就是不爱。

38.有的人老是抱怨找不好人,一两次不要紧,多了就有问题了,首先你要检讨自己本身有没有问题,如果没有,那你就要审视一下自己的眼光了,为什么每次坏人总被你碰到?

39.有人说男人一旦变心,九头牛也拉不回,难道女人变心,九头牛就拉得回来吗?男女之间只在生理上有差异,心理方面大同小异。

40.爱情与人品没多大关系,从前有个女同事跟我说她喜欢射雕里的杨康,不喜欢郭靖,我很惊奇,爱坏厌好?后来想想,也没什么,杨康认贼作父,卖国求荣是不对。可他对爱情却很执着,这样的人为什么不能享有爱?现实生活也有这样的例子,古惑仔也有古惑仔的爱情。

41.有人说没有面包的爱情终究会夭折。我说说这话的人不懂什么是爱情。从前恋爱我很反感别人说女方这条件好那条件好。我不管你什么出身,什么学历,什么 地位,如果我爱你,你擦皮鞋甚至做妓女我也无所谓。大人说我幼稚,没有钱怎么过日子?我说有钱没爱过的是什么日子?和自己爱的人在一起,喝水吃腌菜我也是 高兴的。

42.如果真爱一个人,就会心甘情愿为他而改变。如果一个人在你面前我行我素,置你不喜欢的行为而不顾,那么他就是不爱你。所以如果你不够关心他或是他不 够关心你,那么你就不爱他或他不爱你,而不要以为是自己本来就很粗心或相信他是一个粗心的人。遇见自己真爱的人,懦夫也会变勇敢,同理,粗心鬼也会变得细 心。

43.彼此都有意而不说出来是爱情的最高境界。因为这个时候两人都在尽情的享受媚眼,尽情的享受目光相对时的火热心理,尽情的享受手指相碰时的惊心动魄。 一旦说出来,味道会淡许多,因为两人同意以后,所有的行为都是已被许可,已有心理准备的了,到最后渐渐会变得麻木。

44.一个萝卜一个坑,说的是婚姻情况。事实上对于爱情来说,是不成立的,优秀的人,不管男女,都会是一个萝卜好几个坑。所以这个世界天天上演着悲欢离合的故事。

45.性和爱是可以分开的。性其实只是人的一种很正常的生理欲望。就和吃饭喝水一样,饿了就要吃饭,渴了就要喝水。饭我们既可以自己弄着吃,吃完洗碗洗锅 放好,也可以去馆子吃,吃完嘴一抹,拍屁股走人。剩下的可以不要。所以对于性,很多人在需求时也会去外面“吃”。吃完付钱走人,不需要把对方带走。但自己 做的和外面买的味道是有点不同的,到底谁好谁坏,就看各人的口味了。

46.有两种女人很可爱,一种是妈妈型的,很体贴人,很会照顾人,会把男人照顾的非常周到。和这样的女人在一起,会感觉到强烈的被爱。还有一种是妹妹型 的。很胆小,很害羞,非常的依赖男人,和这样的女人在一起,会激发自己男人的个性的显现。比如打老鼠扛重物什么的。会常常想到去保护自己的小女人。还有一 种女人既不知道关心体贴人,又从不向男人低头示弱,这样的女人最让男人无可奈何。

47.有外遇并非坏男人的专利,好男人一样有,所以当你遇到这样的男人时,不要一棍子打死,可以试着给一次机会,能改还是可以在一起的。几十年的感情不容易,对于男人的偶尔出轨,有时候不必看得过重。

48.吝啬是男人的大忌,就算穷也不要做出一副穷样。有人抱怨女人只爱男人的钱,其实也并不一定就是这样,有的女人喜欢男人为她花钱,有时候也是为了证实自己在男人心目中的位置,男人如果喜欢一个女人,一定愿意为她花钱的。

49.男女搭配,干活不累。因为在异性面前,男人总喜欢表现自己很男人的一面。这样也才像个男人,所以大男子主义有时候是必须有的。

50.追求爱慕的异性是很常见的说法。其实对方不喜欢你,你再怎么追也没用,对方喜欢你,根本不需要挖空心思去追。或许真有一天他被你的诚意所打动,可最 终大多还是会分手的。因为爱情不是感动,你不是他心目中的理想伴侣,即使一时接受你,将来碰上他心仪的那一位,一样会离开你。当然,对于喜欢你的人,你还 是需要花点心思去讨好他的,因为这样才像拍拖,才浪漫。

51.经常有人问在朋友和恋人之间叫你选择,你会选择哪一个?其实我觉得这个问题是多余的。真正懂你的朋友或恋人,他们会体谅你的行为,如果不体谅你,因此失去也不必太在意。朋友或恋人是要互相帮助的,而不是硬性迁就的。

52.都说一个成功的男人背后,常常有一个默默无闻的支持他的女人,那一个失败的男人的背后,是不是也常常有一个明明有闻的瞎捣乱的女人呢?

53.曾经沧海难为水,除却巫山不是云。可是如果我还没经沧海或是刚到沧海打了个转就回来,而且也没到过巫山就一头钻进了围城怎么办啊

54.浪漫是什么?是送花?雨中漫步?楼前伫立不去?如果两人彼此倾心相爱,什么事都不做,静静相对都会感觉是浪漫的。否则,即使两人坐到月亮上拍拖,也是感觉不到浪漫的。

55.是否门当户对不要紧,最重要应该是兴当趣对,不然没有共同语言,即使在一起,仍然会感觉到孤独。

56.学会用理解的,欣赏的眼光去看对方,而不是以自以为是的关心去管对方。

57.幼稚的人和幼稚的人在一起没什么问题,成熟的人和成熟的人在一起也没什么问题,成熟的人和幼稚的人在一起问题就多了。

58.有的女人恋爱时让男友宠着自己,结婚后仍然要老公百般宠着自己,却忘记做为一个女人应该做的份内之事。这样的女人是不懂得爱情的。

59.持久的爱情源于彼此发自内心的真爱,建立在平等的基础之上。任何只顾疯狂爱人而不顾自己有否被爱,或是只顾享受被爱而不知真心爱人的人都不会有好的结局。

测试工具:WAP模拟器(如Opera,M3GATE,等),支持WAP的手机。

一直以来都有朋友在WAP的中文变量传递上面遇到问题,这里给出简单的WAP留言本的制作过程,也解决了WAP的中文传递问题。

WAP网站也和传统网站类似,同样是PC电脑来进行后台的管理。只是不同的是一个是用手机浏览,一个是用电脑浏览。前台显示页面用手机浏览,后台管理页面用IE浏览器进行查看,管理就可以了。

如果你已经能写简单的留言本程序,那么制作WAP留言本已经很简单的事情了,只是把HTML换成WML这么简单,至于WML的语法,看看教程就会了,比HTML还简单,具体教程google一下。

一些WAP教程。

http://www.itsalon.net/wap/
http://www.wapease.com/class/tip2/
http://tech.sina.com.cn/wap/school/index.shtml

其他就自己找找吧。

留言本的程序包括:发贴,保存,显示,编辑,回复,删除。

整个的后台管理+前台显示,也就这几个功能。

注意:以下代码,如果你是使用EditPlus编写的,请在保存的时候选择,另存为“UTF-8”编码。如果不这么做,你就会遇到WML中传递中文变量,出现乱码的问题了。

以ASP为例。那我们就先从发贴页面做起,add.asp

指定ASP页面所用的脚本和编码,CODEPAGE="65001"这个一定不能少,是表示UTF-8编码,GB2312是CODEPAGE="936"。

<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>

先声名WML的头文件信息,这样即使你用的是虚拟的空间,也不用在IIS或者是Apache里面映射MIME文件类型。

<% Response.ContentType="text/vnd.wap.wml;charset=UTF-8" %>

声名WML的头文件信息,这个是规定,规定了WAP的版本和采用的标准,如果不明白就这么写就行了,不变的,但是必须要加上。 其中encoding也是指定编码。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">

接下来就是页面的显示代码了

<card id="add" title="经典WAP留言本">
<p>
昵称:<br/>
<input name="Name" emptyok="false" size="10" maxlength="10"/><br/>
标题:<br/>
<input name="Title" emptyok="false" maxlength="40"/><br/>
内容:<br/>
<input name="Content" format="false" maxlength="150"/><br/>
</p>
</card>

简单介绍一下:wml类似html标签,card代表一个卡片,这里简单理解为一个页面就行了,注意:所有的显示的内容都要放在<p> </p>标签里面,一定要注意这点,要不然就会出错。

< meta http-equiv="Cache-Control" content="max-age=0"/>
< meta http-equiv="Cache-Control" content="no-cache"/>

在meta中指定不缓存页面。

< input name="Title" emptyok="false" maxlength="40"/>< br/>
emptyok不允许为空,maxlength允许输入的文字最大长度。

WML的表单提交有点不同,<postfile name="title" value="($title:n)" />是把input表单的值附给title变量,name="title" 是变量名, value="($title:n)"是变量,即input中输入的信息,content也是一样。

注:这里($title:n)是WML变量的写法,以$符号开头,类似PHP的变量声名,WML中表单提交有:n,:e,:u,和空,四种状态, 其中:n是强制不进行URL转义;:e是转义;:u是反转义;如果为空,在有的手机上默认是不转义,有的是转义, 规范不统一,安全期间,如果不转义,还是写上:n为好。

WAP的变量提交也分两种情况,GET和POST,使用GET方法,对中文的支持并不是很好,所以有使用到表单提交的地方,都改为POST方式提交,代码格式为:

<anchor>POST方式提交
<go href="save.asp" _fcksavedurl=""save.asp"" method="post">
<postfield name="Name" value="$(Name:n)" />
<postfield name="Title" value="$(Title:n)" />
<postfield name="Content" value="$(Content:n)" />
<postfield name="Method" value="POST" />
</go>
</anchor>

当然对于英文和数字,简单的,使用GET方式提交会比较方便一些,代码格式为:

< a href="save.asp?Name=$(Name:n)&Title=$(Title:n)&Content=$(Content:n)&Method=GET">GET方式提交< /a>

注:连接不同变量字符的&符号要写为&

发表留言页面add.asp的代码如下:
<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<% Response.ContentType="text/vnd.wap.wml;charset=UTF-8" %>
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<head>
<meta http-equiv="Cache-Control" content="max-age=0"/>
<meta http-equiv="Cache-Control" content="no-cache"/>
</head>
<card id="add" title="经典WAP留言本">
<p>
昵称:<br/>
<input name="Name" emptyok="false" size="10" maxlength="10"/><br/>
标题:<br/>
<input name="Title" emptyok="false" maxlength="40"/><br/>
内容:<br/>
<input name="Content" format="false" maxlength="150"/><br/>
<br/><anchor>POST方式提交
<go href="save.asp" method="post">
<postfield name="Name" value="$(Name:n)" />
<postfield name="Title" value="$(Title:n)" />
<postfield name="Content" value="$(Content:n)" />
<postfield name="Method" value="POST" />
</go>
</anchor>
<br/><a href="save.asp?Name=$(Name:n)&Title=$(Title:n)&Content=$(Content: n)&Method=GET">GET方式提交</a><br/><br/>
<a href="index.asp">返回留言列表</a>
</p>
<p>
有任何疑问,请访问:http://www.designer5.net或<br/>
蓝色理想论坛WAP版:http://www.blueidea.com/bbs<br/>
广告:蓝色理想WAP网站改版了,使用手机访问<a href="http://wap.blueidea.com">http://wap.blueidea.com</a><br/>
如果您参考了此程序,有WAP站点,请做上http://wap.blueidea.com的链接。
</p>
<do type="prev" label="返回"><prev/></do>
</card>
</wml>

接下来是保存数据。

保存页面save.asp,代码如下:

<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<!–#include file="conn.asp"–>
<%
Function inWML(str)
‘ 把字符串存入数据库,单引号过滤,‘==Chr(39)
sTemp = Replace(str, Chr(39), "‘") ‘单引号过滤
inWML = sTemp
End Function
IF Request("Method")<>"" Then
Name=inWML(Trim(Request("Name")))
Title=inWML(Trim(Request("Title")))
Content=inWML(Trim(Request("Content")))
Method=Request("Method")

Sql = "INSERT INTO guestbook(Name, Title, Content, Method) values(‘"&Name&"‘, ‘"&Title&"‘, ‘"&Content&"‘, ‘"&Method&"‘)"
Conn.Execute Sql
End IF
Response.Redirect ("index.asp")
%>

最后是显示把留言的内容显示出来。

显示数据的时候需要注意字符的替换,因为有些字符是不能直接显示的,需要转换为Ascii码,在WML里面“$”符号是表示变量,如果要显示“$”,需要写为“$$”,例:“一共有$$315元RMB”,显示为“一共有$315元RMB”。

必须要替换的字符,已经写为函数,方便大家使用。

Function outHTM(str)
‘ 把字符串进行HTM解码,输出字符串
Dim sTemp
sTemp = str
outHTM = ""
If IsNull(sTemp) Then
Exit Function
End If
sTemp = Replace(sTemp, "‘", "‘") ‘还原单引号
sTemp = Replace(sTemp, "&", "&")
sTemp = Replace(sTemp, "<", "<")
sTemp = Replace(sTemp, ">", ">")
sTemp = Replace(sTemp, "$", "$$")
sTemp = Replace(sTemp, "", " ")
sTemp = Replace(sTemp, Chr(10), "<br/>")
outHTM = sTemp
End Function

显示留言的页面index.asp,代码如下:

<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<!–#include file="conn.asp"–>
<%
Function outHTM(str)
‘ 把字符串进行HTM解码,输出字符串
Dim sTemp
sTemp = str
outHTM = ""
If IsNull(sTemp) Then
Exit Function
End If
sTemp = Replace(sTemp, "‘", "‘") ‘还原单引号
sTemp = Replace(sTemp, "&", "&")
sTemp = Replace(sTemp, "<", "<")
sTemp = Replace(sTemp, ">", ">")
sTemp = Replace(sTemp, "$", "$$")
sTemp = Replace(sTemp, "", " ")
sTemp = Replace(sTemp, Chr(10), "<br/>")
outHTM = sTemp End Function

Sql = "SELECT * FROM guestbook ORDER BY ID DESC "
Set Rs = Server.CreateObject("Adodb.Recordset")
Rs.Open Sql,conn,1,3
page = Request.QueryString("Page")
Rs.PageSize = 6 ‘一页6条记录

IF Not IsEmpty(Page) Then
IF Not IsNumeric(Page) Then ‘判断Page是否为数字
Page=1
Else
Page=Cint(Page) ‘转换成短整形Integer
End IF
IF Page > Rs.PageCount Then
Rs.AbsolutePage = Rs.PageCount ‘设置当前显示页等于最后一页
ElseIF Page <= 0 Then
Rs.AbsolutePage = 1 ‘设置当前页等于第一页
Else
Rs.AbsolutePage = Page ‘如果大于零,显示当前页等于接收的页数
End IF
Else
Rs.AbsolutePage = 1
End IF
Page = Rs.AbsolutePage
%>
<% Response.ContentType="text/vnd.wap.wml;charset=UTF-8" %>
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<head>
<meta http-equiv="Cache-Control" content="max-age=0"/>
<meta http-equiv="Cache-Control" content="no-cache"/>
</head>
<card id="add" title="经典WAP留言本">
<p>
<a href="add.asp">发表新贴</a><br/> _fcksavedurl=""add.asp">发表新贴</a><br/>"
<%
For i=1 to Rs.PageSize
If Rs.Eof Then
Response.Write "没有留言了!<br/>"
Exit For
End If
%>
(<%=Rs("ID")%>) <%=outHTM(Rs("Title"))%><br/>
内容:<%=outHTM(Rs("Content"))%><br/>
留言者:<%=outHTM(Rs("Name"))%><br/>
时间:<%=outHTM(Rs("CreatTime"))%><br/>
回复:<%
if Rs("Reply")<>""then
Response.Write outHTM(Rs("Reply"))
else
Response.Write "“暂无回复”"
end if
%><br/>
------<br/>
<%
Rs.MoveNext
Next
if page>=Rs.PageCount then
‘Response.Write ("[下一页]")
else
Response.Write("[<a href=‘index.asp?Page=" & (Page+1) & "‘>下一页</a>]")
end if
if page<=1 then
‘Response.Write ("[上一页] ")
else
Response.Write("[<a href=‘index.asp?Page=" & (Page-1) & "‘>上一页</a>]")
end if
%>
<br/><a href="add.asp">发表新贴</a>
</p>
<p>
有任何疑问,请访问:http://www.designer5.net 或<br/>
蓝色理想论坛WAP版:http://www.blueidea.com/bbs<br/>
广告:蓝色理想WAP网站改版了,<a href="http://wap.blueidea.com">http://wap.blueidea.com</a><br/>
如果您有WAP站点,并参考了此程序,请做上http://wap.blueidea.com的连接
</p>
</card>
</wml>

后台管理页面admin.asp,代码如下:

<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<!–#include file="conn.asp"–>
<%
Function inWML(str)
‘ 把字符串存入数据库,单引号过滤
sTemp = Replace(str, Chr(39), "‘") ‘单引号过滤
inWML = sTemp
End Function
IF (Request.Form("Flag")="ReplySave") Then
Id = Request.Form("Id")
Name = inWml(Request.Form("Name"))
Title = inWml(Request.Form("Title"))
Content = inWml(Request.Form("Content"))
Reply = inWml(Request.Form("Reply"))
‘可修改用户留言,是为了避免用户输入非法信息
Sql = "UPDATE GuestBook SET Name = ‘"&Name&"‘, "
Sql = Sql + "Title = ‘"&Title&"‘, "
Sql = Sql + "Content = ‘"&Content&"‘, "
Sql = Sql + "Reply = ‘"&Reply&"‘ "
Sql = Sql + " WHERE Id = "&Id
Conn.ExeCute Sql
Conn.Close
Set Conn = Nothing
Response.Redirect("admin.asp")
End IF

IF (Request.QueryString("Action")="Del") Then
Sql = "DELETE FROM GuestBook WHERE Id=" & Request.QueryString("Id")
Conn.Execute Sql
Conn.Close
Set Conn = Nothing
Response.Redirect("admin.asp")
End IF
%>
<%
Set Rs=Server.CreateObject("adodb.Recordset")
Sql = "SELECT * FROM GuestBook ORDER BY Id Desc"
Rs.open Sql,conn,3,3
Page = Request.QueryString("Page")
Rs.PageSize = 10 ‘一页6条记录
IF Not IsEmpty(Page) Then
IF Not IsNumeric(Page) Then ‘判断Page是否为数字
Page=1
Else
Page=Cint(Page) ‘转换成短整形Integer
End IF
IF Page > Rs.PageCount Then
Rs.AbsolutePage = Rs.PageCount ‘设置当前显示页等于最后一页
ElseIF Page <= 0 Then
Rs.AbsolutePage = 1 ‘设置当前页等于第一页
Else
Rs.AbsolutePage = Page ‘如果大于零,显示当前页等于接收的页数
End IF
Else
Rs.AbsolutePage = 1
End IF
Page = Rs.AbsolutePage
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>经典WAP留言本</title>
<style type="text/css">
body, td{font-size:12px;}
p{line-height:22px;}
</style>
<script language="javascript" type="text/javascript" charset="utf-8">
<!–
function check_form1()
{
if (document.form1.Reply.value==""){
alert("请填写回复内容!");
document.form1.Reply.focus();
}
else{return true;}
return false;
}
–>
</script>
</head>
<body>
<table width="600" border="0" align="center" cellpadding="1" cellspacing="1" bgcolor="#2D96FF">
<tr align="center" bgcolor="#D0E8FF">
<td height="70" colspan="8"><p><strong>经典WAP留言本</strong></p>
<p><strong>制作:</strong><strong><a href="http://www.designer5.net" _fcksavedurl=""http://www.designer5.net"" target="_blank">D5S工作室</a> 作者:yytcpt</strong></p>
</td>
</tr>
<tr align="center" bgcolor="#9BCDFF">
<td height="25"><strong>ID</strong></td>
<td><strong>留言者</strong></td>
<td><strong>标题</strong></td>
<td><strong>留言内容</strong></td>
<td><strong>提交方式</strong></td>
<td><strong>留言时间</strong></td>
<td width="34"><strong>回复</strong></td>
<td><strong>删除</strong></td>
</tr>
<%
For i=1 to Rs.PageSize
If Rs.Eof Then
Exit For
End If
%>
<tr bgcolor="#C8E3FF" onMouseOver="javascript:this.bgColor=‘#9BCDFF‘;" onMouseOut="javascript:this.bgColor=‘#C8E3FF‘;">
<td width="19" height="25" align="center"><%=Rs("Id")%></td>
<td width="48" align="center"><%=Rs("Name")%></td>
<td width="53" align="center"><%=Rs("Title")%></td>
<td width="247" align="left"><%=Rs("Content")%> </td>
<td width="53" align="center"><%=Rs("Method")%></td>
<td width="76" align="center"><%=Rs("CreatTime")%></td>
<td align="center"><a href="admin.asp?Action=Reply&Id=<%=Rs("Id")%>">回复</a></td>
<td width="45" align="center"><a href="javascript:if(confirm(‘确实要删除吗?‘))location=‘admin.asp?Action= Del&Id=<%=Rs("Id")%>‘">删除</a></td>
</tr>
<%
Rs.MoveNext
Next
%>
<tr align="center" bgcolor="#9BCDFF">
<td height="25" colspan="8">
<%
Response.Write("<form name=page method=get onsubmit=""document.location = ‘admin.asp?Page=‘+this.page.value;return false;"">")
if page<=1 then
Response.Write ("[首页] [上一页] ")
else
Response.Write("[<a href=admin.asp?Page=1>首页</a>] ")
Response.Write("[<a href=admin.asp?Page=" & (Page-1) & ">上一页</a>] ")
end if

if page>=Rs.PageCount then
Response.Write ("[下一页] [尾页]")
else
Response.Write("[<a href=admin.asp?Page=" & (Page+1) & ">下一页</a>] ")
Response.Write("[<a href=admin.asp?Page=" & Rs.PageCount & ">尾页</a>]")
end if
Response.Write("[页次:<font color=red>" & page & "</font>/" & Rs.PageCount)
Response.Write("] [共" & Rs.RecordCount & "条 <font color=red>"& Rs.PageSize & "</font>条/页]")
Response.Write(" 转到" & "<input name=page size=4 value=" & page & ">" & "页<input type=submit value=go></form>")
%>
</td>
</tr>
<tr align="center">
<td height="30" colspan="8" bgcolor="#C8E3FF"><p> 有任何疑问,请访问<a href="http://www.designer5.net"> <strong>http://www.designer5.net</strong></a> 或<strong><a href="http://www.blueidea.com/bbs" _fcksavedurl=""http://www.blueidea.com/bbs"" target="_blank"> </a></strong><a href="http://www.blueidea.com/bbs" target="_blank"><strong> </strong></a><strong><a href="http://www.blueidea.com/bbs" target="_blank">蓝色理想论坛WAP版块</a></strong><br/>
<strong>广告:</strong>蓝色理想WAP网站改版了,请使用手机访问<a href="http://wap.blueidea.com"><strong>http://wap.blueidea.com</strong></a><br/>
如果您有WAP站点,并参考了此程序,请做上http://wap.blueidea.com的连接</p></td>
</tr>
</table>
<p> </p>
<%
IF (Request.QueryString("Action")="Reply") Then
Set Rs=Server.CreateObject("adodb.Recordset")
Sql = "SELECT * FROM GuestBook WHERE Id ="&Request.QueryString("Id")
Rs.open Sql,conn,3,3
%>
<table width="333" border="0" align="center" cellpadding="0" cellspacing="0" bgcolor="#C8E3FF">
<form name="form1" method="post" action="admin.asp" onsubmit="javascript:return check_form1()">
<tr>
<td width="69"><strong>ID</strong></td>
<td width="264"><%=Rs("Id")%></td>
</tr>
<tr>
<td><strong>留言者</strong></td>
<td>
<input name="Name" type="text" value="<%=Rs("Name")%>" size="20">
</td>
</tr>
<tr>
<td><strong>标题</strong></td>
<td><input name="Title" type="text" value="<%=Rs("Title")%>" size="20"></td>
</tr>
<tr>
<td><strong>留言时间</strong></td>
<td><%=Rs("CreatTime")%></td>
</tr>
<tr>
<td><strong>留言内容</strong></td>
<td><textarea name="Content" cols="30" rows="4"><%=Rs("Content")%></textarea></td>
</tr>
<tr>
<td><strong>本站回复</strong></td>
<td><textarea name="Reply" cols="30" rows="4"><%=Rs("Reply")%></textarea></td>
</tr>
<tr align="center">
<td colspan="2"><input type="submit" name="Submit" value="提交">

<input type="reset" name="Submit" value="重置">
<input name="Id" type="hidden" value="<%=Rs("Id")%>">
<input name="Flag" type="hidden" value="ReplySave">
</td>
</tr>
</form>
</table>
<% End IF %>
</body>
</html>
<%
Rs.Close
Set Rs = Nothing
%>

连接数据库conn.asp,代码如下:

<%
Dim Conn, StrSQL
StrSQL = "provider=microsoft.jet.oledb.4.0;" & "data source = " & server.mappath("d5s.mdb")
set Conn = Server.Createobject("Adodb.Connection")
Conn.open StrSQL
%>

源码下载地址:点击下载

引言

如果你不是只在大集团公司工作过的话,你一定会有机会接触到MySQL,虽然它并不支持事务处理,存储过程,但是它提供的功能一定能满足你的大部分需求,另外,简洁的MySQL也有一些它独到的优势,在有些时候,它的速度甚至超过大型数据库。

那么如何在.NET中访问MySQL数据库呢?也许很多人马上会说:用OLEDB嘛,但是事实上采用.NET OleDb Data Provider并不能访问MySQL,如果你使用的话,系统会提示你:"Net Data OLE DB 提供程序 (System.Data.Odbc) 不支持 MSDASQL 提供程序(用于 Odbc 驱动程序的 Microsoft OLE DB 提供程序)。",是什么原因我并不知道,按照MySQLDriverCS的作者的说法就是它被"abandoned by the owner",呵呵,兴许还有些故事。

幸好,我们还有其它的选择,这里就要介绍两种访问MySQL数据库的办法。

使用ODBC.NET

ODBC.NET(全称ODBC .NET Data Provider)是一个免费的.NET Framework附加组件,需要到微软公司的网站上去下载,下载地址为:http://download.microsoft.com/download/dasdk/Install/1.0.4030.0/W98NT42KMeXP/EN-US/odbc_net.msi,它需要系统已经安装MDAC 2.7或者更高版本。另外,还需要安装MySQL的ODBC驱动程序,下载地址为:http://www.mysql.com/downloads/api-myodbc-2.50.html,还需要在"ODBC数据源管理器"中配置一下DSN,如下图所示:

看原大图

在对象的设计上,ODBC.NET也跟OLEDB,SQL等一样,分别为OdbcConnection, OdbcCommand, OdbcDataAdapter, OdbcDataReader,用法也完全一样,如果你希望用ODBC .NET来代替以前的OleDb .NET Data Provider,事实上完全可以通过查找替换的办法来修改你的程序。

以下是一段代码示例:

try
{
string constr = "DSN=MySQL;" + "UID=;" +"PWD="; ;
conn = new OdbcConnection(constr);
conn.Open();
string query = "insert into test.dbtable values10,‘disksidkfsdi‘, ‘asdfaf‘, ‘adsfasdf‘)";
string tmp = null;
OdbcCommand cmd = new OdbcCommand(query, conn);
for(int i = 0; i < 100000; i++)
{
cmd.ExecuteNonQuery();
}
cmd.Dispose();
conn.Close();
query = "select * from test.dbtable";
OdbcCommand cmd2 = newOdbcCommand(query, conn);
conn.Open();
OdbcDataReader reader = cmd2.ExecuteReader();
while(reader.Read())
{
tmp = reader[0].ToString();
tmp = reader[1].ToString();
tmp = reader[2].ToString();
tmp = reader[3].ToString();
}
conn.Close();
query = "delete from test.dbtable";
OdbcCommand cmd3 = newOdbcCommand(query, conn);
conn.Open();
cmd3.ExecuteNonQuery();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
conn.Close();
}
只要是用C#写过数据库应用的人一定能知道,上面的代码执行了十万次插入数据和读取数据,最后将数据记录全部删除的操作。

使用MySQLDriverCS

可能大部分的人都不知道这个东西,MySQLDriverCS是MySQL数据库的一个免费开源的.NET驱动程序。和Sql .NET Data Provider是为Sql Server一样,它是专门为MySQL设计的,可以叫做MySQL .NET Data Provider。使用他不需要额外的去设置ODBC数据源,基本上只要能连接到MySQL就能通过MySQLDriverCS来访问。

MySQLDriverCS是SourceForge.NET上的一个项目,不过不知道什么原因,这个网站在国内访问不到。

下面是使用MySQLDriverCS的代码示例:

MySQLConnection conn = null;
try
{
string connstr = "Data Source=MySQL;Password=root;User ID=root;Location=localhost";
conn = new MySQLConnection(constr);
conn.Open();
string query = "insert into test.dbtable values(10, ‘disksidkfsdi‘, ‘asdfaf‘, ‘adsfasdf‘)";
string tmp = null;
MySQLCommand cmd = new MySQLCommand(query, conn);
for(int i = 0; i < 100000; i++)
{
cmd.ExecuteNonQuery();
}
cmd.Dispose();
conn.Close();
query = "select * from test.dbtable";
MySQLCommand cmd2 = new MySQLCommand(query, conn);
conn.Open();
MySQLDataReader reader = cmd2.ExecuteReaderEx();
while(reader.Read())
{
tmp = reader[0].ToString();
tmp = reader[1].ToString();
tmp = reader[2].ToString();
tmp = reader[3].ToString();
}
conn.Close();
query = "delete from test.dbtable";
MySQLCommand cmd3 = new MySQLCommand(query, conn);
conn.Open();
cmd3.ExecuteNonQuery();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
conn.Close();
}
和上面的那段代码几乎一模一样,所不同的是Odbc变成了MySQL,另外,需要注意的一点是Command的ExecuteReader方法在MySQLDriverCS中变成了ExecuteReaderEx,还有些细微的差别请参考附带的文档详细的介绍。

性能测试

有些读者其实已经看出来我以上写的那段代码的用意,对了,其实目的就是用来进行性能测试的。以上两段代码的执行时间分别是:ODBC.NET为 24秒左右,MySQLDriverCS为17秒左右。结果并不出人意外,作为MySQL的专用数据驱动程序,MySQLDriverCS的速度大大快于 ODBC.NET是在情理之中的。

总结

本文介绍了两种MySQL数据库访问的方法,同时对它们的性能做了一个简单的测试,希望能为各位读者在采用MySQL数据库开发.NET应用的时候提供一个有价值的参考。

一、不能盲目相信用户输入

在Web应用开发中,开发者最大的失误往往是无条件地信任用户输入,假定用户(即使是恶意用户)总是受到浏览器的限制,总是通过浏览器和服务器交 互,从而打开了攻击Web应用的大门。实际上,黑客们攻击和操作Web网站的工具很多,根本不必局限于浏览器,从最低级的字符模式的原始界面(例如 telnet),到CGI脚本扫描器、Web代理、Web应用扫描器,恶意用户可能采用的攻击模式和手段很多。

因此,只有严密地验证用户输入的合法性,才能有效地抵抗黑客的攻击。应用程序可以用多种方法(甚至是验证范围重叠的方法)执行验证,例如,在认可 用户输入之前执行验证,确保用户输入只包含合法的字符,而且所有输入域的内容长度都没有超过范围(以防范可能出现的缓冲区溢出攻击),在此基础上再执行其 他验证,确保用户输入的数据不仅合法,而且合理。必要时不仅可以采取强制性的长度限制策略,而且还可以对输入内容按照明确定义的特征集执行验证。下面几点 建议将帮助你正确验证用户输入数据:

⑴ 始终对所有的用户输入执行验证,且验证必须在一个可靠的平台上进行,应当在应用的多个层上进行。
⑵ 除了输入、输出功能必需的数据之外,不要允许其他任何内容。
⑶ 设立“信任代码基地”,允许数据进入信任环境之前执行彻底的验证。
⑷ 登录数据之前先检查数据类型。
⑸ 详尽地定义每一种数据格式,例如缓冲区长度、整数类型等。
⑹ 严格定义合法的用户请求,拒绝所有其他请求。
⑺ 测试数据是否满足合法的条件,而不是测试不合法的条件。这是因为数据不合法的情况很多,难以详尽列举。

二、五种常见的ASP.NET安全缺陷

下面给出了五个例子,阐述如何按照上述建议增强应用程序的安全性。这些例子示范了代码中可能出现的缺陷,以及它们带来的安全风险、如何改写最少的代码来有效地降低攻击风险。

2.1 篡改参数

◎ 使用ASP.NET域验证器

盲目信任用户输入是保障Web应用安全的第一敌人。用户输入的主要来源是HTML表单中提交的参数,如果不能严格地验证这些参数的合法性,就有可能危及服务器的安全。

下面的C#代码查询后端SQL Server数据库,假设user和password变量的值直接取自用户输入:
SqlDataAdapter my_query = new SqlDataAdapter(
 "SELECT * FROM accounts WHERE acc_user=‘" + user + "‘ AND acc_password=‘" + password, the_connection);
从表面上看,这几行代码毫无问题,实际上却可能引来SQL注入式攻击。攻击者只要在user输入域中输入“OR 1=1”,就可以顺利登录系统,或者只要在查询之后加上适当的调用,就可以执行任意Shell命令:
‘; EXEC master..xp_cmdshell(Oshell command here‘)–

■ 风险分析
在编写这几行代码时,开发者无意之中作出了这样的假定:用户的输入内容只包含“正常的”数据——合乎人们通常习惯的用户名字、密码,但不会包含引 号之类的特殊字符,这正是SQL注入式攻击能够得逞的根本原因。黑客们可以借助一些具有特殊含义的字符改变查询的本意,进而调用任意函数或过程。

■ 解决方案
域验证器是一种让ASP.NET开发者对域的值实施限制的机制,例如,限制用户输入的域值必须匹配特定的表达式。
要防止上述攻击行为得逞,第一种办法是禁止引号之类的特殊字符输入,第二种办法更严格,即限定输入域的内容必须属于某个合法字符的集合,例如“[a-zA-Z0-9]*”。

2.2 篡改参数之二

◎ 避免验证操作的漏洞

然而,仅仅为每个输入域引入验证器还不能防范所有通过修改参数实施的攻击。在执行数值范围检查之时,还要指定正确的数据类型。

也就是说,在使用ASP.NET的范围检查控件时,应当根据输入域要求的数据类型指定适当的Type属性,因为Type的默认值是String。

<!– 要求输入值必须是1-9之间的数字 –>
<asp:RangeValidator … MinimumValue="1" MaximumValue="9" …/>

■ 风险分析
由于没有指定Type属性值,上面的代码将假定输入值的类型是String,因此RangeValidator验证器只能确保字符串由0-9之间的字符开始,“0abcd”也会被认可。

■ 解决方案
要确保输入值确实是整数,正确的办法是将Type属性指定为Integer:
<!– 要求输入值必须是1-9之间的数字 –>
<asp:RangeValidator … MinimumValue="1"
MaximumValue="9" Type="Integer"

2.3 信息泄漏

◎ 让隐藏域更加安全

在ASP.NET应用中,几乎所有HTML页面的__VIEWSTATE隐藏域中都可以找到有关应用的信息。由于__VIEWSTATE是 BASE 64编码的,所以常常被忽略,但黑客可以方便地解码BASE 64数据,用不着花什么力气就可以得到__VIEWSTATE提供的详细资料。

■ 风险分析
默认情况下,__VIEWSTATE数据将包含:
⑴ 来自页面控件的动态数据。
⑵ 开发者在ViewState中显式保存的数据。
⑶ 上述数据的密码签字。

■ 解决方案
设置EnableViewStatMAC="true",启用__VIEWSTATE数据加密功能。然后,将machineKey验证类型设置成3DES,要求ASP.NET用Triple DES对称加密算法加密ViewState数据。

2.4 SQL注入式攻击

◎ 使用SQL参数API

正如前文“篡改参数”部分描述的,攻击者可以在输入域中插入特殊字符,改变SQL查询的本意,欺骗数据库服务器执行恶意的查询。

■ 风险分析
恶意查询有可能获取后端数据库保存的任何信息,例如客户信用卡号码的清单。

■ 解决方案
除了前面介绍的办法——用程序代码确保输入内容只包含有效字符,另一种更加健壮的办法是使用SQL参数API(例如ADO.NET提供的API),让编程环境的底层API(而不是程序员)来构造查询。

使用这些API时,开发者或者提供一个查询模板,或者提供一个存储过程,然后指定一系列的参数值,由底层API将参数值嵌入到查询模板,然后将构 造出来的查询提交给服务器查询。这种办法的好处是确保参数能够正确地嵌入,例如,系统将对引号进行转义处理,从根本上杜绝SQL注入式攻击的发生。同时, 在表单中引号仍是一个允许输入的有效字符,这也是使用底层API的一个优点。

按照这种思路修改前文“篡改参数”部分的例子,结果如下:
SqlDataAdapter my_query = new SqlDataAdapter("SELECT * FROM accounts
WHERE acc_user= @user AND acc_password=@pass", the_connection);
SqlParameter userParam = my_query.Select_Command.Parameters.Add(
"@user",SqlDb.VarChar,20);
userParam.Value=user;
SqlParameter passwordParam = my_query.Select_Command.Parameters.Add(
"@",SqlDb.VarChar,20);
asswordParam.Value=password;

2.5 跨站脚本执行

◎ 对外发的数据进行编码

跨站脚本执行(Cross-site scripting)是指将恶意的用户输入嵌入到应答(HTML)页面。例如,下面的ASP.NET页面虽然简单,却包含着一个重大的安全缺陷:

<%@ Page Language="vb" %>
<asp:Label id="Label1" runat="server">
标签文字
</asp:Label>
<form method="post" runat="server" ID="Form1">
请在此处输入反馈信息<br>
<asp:Textbox ID="feedback" runat="server"/><br>
<asp:Button id="cmdSubmit" runat="server"
Text="提交!" >
</asp:Button>
</form>
<script runat="server">
Sub do_feedback(sender As Object, e As System.EventArgs)
Label1.Text=feedback.Text
End Sub
</script>

■ 风险分析
攻击者可以用JavaScript代码构造一个恶意的查询,点击链接时JavaScript就会运行。举例来说,脚本可以通过下面的用户输入来嵌入:
<script>alert(document.cookie)
</script>

■ 解决方案
在一个双层的安全体系中,对HTML页面中出现的外发用户数据执行输入验证和HTML编码,确保浏览器只把用户输入数据当成纯粹的文本,而不是其他具有特殊含义的内容,例如HTML代码、JavaScript脚本。

对于本例,只要加入一个HtmlEncode调用即可:
Label1.Text=Server.HtmlEncode(feedback.Text)

这样,应答HTML流将包含用户输入内容的HTML编码版本,也就是说,浏览器不会执行用户输入的JavaScript代码,因为根本不存在HTML的“<SCRIPT>”标记,用户输入的“<”和“>”字符已经被替换成HTML编码版本,即“<”和“>”。

三、使用自动安全测试工具

由于客户需求不断变化,一些单位平均每三个月就要部署新的应用,同时由于人员流动,所以对开发者快速开发健壮的、高质量的代码寄予很高的期望。虽 然对所有开发者进行代码安全技术的培训是十分必要的,但不可否认,自动检测代码安全漏洞的工具也有助于快速开发安全的应用程序。

到目前为止,开发者常用的工具只能涵盖功能测试的特定方面,例如性能测试,BUG/故障点侦查。人工检查代码有着许多与生俱来的局限,而且要求开发者具有丰富的代码安全经验,所以对于编写高质量的应用来说,面向应用程序安全及其在恶意环境下行为的工具也是十分关键的。

要迅速提高应用的质量和安全性,最有效的办法是给开发者提供一个自动测试应用的工具。如果在单元测试期间,工具能够检测出应用的安全缺陷,并将修 补建议嵌入到代码之中,开发者就能立即找出代码中存在的错误,不仅方便了现有错误的修改,而且也有助于避免将来再犯同样的错误,不断地提高代码抗御攻击的 能力。

结束语

Web服务应用正在爆炸式增长,越来越多的应用被推出到防火墙之外,安全性脆弱的Web应用面临的风险也只会有增无减。同时,为了在紧迫的时限之 前快速完成应用开发,开发者面临的压力也越来越大。注重编写代码时的安全问题,同时投入必要的资源,这样才能为未来的Web服务应用做好准备,同时确保当 前应用的高质量。只有从应用的出生之日开始就采取正确的措施来确保其安全性,才能构造出高质量、安全的应用。

消费者左右为难,液晶等离子该选谁?

一年前人们还在谈论平板电视何时可以普及,而一年后的今天,液晶与等离子已经不再被束之高阁,越来越低的价格让很多普通消费者也昂首步入大屏时代,从前的持币待购也终于转化为实实在在的购买行动。

而正当用户真正开始考虑购买平板电视的时候,一些此前不被人注意的问题现在也逐渐浮出水面。其中最被用户关注的一个问题——液晶电视与等离子电视,究竟应该买谁?

的确,这也是困扰很多消费者的一个问题。根据我们在家电卖场里对普通消费做的采访,很多人并不是十分清楚二者在性能、价格方面的差异,因而都是抱着“对比”的心态来卖场里做实地考察,而已经明确购买对象的用户还只占少数。所以我们就有必要针对液晶与等离子的优劣势作出具体的分。

本文并非要去讨论液晶与等离子谁能替代谁,我们会以“购买液晶的理由”与“购买等离子的理由”作为切入点,让您了全面具体地了解到两类产品的各自的优缺点,从而在购买时可以做到心中有数。本篇文章为上篇,着重论述购买液晶的N个理由。

无论是等离子电视、液晶电视,还是传统的映像管电视,都会有各自的市场需求,它们都能在消费者的客厅中找到属于自己的位置.

尺寸:比小不比大,等离子自愧不如

如果您准备为客厅或者书房添置一台20英寸左右的平板电视,你会发现液晶在此时会是你的不二之选。这是因为液晶电视对于尺寸的选择可以很自由,从15英寸到40英寸一应俱全。相比之下,等离子在尺寸方面则要拘束的多,几乎所有的等离子电视的尺寸都在40英寸以上。

由于等离子屏幕上布满了一个个的“等离子腔”

因此画面像素看上去要明显偏大

究其原因,在于它的技术原理。等离子是在2块玻璃之间涂上可发出红、绿、蓝光的荧光材料,铺成“很小的荧光灯”(等离子腔),然后分别进行高速点亮与熄灭。在这里,每一个“荧光灯”就是一个像素,也正是因为这种“荧光灯”的成像方式,就不可避免的会遇到像素粗大的问题,因而等离子就不适合精细加工与显示,所以很难生产出30英寸以下的产品。

而在一、两年前,等离子还可以凭借尺寸优势称霸大屏市场,而随着液晶技术的不断进步,今天40英寸的液晶电视也屡见不鲜。可以说在尺寸的争夺上,液晶与等离子已经难分伯仲。

分辨率:HDTV任重道远,等离子步履维艰

分辨率直接决定了电视画面的清晰度,同时也决定了你在今天购买的产品是否能满足明天高清信号的要求。对于时下的主流产品而言,液晶对比等离子在分辨率方面也同样具有优势。主流液晶电视的尺寸为32英寸,分辨率为1366×768;主流等离子电视的尺寸为42英寸,分辨率一般为852×480或者1024×768。

同样主流产品,液晶在分辨率方面的优势显而易见。并且主流液晶电视更可以支持720P的显示要求,这也使它不至于在高清信号普及之后就会被淘汰。反关等离子,若想支持720P高清显示,就需要50英寸这一级别的产品,但这类产品在价格方面还是偏贵一些,目前在2万元左右。

此外,对于1080P的规格而言,目前市场上销售的等离子电视还望尘莫及,不过液晶电视在这方面的的优势则要突出一些,42英寸支持1080P的产品已经早就开始在市场上销售了。

烧屏:让等离子电视挥之不去的噩梦

等离子电视还有一个隐患就是“烧屏”,由于等离子电视使用了磷光剂,如果屏幕上长时间保持一幅静止图像,则屏幕上会留下该图像的“鬼影”。电视台的新闻滚动条长时间显示在电视画面的下方,或者你经常在宽屏幕上看标准幅面的电视节目,屏幕的上下或两侧会出现影像侧边的影子;此外,观看同一频道的节目太久,屏幕一角的频道标帜可能烙印在屏幕上,在观赏其它频道时仍看得到其残影。从而影响到了观看时的视觉效果。

虽然制造商采取各种手段尽力解决这一问题,但最好还是自己使用中注意,比如不要长时间在屏幕上播放静止图像,以及将对比度设定到50%以下等。相比之下液晶则不存在这一问题,也省去了用户的很多烦恼。

海拔:一个让人难以想象的缺陷

由于等离子电视特殊的工作原理,等离子电视在高海拔地区(超过2500米)也可能会遇到问题。因此等离子屏幕由一个个很小的等离子腔构成,而在等离子腔内又注入各种惰性气体。而在高海拔地区,由于气压低的缘故,会致使等离子电视在工作时发出“嗡嗡”的声音,而更严重则会出现电视无法正常使用的情况。

虽然有厂商已经推出专门的产品来应对等离子电视的“海拔”问题,但如果您正好居住在高海拔地区,我们仍然不推荐您购买等离子电视。

功耗&寿命:液晶电视的传统强项

功耗:

在功能方面,无疑液晶电视具有明显的优势。通常,液晶电视的功耗只有等离子电视电视的3/4左右。

随着技术的不断发展,等离子电视生产厂商也都在花大力气去解决等离子电视的功耗问题,目前已经有低功耗的等离子电视面市,例如日立的1024×1024分辨率的等离子电视,由于采用隔行发光显示的方法工作,不但降低了耗电量、发热量,还可延长使用寿命。

此外,一般来说厂商标称的都是等离子电视的最大功耗,这一指标通常为350~400W。但是在实际使用中,功率曲线将随着图像的显示情况而上下起伏,实际的功率消耗也会比标称值低一些。

寿命:

实际上在寿命这一观点上,我们认为液晶与等离子都同样优秀,只是相对而言,液晶的寿命要更长久一些。按目前最保守的说法,等离子的寿命也不低于4.5万小时,乐观的说法是6万小时,而液晶基本可以达到6万小时,这么算来,即使每天看10个小时,看10年也不会有问题。

趋势:王者无敌!液晶大口吞噬等离子市场

作为平板电视的两大阵营,液晶和等离子电视已经决出胜负。此前赛诺市场研究公司指出,在2003和2004年,液晶电视只是略胜等离子一筹。进入 2005年,液晶电视的份额大幅度上升,占据平板电视70%的市场。预计到2006年,液晶电视的份额将进一步提升,超过75%。从这里我们也可以看出液晶电视在未来的前景将愈发广阔。

值得注意的是,虽然液晶电视在超大屏平板电视市场上还不能敌过等离子电视,但它的尺寸结构则处于不断扩大的趋势,2004年,20英寸是主流液晶电视尺寸,今年主流液晶电视尺寸上升为32英寸,到2006年 37英寸将成为市场主流。

1、iis配置Wap环境

在作为wap站点的属性-->Http头-->MIME映射中添加新的文件类型,具体如下:
关联文件名 内容类型
wml text/vnd.wap.wml
wmlc application/vnd.wap.wamlc
wmls text/vnd.wap.wmlscript
wmlsc application/vnd.wap.wmlscript
wbmp image/vnd.wap.wbmp
编写一个wml文件或者使用asp编写一个动态网页
如果使用asp编写,在源码的开始添加
<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<%Response.ContentType = "text/vnd.wap.wml; charset=utf-8"%>
编码采用utf-8就可以使用模拟器进行浏览了。

2、wap中的编码比较严格,标签区分大小写。标签一定要对应。初学者经常犯这样的错误

3、说到标签对应就涉及到这样一个问题。当在一个表中查询记录的时候,在asp中没有记录就输出“没有记录提示”并response.end。但是在wap中不行,因为这样就不会输出</card></wml>等闭合标签。
我采用的方法是。得到记录集后

if rs.eof then
Wrong="暂时没有记录。。。"
else
‘正常的进行页面显示。。。。。
end if
respong.write Wrong

</p>
</card>
</wml>
这样可以避免标签不闭合。

4、图片下载中首先一定要做到

a、图片格式要正确:有的手机支持png 有的支持gif、bmp、jpg 。(联通CDMA的大部分都支持png)
b、图片的路径要正确:绝对路径 比如http://****/PicDown/aa.png
c、图片的大小要适当:预览的图片不能超过10kb,供下载的图片不能超过30kb。(这个我也不知道有没有标准,这是我在实际测试中得到的数据),下载有些手机支持图片或者铃声可能还要大 <50kb,但是为了照顾大多数手机所以,建议<30kb。
d、图片的大小一定要和图片的名称对应,也就是说 aa.png是多么大,在其size中就写多么大,这两个是对应的。
e、有的手机在手机内存储图片达到一定数量时候,就会提示“下载个数过多”等类似提示,有的手机有预览-->保存(如:MOTO)有的没有,下载后直接保存到手机中(LG8180)。
f、判断用户下载是否成功,可以在指定的文件中获得Status,if Status=‘ok’ 则表明下载成功,进行提示下载成功、下载次数+1等操作,否则,提示下载失败。

5、wap中的分页

分页和web中是一样的,只是有些功能比较简化了,下面是常用的分页,没有写成函数是方便大家修改。

在打开记录集后写,如下代码:

<%
filepath=request.servervariables("path_info")%>
<%page=1
page=request("page")
rs.PageSize = 8 ‘每页的记录的条数
if Not IsEmpty(trim(Request("Page"))) then
Page = CInt(Request("Page"))
if Page > rs.PageCount then
rs.AbsolutePage = rs.PageCount
elseif Page <= 0 then
Page = 1
else
rs.AbsolutePage = Page
end if
End if
%>

然后再想显示分页的地方,一般是在记录集循环输出完毕的后面写:

<%if rs.pagecount<>1 and rs.pagecount<>0 then%>
<br/>
<%if page>rs.pagecount then%>
<a title="确定" href="<%=filepath%>?Page=<% =page -1 %>">上一页</a>
<%else%>
<%if page<>1 then %>
<a title="确定" href="<%=filepath%>?Page=<% =page -1 %>">上一页</a><br/>
<% end if %>
<a title="确定" href="<%=filepath%>?Page=<% = page + 1%>">下一页</a>
<%end if %>
<%end if
response.Write "第"&page&"页 共"&rs.pagecount&"页"
%>

注意显示的时候首先显示下一页,然后再显示上一页这和web上的习惯不太一样。

另外,如果这页的内容是显示是通过上页传送来的参数,作为条件的,则在 类似
<a title="确定" href="<%=filepath%>?Page=<% = page + 1%>">下一页</a>
的地方都要加上该参数,否则进行下一页连接的时候就会把参数丢掉。
例如:从上页用户选择的新闻的种类,来显示新闻。在List.asp页面首先写,NewType=request.form("NewType")得到用户选择的新闻的类型。
然后SQL="Select ……….where NewType=‘"&NewType&"‘" 。完成记录集合的准备工作。注意:在进行下页面的时候要写成
<a title="确定" href="<%=filepath%>?Page=<% =page -1 %>&NewType=<%=NewType%>">上一页</a><br/>,
这样的形式,有多少条件后面跟多少条件。
但是这样就产生问题了,即时这样写NewType=request.form("NewType")也得不到NewType的值。所以在页首刚开始的地方应该写成NewType=request("NewType")。就可以实现把参数带到下一页的连接中了。

wap中上一条、下一条的问题。

在开发中,新闻、笑话、下载等业务为用户提供方便基本都需要在一条记录完成后,再提供下一条记录的操作,下面是简要的对下一条记录实现方法的描述。

比如显示新闻是国际新闻的记录,list.asp来进行显示,通过sql语句select * from NewsInfo where type=‘国际‘ ,来得到符合条件的记录集,用户在浏览过程中,当前记录的id=10,下一条记录的id是idnext=10+1=11,上一条记录的id是idpre= 10-1=9,然后<a href="list.asp?id=‘"&IdNext&"‘">上一条</a>,这样的做法是欠缺 的,仅仅适用与id是连续的,也就是说所有国际新闻的id是连续的,如果国际新闻和国内新闻在表中是穿插写入的,那么你的id-1很可能是国内新闻,条件 限制type=‘国际‘ 就不起作用了。

正确且简练的做法应该是这样的(可能大家还有更好的做法):

当前的id是IdNow,表NewsInfo是按照id自增的。
获得idnext=select top 1 from NewsInfo where type=‘国际‘ and id>‘"&IdNow&"‘
获得Idpre=select top 1 from NewsInfo where type=‘国际‘ and id<‘"&IdNow&"‘ order by id desc

剩下的问题,就不用说了吧,注意,先显示下一条,然后显示上一条,这样才方便用户。

wap中新闻等图片和文字混排

Wap开发中,图片和文字混排,可以采用ubb编码,原理就是自己定义一共特殊的格式,采用mid和replace函数进行转换。比如定义
string1all = Replace(string1all,"" title="看原大图" target="_blank">
string1all = Replace(string1all,"" class="ubb_img" onload="javascript:DrawImage(this);" alt="看原大图"/>
"," "" alt=""""/></p><p>")

会使得图片居中显示。

新闻小说的分页

在wap中过长的新闻和小说,会给大家带来很大的不方便。所以要求进行分页显示,比如按照每页显示300字来举例子。

pageWordNum=300 ‘ 每页显示的字数,这里300可以是变量
StartWord = 1
Length=len(Content) ‘要显示内容的总的长度
PageAll=(Length+PageWordNum-1)\PageWordNum ‘该篇新闻总共可分的总页数

i=request.QueryString("i") ‘第几页的标记
if isnull(i) or i="" then ‘如果是新闻的刚开始则默认i=0
i=0
end if
Content = mid(Content,StartWord+i*PageWordNum,PageWordNum) ‘利用mid函数进行新闻内容的截取(mid函数的含义:从字符串中返回指定数目的字符)




<%
‘开始进行分页操作
if 0<=i<PageAll then
if cint(i)<cint(PageAll)-1 then%>
<a href="ListFengshuiInfo.asp?i=<%=i+1%>">下一页</a><br/>
<%end if
if cint(i)>0 then%>
<a href="ListFengshuiInfo.asp?i=<%=i-1%>">上一页</a><br/>
<%end if
end if
%>

结束。

注意:1、 <a href="ListFengshuiInfo.asp?i=<%=i+1%>">下一页</a>< br/>中ListFengshuiInfo.asp?i=<%=i+1%>可以按照你的实际环境的需要添加变量。
2、Mid函数的解释说明:
从字符串中返回指定数目的字符。
Mid(string, start[, length])
参数
string
字符串表达式,从中返回字符。如果 string 包含 Null,则返回 Null。
Start
string 中被提取的字符部分的开始位置。如果 start 超过了 string 中字符的数目,Mid 将返回零长度字符串 ("")。
Length
要返回的字符数。如果省略或 length 超过文本的字符数(包括 start 处的字符),将返回字符串中从 start 到字符串结束的所有字符。