ASP开发必备:WEB打印代码大全这篇文章主要介绍了如何使用ASP控制Web的各种打印效果,它能够控制纵打、横打和页面边距等。

  1、控制"纵打"、 "横打"和"页面的边距"。 

  (1)

<script defer> 
  function SetPrintSettings() { 
  // — advanced features 
  factory.printing.SetMarginMeasure(2) // measure margins in inches 
  factory.SetPageRange(false, 1, 3) // need pages from 1 to 3 
  factory.printing.printer = "HP DeskJet 870C" 
  factory.printing.copies = 2 
  factory.printing.collate = true 
  factory.printing.paperSize = "A4" 
  factory.printing.paperSource = "Manual feed" 

  // — basic features 
  factory.printing.header = "This is MeadCo" 
  factory.printing.footer = "Advanced Printing by ScriptX" 
  factory.printing.portrait = false 
  factory.printing.leftMargin = 1.0 
  factory.printing.topMargin = 1.0 
  factory.printing.rightMargin = 1.0 
  factory.printing.bottomMargin = 1.0 
  } 
  </script> 

  (2) 


  <script language="javascript"> 
  function printsetup(){ 
  // 打印页面设置 
  wb.execwb(8,1); 
  } 
  function printpreview(){ 
  // 打印页面预览 
  
  wb.execwb(7,1); 
  
  
  } 

  function printit() 
  { 
  if (confirm(‘确定打印吗?‘)) { 
  wb.execwb(6,6) 
  } 
  } 
  </script> 
  </head> 
  <body> 


  <OBJECT classid="CLSID:8856F961-340A-11D0-A96B-00C04FD705A2" 

  height=0 id=wb name=wb width=0></OBJECT> 
  <input type=button name=button_print value="打印" 

  onclick="javascript:printit()"> 
  <input type=button name=button_setup value="打印页面设置" 

  onclick="javascript:printsetup();"> 
  <input type=button name=button_show value="打印预览" 

  onclick="javascript:printpreview();"> 
  <input type=button name=button_fh value="关闭" 

  onclick="javascript:window.close();"> 

  ———————————————— 
  关于这个组件还有其他的用法,列举如下: 
  WebBrowser.ExecWB(1,1) 打开 
  Web.ExecWB(2,1) 关闭现在所有的IE窗口,并打开一个新窗口 
  Web.ExecWB(4,1) 保存网页 
  Web.ExecWB(6,1) 打印 
  Web.ExecWB(7,1) 打印预览 
  Web.ExecWB(8,1) 打印页面设置 
  Web.ExecWB(10,1) 查看页面属性 
  Web.ExecWB(15,1) 好像是撤销,有待确认 
  Web.ExecWB(17,1) 全选 
  Web.ExecWB(22,1) 刷新 
  Web.ExecWB(45,1) 关闭窗体无提示 

  2、分页打印 


  <HTML> 
  <HEAD> 
  <STYLE>   
  P {page-break-after: always} 
  </STYLE> 
  </HEAD> 
  <BODY> 
  <%while not rs.eof%> 
  <P><%=rs(0)%></P> 
  <%rs.movenext%> 
  <%wend%> 
  </BODY> 
  </HTML> 

  3、ASP页面打印时如何去掉页面底部的路径和顶端的页码编号 
  (1)ie的文件-〉页面设置-〉讲里面的页眉和页脚里面的东西都去掉,打印就不出来了。 
  (2)


<HTML> 
  <HEAD> 
  <TITLE> New Document </TITLE> 
  <META NAME="Generator" CONTENT="EditPlus"> 
  <META NAME="Author" CONTENT="YC"> 
  <script language="VBScript"> 


  dim hkey_root,hkey_path,hkey_key 
  hkey_root="HKEY_CURRENT_USER" 
  hkey_path="SoftwareMicrosoftInternet ExplorerPageSetup" 
  ‘//设置网页打印的页眉页脚为空 
  function pagesetup_null() 
  on error resume next 
  Set RegWsh = CreateObject("WScript.Shell") 
  hkey_key="header"   
  RegWsh.RegWrite hkey_root+hkey_path+hkey_key,"" 
  hkey_key="footer" 
  RegWsh.RegWrite hkey_root+hkey_path+hkey_key,"" 
  end function 
  ‘//设置网页打印的页眉页脚为默认值 
  function pagesetup_default() 
  on error resume next 
  Set RegWsh = CreateObject("WScript.Shell") 
  hkey_key="header"   
  RegWsh.RegWrite hkey_root+hkey_path+hkey_key,"&w&b页码,&p/&P" 
  hkey_key="footer" 
  RegWsh.RegWrite hkey_root+hkey_path+hkey_key,"&u&b&d" 
  end function 
  </script> 
  </HEAD> 

  <BODY> 
  <br/> 
  <br/> 
  <br/> 
  <br/> 
  <br/> 
  <br/><p align=center> 
  <input type="button" value="清空页码" onclick=pagesetup_null()> <input type="button" value="恢复页吗" onclick=pagesetup_default()><br/> 

  </p> 
  </BODY> 
  </HTML> 

  4、浮动帧打印 


  <SCRIPT LANGUAGE=javascript> 
  function button1_onclick() { 
  var odoc=window.iframe1.document; 
  var r=odoc.body.createTextRange(); 
  var stxt=r.htmlText; 
  alert(stxt) 
  var pwin=window.open("","print"); 
  pwin.document.write(stxt); 
  pwin.print(); 
  } 
  </SCRIPT> 

  4、用FileSystem组件实现WEB应用中的本地特定打印 


  <script Language=VBScript> 
  function print_onclick //打印函数 
  dim label 
  label=document.printinfo.label.value //获得HTML页面的数据 
  set objfs=CreateObject("Scripting.FileSystemObject") //创建FileSystem组件对象的实例 
  set objprinter=objfs.CreateTextFile ("LPT1:",true) //建立与打印机的连接 
  objprinter.Writeline("__________________________________") //输出打印的内容 
  objprinter.Writeline("| |") 
  objprinter.Writeline("| 您打印的数据是:"&label& " |”) 
  objprinter.Writeline("| |") 
  objprinter.Writeline("|_________________________________|") 
  objprinter.close //断开与打印机的连接 
  set objprinter=nothing 
  set objfs=nothing // 关闭FileSystem组件对象 
  end function 
  </script> 
  服务器端脚本: 
  <%……… 
  set conn=server.CreateObject ("adodb.connection") 
  conn.Open "DSN=name;UID=XXXX;PWD=XXXX;" 
  set rs=server.CreateObject("adodb.recordset") 
  rs.Open(“select ……”),conn,1,1 
  ……….%> //与数据库进行交互 
  HTML页面编码: 
  <HTML> 
  ……… 
  <FORM ID=printinfo NAME="printinfo" > 
  <INPUT type="button" value="打印>>" id=print name=print > //调用打印函数 
  <INPUT type=hidden id=text1 name=label value=<%=………%>> //保存服务器端传来的数据 
  ……… 
  </HTML>


文本代码保护是件很头痛的事,随着了解的加深保护的方法越多,也就意味着漏洞越多.
下面说说我的经验,有更好方法的欢迎交流QQ:17789897.

[-调取原代码的方法-]

1:右键 – 查看原文件
2:查看 – 原文件
3:文件 – 另存为
4:IE缓存
5:还可以通过代码提取
教程代码:
<SCRIPT>
function add()
{
var ress=document.forms[0].it315zhangxx.value
window.location="view-source:"+ress;
}
</SCRIPT>

<p>在网页源代码查看器中输入要查看网页源代码的URL地址:
<p> 
<FORM><INPUT name=it315zhangxx size=56 value=http://></FORM>
<FORM>
<INPUT onclick=add() type=button value=查看网页源代码></FORM>

[-关于保护-]

先通过代码来禁止IE的一些操作

:禁止另存为
<NOSCRIPT><IFRAME src="/*.html>";</IFRAME></NOSCRIPT>

:取消选取、防止复制 不准粘贴 防止复制>
<BODY onselectstart="return false" oncut="return false;" onpaste="return false" onmouseover="window.status=‘ ‘;return true" oncopy="return false;" bgColor=#ffffff leftMargin=0 topMargin=0>

:禁止右键>
<SCRIPT language=JavaScript>
<!–

if (window.Event)
document.captureEvents(Event.MOUSEUP);

function nocontextmenu()
{
event.cancelBubble = true
event.returnValue = false;

return false;
}

function norightclick(e)
{
if (window.Event)
{
if (e.which == 2    e.which == 3)
return false;
}
else
if (event.button == 2    event.button == 3)
{
event.cancelBubble = true
event.returnValue = false;
return false;
}

}

document.oncontextmenu = nocontextmenu; // for IE5+
document.onmousedown = norightclick; // for all others
//–>
</SCRIPT>
:状态栏固定
<body bgcolor="#fef4d9" onmouseover="self.status=‘自定义资料‘;return true">

:禁止缓存 在页面中使用HTML标记,如下面:
<HEAD>
<META http-equiv=Pragma content=no-cache>
<META http-equiv=Cache-Control content=no-cache>
<META http-equiv=Expires content=0>

-利用上面的代码可以禁止下面几种手段-
1:右键 – 查看原文件
3:文件 – 另存为
4:IE缓存

-用代码本身很难禁止下面的手段我门就迷惑的方法阻止调出原代码-
2:查看 – 原文件
5:还可以通过代码提取

URL欺骗(可以隐藏真实地址)
教程代码:

<meta http-equiv="refresh" content="0;url=‘http://东邪.明天毕竟又是新的一天@www.hack.net/index.htm‘">

注意代码中url=‘http://东邪.明天毕竟又是新的一天@www.hack.net/index.htm‘"
@ 符号前面的[http://东邪.明天毕竟又是新的一天]就是欺骗后在IE中出现的效果 也可以是 http://www.163.com
后面的不用说就是连接的真实地址 www.hack.net/index.htm

URL迷惑
<meta http-equiv="refresh" content="0;url=‘http://东邪.明天毕竟又是新的一天@.htm‘">
注意这一段和上面的有什么不同对就是.htm 那.htm是什么呢呵呵其实就是真实地址
怎么访问呢 有.htm吗
呵呵我门要做的就就做一个没有名字的HTM
方法很简单先创建个XXX.htm 上传到 QQ网络硬盘 双激文件名将XXX删除 怎么样.htm出来了吧

这样就算得到原代码很难看出真实地址
列1:http://东邪.明天毕竟又是新的一天@.htm
列2:http://www.163.com/@.htm
呵呵很难看出真实地址是什么吧

[JS禁止 用IE – 查看 – 原文件]
也是迷惑的方法 但是可以绝对禁止以上面的方式调用原文件
要用到JS
教程JS代码
var oPopup = window.createPopup();
var popTop=50;
function popmsg(msgstr){
var winstr="<table style=/"border: 1 solid #000000/" width=/"241/" height=/"172/" border=/"0/" cellpadding=/"0/" cellspacing=/"0/">";
winstr+="<tr><td height=/"150/"></td><td align=/"center/"><table width=/"90%/" height=/"110/" border=/"0/" cellpadding=/"0/" cellspacing=/"0/">";
winstr+="<tr><td valign=/"top/" style=/"font-size:12px; color: #F00000; face: Tahoma/">"+msgstr+"</td></tr></table></td></tr></table>";
oPopup.document.body.innerHTML = winstr;
popshow();
}
function popshow(){
window.status=popTop;
if(popTop>1720){
clearTimeout(mytime);
oPopup.hide();
return;
}else if(popTop>1520&&popTop<1720){
oPopup.show(screen.width-250,screen.height,241,1720-popTop);
}else if(popTop>1500&&popTop<1520){
oPopup.show(screen.width-250,screen.height+(popTop-1720),241,172);
}else if(popTop<180){
oPopup.show(screen.width-250,screen.height,241,popTop);
}else if(popTop<220){
oPopup.show(screen.width-250,screen.height-popTop,241,172);
}
popTop+=10000;
var mytime=setTimeout("popshow();",1);
}
popmsg(" ");

另存为 17789897.js

HTM调用JS代码
<SCRIPT language=javascript
src="/17789897.js"></SCRIPT>
呵呵有写朋友可能熟悉但是我要告诉你他现在的作用是禁止同过 [IE – 查看 – 原文件]
区别在这段代码
popTop+=10000;
var mytime=setTimeout("popshow();",1);
看到了吗?速度是10000
不用我说也知道是什么意思了吧

把上面JS和HTM调用JS代码
加到网页里就可以禁止 [IE – 查看 – 原文件]
关于保护我知道的就这些.

[-关于加密-]
我建议重要的代码采用复合加密
方式基本上有以下几种
JS编码
escape加密
8进制转义字符串
16进制转义字符串
10进制HTML编码如下
16进制HTML编码如下
都可以用<script>
<!–
document.write(unescape("加密后的代码"));
//–>
</script>
由于他门的代码很大还有JS文件我就不给了
大家可以去baidu.com搜索

[-关于破解-]
正所谓魔高一尺,道高一丈,再复杂的加密,在多的迷惑,还是要用IE来解码
给大家个超级技巧
在地址栏或按Ctrl+O,输入:

javascript:s=document.documentElement.outerHTML;document.write(’<body></body>’);document.body.innerText=s;

源代码就出来了.不论加密如何复杂,最终都要还原成浏览器可以解析的html代码,而documentElement.outerHTML正是最终的结果.

作为一个程序员,在完成设计后还要根据程序的情况以及用户的反映不断对程序进行改进,这样才能不断地完善自己的作品。我在制作完软件商务网 http://www.bizsofts.com 的论坛后,发现人们总喜欢在帖子中加上各种有用的URL链接或Email地址。而我当初设计时没有考虑到这一点,使得这些URL链接或Email地址只能 以文字的形式而并不是以超链接的形式显示,其它浏览帖子的人还必须把这些URL链接拷贝到浏览器中或把Email地址拷贝到Outlook中才能转到相应 的链接地址或发送电子邮件到相应的Email地址。
  发现这个问题后,我就着手进行解决。首先是从网上查找有关这方面的现在代码,可惜的是,在搜索引擎上反复查找也没有发现这方面的文章。后来我一想,干脆我自己用ASP.NET编写一个。
  要想自动显示超链接的关键在于如何能正确识别超链接,毫无疑问的,最有效的方法是用正则表达式。正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式,描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取 出符合某个条件的子串等。.NET基础类库中包含有一个名字空间和一系列可以充分发挥规则表达式威力的类,用它就可以自动探测出文字中的URL链接或 Email地址。下面我具体讲讲如何用ASP.NET(C#)一步步实现我们的目的:

  首先,要想在ASP.NET(C#)中使用正则表达式就必须把 System.Text.RegularExpressions 这个命名空间包含进来:

using System.Text.RegularExpressions;

  第二步是用正则表达式识别URL超链接:

Regex urlregex = new Regex(@\"(http:\\/\\/([\\w.]+\\/?)\\S*)\",
RegexOptions.IgnoreCase|RegexOptions.Compiled);

  这里的代码是用正则表达式识别Email地址:

Regex emailregex = new Regex(@\"([a-zA-Z_0-9.-]+\\@[a-zA-Z_0-9.-]+\\.\\w+)\",
RegexOptions.IgnoreCase|RegexOptions.Compiled);

  第三步,当程序已经识别出URL超链接或Email地址后,必须用<a href=…>超链接</a>对这些超链接进行替换,这样才能把这些文字显示为链接的形式。我这里把它们全部包含在函数中:

private void Button1_Click(object sender, System.EventArgs e)
{
string strContent = InputTextBox.Text;
Regex urlregex = new Regex(@\"(http:\\/\\/([\\w.]+\\/?)\\S*)\",
RegexOptions.IgnoreCase| RegexOptions.Compiled);
strContent = urlregex.Replace(strContent,
\"<a href=\\\"\\\" target=\\\"_blank\\\"></a>\");
Regex emailregex = new Regex(@\"([a-zA-Z_0-9.-]+\\@[a-zA-Z_0-9.-]+\\.\\w+)\",
RegexOptions.IgnoreCase| RegexOptions.Compiled);
strContent = emailregex.Replace(strContent, \"<a href=mailto:></a>\");
lbContent.Text += \"<br>\"+strContent;
}

  通过以上几步,你就可以在网页上自动显示超链接以及Email地址了。欢迎大家下载本示例的源代码,以及到http://www.bizsofts.com 的论坛上观看实际效果。(作者注:该篇文章的英文版已经发表在CodePoject和CodeGuru上)

<SCRIPT language=JavaScript1.2>
message="任何款式的虚拟主机空间均可免费试用一周。(先试用,后付款!)所试用的空间是真实的空间,即试用空间=将要购买的空间。"
ns6switch=1
var ns6=document.getElementById&&!document.all
mes=new Array();
mes[0]=-1;
mes[1]=-4;
mes[2]=-7;mes[3]=-10;
mes[4]=-7;
mes[5]=-4;
mes[6]=-1;
num=0;
num2=0;
txt="";
function jump0(){
if (ns6&&!ns6switch){
jump.innerHTML=message
return
}
if(message.length > 6){
for(i=0; i != message.length;i++){
txt=txt+"<span style=‘position:relative;‘ id=‘n"+i+"‘>"+message.charAt(i)+"</span>"};
jump.innerHTML=txt;
txt="";
jump1a()
}
else{
alert("上海伯汉网络科技有限公司")
}
}
function jump1a(){
nfinal=(document.getElementById)? document.getElementById("n0") : document.all.n0
nfinal.style.left=-num2;
if(num2 != 9){
num2=num2+3;
setTimeout("jump1a()",50)
}
else{
jump1b()
}
}

function jump1b(){
nfinal.style.left=-num2;
if(num2 != 0){num2=num2-3;
setTimeout("jump1b()",50)
}
else{
jump2()
}
}
function jump2(){
txt="";
for(i=0;i != message.length;i++){
if(i+num > -1 && i+num < 7){
txt=txt+"<span style=‘position:relative;top:"+mes[i+num]+"‘>"+message.charAt(i)+"</span>"
}
else{txt=txt+"<span>"+message.charAt(i)+"</span>"}
}
jump.innerHTML=txt;
txt="";
if(num != (-message.length)){
num–;
setTimeout("jump2()",50)}
else{num=0;
setTimeout("jump0()",50)}}
</SCRIPT>
<DIV id=jumpx style="COLOR: #3C6897"></DIV>
<SCRIPT>
if (document.all||document.getElementById){
jump=(document.getElementById)? document.getElementById("jumpx") : document.all.jumpx
jump0()
}
else
document.write(message)
</SCRIPT>

大家好,我是Asp.net的忠实爱好者,很想把这方面的经验和大家分享一下. 目前我选用的是时代互联(http://www.now.net.cn )的Asp.net+ACCESS空间(增强C).
欢迎大家一起进来讨论讨论!
——————————————————————————–

注意:要运行上述ACCESS例程请先下载数据库, 与例程放在同一目录下。
<%@ Import Namespace="System.Data" %>
<%@ Import NameSpace="System.Data.OleDb" %>
<script laguage="VB" runat="server">
Dim myConnection As OleDbConnection
Dim myCommand As OleDbCommand
sub page_load(sender as Object,e as EventArgs)
‘1.连接数据库
dim dbname as string
dbname=server.mappath("authors.mdb")
myConnection = New OleDbConnection( "PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA Source="&dbname )
myConnection.Open()
la1.text="Connection Opened!"

‘2.添加记录
myCommand = New OleDbCommand( "Insert INTO Authors(Authors,country) Values(‘Simson‘,‘usa‘)", myConnection )
myCommand.ExecuteNonQuery()
la2.text="New Record Inserted!"

‘3 更新数据(Access)
myCommand = New OleDbCommand( "UPDATE Authors SET Authors=‘Bennett‘ WHERE Authors = ‘Simson‘", myConnection )
myCommand.ExecuteNonQuery()
la3.text="Record Updated!"

‘4 删除数据(access)
myCommand = New OleDbCommand( "DELETE FROM Authors WHERE Authors = ‘David‘", myConnection )
myCommand.ExecuteNonQuery()
la4.text="Record Deleted!"

‘5 使用DateGrid显示数据
myCommand = New OleDbCommand( "select * FROM Authors", myConnection )
MyDataGrid.DataSource=myCommand.Executereader()
MyDataGrid.DataBind()

end sub
</script>
<html>
<body>
<asp:label id="la1" runat="server" /><br>
<asp:label id="la2" runat="server" /><br>
<asp:label id="la3" runat="server" /><br>
<asp:label id="la4" runat="server" /><br>
<ASP:DataGrid id="MyDataGrid" runat="server"
BorderColor="black"
BorderWidth="1"
GridLines="Both"
CellPadding="3"
CellSpacing="0"
Font-Name="Verdana"
Font-Size="10pt"
HeaderStyle-BackColor="#aaaadd"
AlternatingItemStyle-BackColor="#eeeeee"
>
</asp:DataGrid>

</body>
</html>
注意:要运行上述ACCESS例程请先下载数据库,与例程放在同一目录下。

Asp.net+ACCESS这款时代互联的空间在使用的速度和稳定上我都是非常满意的!

Asp.net虚拟主机的服务提供商中,目前首推的是CNNIC的其中一家权威机构—时代互联(www.now.net.cn),
他们在2003年便更新使用微软发布最新版本的ASP.net Web Matrix了.经笔者的使用测试,
他提供的ASP.NET空间性能非常的稳定,版本也会定期的更新升级!

使用详解和例程: http://www.now.net.cn/support/host/(这里有更多更细的Asp.net的详细例程)
全球免费咨询电话:http://www.now.net.cn/customer/moreline.net(很方便的)
时代互联的Asp.net空间购买方法:http://www.now.net.cn/host

Asp.net虚拟主机的服务提供商中,目前首推的是CNNIC的其中一家权威机构—时代互联(www.now.net.cn),
他们在2003年便更新使用微软发布最新版本的ASP.net Web Matrix了.经笔者的使用测试,
他提供的ASP.NET空间性能非常的稳定,版本也会定期的更新升级!

喜欢asp.net和需要建网站的朋友,可以去网站看看,相信会在asp.net的使用方面会有更深的认识。

本文是我在进行MS-Windows、HP-Unix网络编程的实践过程中总结出来的一些经验,仅供大家参考。本文所谈到的Socket函数如果没有特别说明,都是指的Windows Socket API。

  一、WSAStartup函数

  int WSAStartup(
  WORD wVersionRequested,
  LPWSADATA lpWSAData
  );

  使用Socket的程序在使用Socket之前必须调用WSAStartup函数。该函数的第一个参数指明程序请求使用的Socket版本, 其中高位字节指明副版本、低位字节指明主版本;操作系统利用第二个参数返回请求的Socket的版本信息。当一个应用程序调用WSAStartup函数 时,操作系统根据请求的Socket版本来搜索相应的Socket库,然后绑定找到的Socket库到该应用程序中。以后应用程序就可以调用所请求的 Socket库中的其它Socket函数了。该函数执行成功后返回0。

  例:假如一个程序要使用2.1版本的Socket,那么程序代码如下

  wVersionRequested = MAKEWORD( 2, 1 );
  err = WSAStartup( wVersionRequested, &wsaData );

  二、WSACleanup函数

  int WSACleanup (void);

  应用程序在完成对请求的Socket库的使用后,要调用WSACleanup函数来解除与Socket库的绑定并且释放Socket库所占用的系统资源。

  三、socket函数

  SOCKET socket(
  int af,
  int type,
  int protocol
  );

  应用程序调用socket函数来创建一个能够进行网络通信的套接字。第一个参数指定应用程序使用的通信协议的协议族,对于TCP/IP协议 族,该参数置PF_INET;第二个参数指定要创建的套接字类型,流套接字类型为SOCK_STREAM、数据报套接字类型为SOCK_DGRAM;第三 个参数指定应用程序所使用的通信协议。该函数如果调用成功就返回新创建的套接字的描述符,如果失败就返回INVALID_SOCKET。套接字描述符是一 个整数类型的值。每个进程的进程空间里都有一个套接字描述符表,该表中存放着套接字描述符和套接字数据结构的对应关系。该表中有一个字段存放新创建的套接 字的描述符,另一个字段存放套接字数据结构的地址,因此根据套接字描述符就可以找到其对应的套接字数据结构。每个进程在自己的进程空间里都有一个套接字描 述符表但是套接字数据结构都是在操作系统的内核缓冲里。下面是一个创建流套接字的例子:

  struct protoent *ppe;
  ppe=getprotobyname("tcp");
  SOCKET ListenSocket=socket(PF_INET,SOCK_STREAM,ppe->p_proto);

  四、closesocket函数

  int closesocket(
  SOCKET s
  );

  closesocket函数用来关闭一个描述符为s套接字。由于每个进程中都有一个套接字描述符表,表中的每个套接字描述符都对应了一个位于 操作系统缓冲区中的套接字数据结构,因此有可能有几个套接字描述符指向同一个套接字数据结构。套接字数据结构中专门有一个字段存放该结构的被引用次数,即 有多少个套接字描述符指向该结构。当调用closesocket函数时,操作系统先检查套接字数据结构中的该字段的值,如果为1,就表明只有一个套接字描 述符指向它,因此操作系统就先把s在套接字描述符表中对应的那条表项清除,并且释放s对应的套接字数据结构;如果该字段大于1,那么操作系统仅仅清除s在 套接字描述符表中的对应表项,并且把s对应的套接字数据结构的引用次数减1。

  closesocket函数如果执行成功就返回0,否则返回SOCKET_ERROR。

  五、send函数

  int send(
  SOCKET s,
  const char FAR *buf,
  int len,
  int flags
  );

  不论是客户还是服务器应用程序都用send函数来向TCP连接的另一端发送数据。客户程序一般用send函数向服务器发送请求,而服务器则通 常用send函数来向客户程序发送应答。该函数的第一个参数指定发送端套接字描述符;第二个参数指明一个存放应用程序要发送数据的缓冲区;第三个参数指明 实际要发送的数据的字节数;第四个参数一般置0。这里只描述同步Socket的send函数的执行流程。当调用该函数时,send先比较待发送数据的长度 len和套接字s的发送缓冲区的长度,如果len大于s的发送缓冲区的长度,该函数返回SOCKET_ERROR;如果len小于或者等于s的发送缓冲区 的长度,那么send先检查协议是否正在发送s的发送缓冲中的数据,如果是就等待协议把数据发送完,如果协议还没有开始发送s的发送缓冲中的数据或者s的 发送缓冲中没有数据,那么send就比较s的发送缓冲区的剩余空间和len,如果len大于剩余空间大小send就一直等待协议把s的发送缓冲中的数据发 送完,如果len小于剩余空间大小send就仅仅把buf中的数据copy到剩余空间里(注意并不是send把s的发送缓冲中的数据传到连接的另一端的, 而是协议传的,send仅仅是把buf中的数据copy到s的发送缓冲区的剩余空间里)。如果send函数copy数据成功,就返回实际copy的字节 数,如果send在copy数据时出现错误,那么send就返回SOCKET_ERROR;如果send在等待协议传送数据时网络断开的话,那么send 函数也返回SOCKET_ERROR。要注意send函数把buf中的数据成功copy到s的发送缓冲的剩余空间里后它就返回了,但是此时这些数据并不一 定马上被传到连接的另一端。如果协议在后续的传送过程中出现网络错误的话,那么下一个Socket函数就会返回SOCKET_ERROR。(每一个除 send外的Socket函数在执行的最开始总要先等待套接字的发送缓冲中的数据被协议传送完毕才能继续,如果在等待时出现网络错误,那么该Socket 函数就返回SOCKET_ERROR)

  注意:在Unix系统下,如果send在等待协议传送数据时网络断开的话,调用send的进程会接收到一个SIGPIPE信号,进程对该信号的默认处理是进程终止。

六、recv函数

  int recv(
  SOCKET s,
  char FAR *buf,
  int len,
  int flags
  );

  不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据。该函数的第一个参数指定接收端套接字描述符;第二个参数指明一 个缓冲区,该缓冲区用来存放recv函数接收到的数据;第三个参数指明buf的长度;第四个参数一般置0。这里只描述同步Socket的recv函数的执 行流程。当应用程序调用recv函数时,recv先等待s的发送缓冲中的数据被协议传送完毕,如果协议在传送s的发送缓冲中的数据时出现网络错误,那么 recv函数返回SOCKET_ERROR,如果s的发送缓冲中没有数据或者数据被协议成功发送完毕后,recv先检查套接字s的接收缓冲区,如果s接收 缓冲区中没有数据或者协议正在接收数据,那么recv就一直等待,只到协议把数据接收完毕。当协议把数据接收完毕,recv函数就把s的接收缓冲中的数据 copy到buf中(注意协议接收到的数据可能大于buf的长度,所以在这种情况下要调用几次recv函数才能把s的接收缓冲中的数据copy完。 recv函数仅仅是copy数据,真正的接收数据是协议来完成的),recv函数返回其实际copy的字节数。如果recv在copy时出错,那么它返回 SOCKET_ERROR;如果recv函数在等待协议接收数据时网络中断了,那么它返回0。

  注意:在Unix系统下,如果recv函数在等待协议接收数据时网络断开了,那么调用recv的进程会接收到一个SIGPIPE信号,进程对该信号的默认处理是进程终止。

  七、bind函数

  int bind(
  SOCKET s,
  const struct sockaddr FAR *name,
  int namelen
  );

  当创建了一个Socket以后,套接字数据结构中有一个默认的IP地址和默认的端口号。一个服务程序必须调用bind函数来给其绑定一个IP 地址和一个特定的端口号。客户程序一般不必调用bind函数来为其Socket绑定IP地址和断口号。该函数的第一个参数指定待绑定的Socket描述 符;第二个参数指定一个sockaddr结构,该结构是这样定义的:

  struct sockaddr {
  u_short sa_family;
  char sa_data[14];
  };

  sa_family指定地址族,对于TCP/IP协议族的套接字,给其置AF_INET。当对TCP/IP协议族的套接字进行绑定时,我们通常使用另一个地址结构:

  struct sockaddr_in {
  short sin_family;
  u_short sin_port;
  struct in_addr sin_addr;
  char sin_zero[8];
  };

  其中sin_family置AF_INET;sin_port指明端口号;sin_addr结构体中只有一个唯一的字段s_addr,表示 IP地址,该字段是一个整数,一般用函数inet_addr()把字符串形式的IP地址转换成unsigned long型的整数值后再置给s_addr。有的服务器是多宿主机,至少有两个网卡,那么运行在这样的服务器上的服务程序在为其Socket绑定IP地址时 可以把htonl(INADDR_ANY)置给s_addr,这样做的好处是不论哪个网段上的客户程序都能与该服务程序通信;如果只给运行在多宿主机上的 服务程序的Socket绑定一个固定的IP地址,那么就只有与该IP地址处于同一个网段上的客户程序才能与该服务程序通信。我们用0来填充 sin_zero数组,目的是让sockaddr_in结构的大小与sockaddr结构的大小一致。下面是一个bind函数调用的例子:

  struct sockaddr_in saddr;
  saddr.sin_family = AF_INET;
  saddr.sin_port = htons(8888);
  saddr.sin_addr.s_addr = htonl(INADDR_ANY);
  bind(ListenSocket,(struct sockaddr *)&saddr,sizeof(saddr));

  八、listen函数

  int listen( SOCKET s, int backlog );

  服务程序可以调用listen函数使其流套接字s处于监听状态。处于监听状态的流套接字s将维护一个客户连接请求队列,该队列最多容纳backlog个客户连接请求。假如该函数执行成功,则返回0;如果执行失败,则返回SOCKET_ERROR。

  九、accept函数

  SOCKET accept(
  SOCKET s,
  struct sockaddr FAR *addr,
  int FAR *addrlen
  );

  服务程序调用accept函数从处于监听状态的流套接字s的客户连接请求队列中取出排在最前的一个客户请求,并且创建一个新的套接字来与客户 套接字创建连接通道,如果连接成功,就返回新创建的套接字的描述符,以后与客户套接字交换数据的是新创建的套接字;如果失败就返回 INVALID_SOCKET。该函数的第一个参数指定处于监听状态的流套接字;操作系统利用第二个参数来返回新创建的套接字的地址结构;操作系统利用第 三个参数来返回新创建的套接字的地址结构的长度。下面是一个调用accept的例子:

  struct sockaddr_in ServerSocketAddr;
  int addrlen;
  addrlen=sizeof(ServerSocketAddr);
  ServerSocket=accept(ListenSocket,(struct sockaddr *)&ServerSocketAddr,&addrlen);

  十、connect函数

  int connect(
  SOCKET s,
  const struct sockaddr FAR *name,
  int namelen
  );

  客户程序调用connect函数来使客户Socket s与监听趎ame所指定的计算机的特定端口上的服务Socket进行连接。如果连接成功,connect返回0;如果失败则返回SOCKET_ERROR。下面是一个例子:

  struct sockaddr_in daddr;
  memset((void *)&daddr,0,sizeof(daddr));
  daddr.sin_family=AF_INET;
  daddr.sin_port=htons(8888);
  daddr.sin_addr.s_addr=inet_addr("133.197.22.4");
  connect(ClientSocket,(struct sockaddr *)&daddr,sizeof(daddr));

在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

测试工具: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
%>

源码下载地址:点击下载