qishun's profile躺在角落的孤独者PhotosBlogLists Tools Help

Blog


    August 21

    windows下双网卡双网关的设置

    双网卡双网关的设置

    工作中遇到双网卡双网关的问题,经过查询和实践,设置好后做个笔记记录,具体如下:

    单位安装的瑞星网络版服务器,一方面服务器本身需要上互联网即时更新病毒库,另一方面内网的机器又需要到服务器上更新病毒库。这就需要在反病毒服务器上安装二块网卡,并连接二个不同的网络。

    网络A(互联网)IP:221.231.X.134 子网掩码:255.255.255.248 网关:221.231.X.129

    网络B(局域网):172.32.18.XXX 子网掩码:255.255.0.0 网关:172.32.1.1

    现设置如下:

    将网络A(互联网)设好固定IP,将网关设为221.231.X.129;网络B(局域网)设好固定IP,将网关留空。

    二个网卡要将网卡A的网关设为默认网关,即将网卡A的跃点设为1,就可设为默认网关了。(跃点设置具体为:在TCP/IP的高级属性里,去掉窗口下部的“自动跃点计数”前的小勾,并填写1即可)

    在CMD下输入route print 后面显示的默认网关就改为了221.231.X.129

    Default Gateway:       221.231.X.129
    ===========================================

    接着,再增加一条路由命令就OK了

    进入CMD,运行:

    route -p add 172.32.0.0 mask 255.255.0.0 172.32.1.1 metric 30

    (意思是将172开头IP包的路由网关设为172.32.1.1,-p 参数代表永久写入路由表,如果不加此参数,每次机器重启后设置会丢失,要重新设置。)

    同时启用两个网卡,两个网关可以同时起作用了,两个子网也可以同时访问了,加了参数-P后关机重启也不用重设,是不是很方便呢?
    August 12

    IBM Director

    在同一个时期内,不同厂商所推出的服务器的硬件配置是非常相似的,硬件的价格成本也是非常相似的。但是如何有效的利用硬件设备投资,则需要一套有效的系统管理软件,提高硬件设备的可用性,保持较低的运行和维护成本。IBM试图为自己的每个系列的产品都配置优秀的行业工具,以提高可用性、跟踪资产、优化性能并实现远程维护,从而节约用户的时间和资金。  

    IBM Director功能示意图

      通过上面的示意图我们可以了解到,IBM以Director为中心帮助用户进行部署(Deploy)、维护和更新(Maintain and update)、监测和报警(Monitor and alert)、Optimize(优化)、Analyze and trouble shoot(分析和解决故障)等5个方面的工作。

      IBM Director是IBM提供的一个具有良好兼容性的系统管理解决方案,它符合工业标准,可以支持大部分的基于Intel微处理器的系统和部分IBM eServer i系列和p系列服务器。在IBM X系列服务器中附送了不同版本的IBM Director,比如我们这次所测试的X346 8840服务器中附送了IBM Director v4.22,X336 8837服务器中附送了IBM Director v4.21,目前最新版本为5.10。

      IBM Director可以用于多操作系统环境(异构环境),被设计用于管理包括数量众多的服务器、PC、工作站、笔记本等多种计算机混合的复杂环境,最多可以管理5000个系统。它可以同种类繁多的工作组和企业管理软件整合,比如IBM、Computer Associates、Hewlett-Packard、Microsoft、NetIQ和BMC等的软件。

      IBM Director的主要组件包括IBM Director Server、IBM Director Agent和IBM Director Console。它们的主要功能是:

      IBM Director Server是IBM Director的主要组件,它包括了管理数据、服务器引擎和应用程序逻辑。IBM Director Server的基本功能是发现可管理系统、持续的存储配置和管理数据、存货清单、事件监听、安全和认证、管理控制台支持、管理任务。IBM Director Server用SQL数据库储存“盘存数据”。安装了IBM Director Server的服务器被称之为管理服务器。IBM授予X系列服务器1份Director Server安装许可。

      IBM Director Agent向IBM Director Server提供采集到的数据,它们之间可以采用TCP/IP、NetBIOS、IPX和SNA等多种协议传输数据。IBM Director Server可以同网络中安装了Agent软件的所有系统通讯。在不同的操作系统上,IBM Director Agent的功能有所不同。安装了IBM Director Agent程序的系统被称为可管理系统。IBM授予用户20份IBM Director Agent安装许可。

      IBM Director Console用于远程控制,它的主要作用充当IBM Director Server的GUI,供远程用户进行操作。Director Console/Server两者之间通过TCP/IP协议传输数据。利用IBM Director Console,用户可以通过简单的鼠标操作就可以完成大部分的系统管理工作。IBM给予X系列服务器用户无限数量的授权,可以在任意数量的系统上安装。

    IBM Director光盘启动界面

      IBM部署工具包括Remote Deployment Manager(远程部署管理器,RDM)、ServerGuide,它们可以帮助用户尽可能快的设置好系统并且让系统进入到正常运行状态。

     RDM可以提供用户远程部署IBM或者非IBM系统的能力,它支持Windows 2003和Linux(Redhat和SuSe)系统的远程无人值守安装,可帮助用户远程初始化操作系统安装、更新BIOS、处理淘汰系统等等。

      IBM ServerGuide支持主流操作系统,比如Windows 2000/2003、Linux(Redhat和SUSE)、Novell NetWare。ServerGudie可自动识别IBM计算机型号、机型、SerVerRAID适配器以及其它硬件,并且根据收集到的硬件信息安装相应的驱动程序,还可以根据用户的设定安装系统组件。我们试用过程中发现只要按照ServerGuide的指引进行设定,等待程序把需要的文件拷贝到硬盘中,那么剩下的事情就可以完全交给ServerGuide。ServerGuide可以有效的简化操作系统的安装,从而帮助降低总体拥有成本和对于管理人员与技术人员的要求。

      监控和报警工具需要IBM Director、IBM Director Agent、Capacity Manager、System Availability等多个工具配合实现。Capacity Manager(容量管理器)可以帮助用户监测关键资源的利用情况,比如处理器占用率、硬盘容量、内存利用率和网络连通性能。它可以根据侦测到数据,判断服务器或者服务器群当前或者潜在的瓶颈。它可以生成性能分析报告。系统可用性(System Availability )工具可跟踪停机和正常运行时间,从而为您提供可使您评测系统管理工具效率的图形视图。

      优化工具是一套具有“预警”功能的高级系统管理工具,它通过最大化正常运行时间、优化服务器吞吐量、利用率和性能来最大化服务器投资。这一系列工具包括Capacity Manager(容量管理器)、System Availability(系统可用性)、Virtual Machine Manager(虚拟机管理器)和Application Workload Manager(应用程序负载管理器),显然是监控和报警工具的功能扩展。

      AWM主要用于消除系统资源竞争,它通过于IBM Director紧密集成实现精确的CPU资源分配、内存/虚拟内存分配,在最大成都的提高系统利用率的同时却不会影响应用程序的性能。AWM还能提供实现服务器整合所需的资源管理能力。

      维护和升级工具主要用于保持系统的更新,它需要RDM、UpdateXpress和Software Distribution三个工具的支持。UpdateXpress可以自动监测当前硬件设备的驱动程序和固件版本,然后可以对于BIOS、诊断程序、系统管理处理器、ServeRAID、磁盘驱动器和硬盘驱动器的软件进行升级。更重要的是UpdateXpress能够识别可自动安装的固件与设备驱动程序更新,并将其分发到LAN 中运行Windows的任何目标计算机上, UpdateXpress简化了维护数百台甚至是更多台服务器的工作。

      分析和故障解决工具,包括远程管理适配器、动态系统分析、实时诊断和支持工具。利用预测性故障分析(PFA)可以周期性的评估硬盘驱动器、电源、风扇、处理器和内存工作状态,如果任何一个组件的参数超过了预定义的阈值,PFA就会发出警告,用户可以在故障真正出现之前更换硬件。集成系统管理处理器 (ISMP)可以进一步增强系统在这个方面的功能,而远程管理适配器的功能更加强大。IBM实时诊断软件可以在运行状态的服务器上运行行业标准的诊断实用程序,这最大程度地保证了服务器可用性,同时又实现了对于服务器的主动预防性维护。

      IBM以IBM Director管理工具为核心,从系统部署、管理、维护、更新等多个方面提供了全面的软件解决方案,充分的利用它们,可以明显的降低系统维护的成本、保证系统最长正常运行时间和最大化用户在服务器上投资。这套管理解决方案是目前我们所接触到的功能最全面的服务器管理解决方案,当然要全面的掌握一系列软件的应用也是需要用户深入学习才能掌握的。

    August 04

    远程桌面默认端口修改

        集团演示方案准备使用远程桌面提供客户进行体验,和信息中心沟通以后,不能开启默认的远程桌面端口,于是乎,到百度求救,
    得到如下总结,嘻嘻,第三步很重要,刚开始修改了第二步,第三步没改,不启作用,白忙活了半天。


    一、修改注册表.
    1、开始--运行--regedit
    依次展开

    2、HKEY_LOCAL_MACHINE/SYSTEM/CURRENTCONTROLSET/CONTROL/TERMINAL SERVER/WDS/RDPWD/TDS/TCP
    右边键值中 PortNumber 改为你想用的端口号.注意使用十进制(例 14001)

    3、HKEY_LOCAL_MACHINE/SYSTEM/CURRENTCONTROLSET/CONTROL/TERMINAL SERVER/WINSTATIONS/RDP-TCP/
    右边键值中 PortNumber 改为你想用的端口号.注意使用十进制(例 14001)

    4、修改完毕.重新启动服务器.设置生效.

    5、这样.使用MICROSOFT_TERMINALSERVER_CLIENT连接的时候.
    就应该填写 IP:14001
    即 ip 后面跟冒号和端口号.
    December 28

    解决在Firefox下面Live Space“发布日志”按钮被禁用的问题

    本文转自http://ftofficer.spaces.live.com/

    解决在Firefox下面Live Space“发布日志”按钮被禁用的问题

    也许你发现了上面的帖子。
    这个帖子是我在进行测试,看看能不能启用Live Space的“发布日志”按钮。
    事实上是成功了,特将其分享给大家。

    首先,你需要安装Firefox扩展 greasemonkey。这个扩展可以使你在加载一个页面的时候执行一段你自己的Javascript程序。

    安装之后,将下面的程序拷贝到一个文本文件,并把扩展名改成 .user.js。(务必是.user.js,否则greasemonkey无法自动安装之)。

    ===脚本开始,拷贝时请不要包含这一行===
    // ==UserScript==
    // @name           Enable Live Space Post Button
    // @namespace      http://ftofficer.spaces.live.com
    // @description    Enable Live Space Post Button
    // @include        http://*.spaces.live.com/*
    // ==/UserScript==

    function LiveSpace_enableButton(id) {
      var button = document.getElementById(id);
      if ( button ) {
        var cls = button.getAttribute("class");
        var clsNameEnd = cls.indexOf("spDisabled");
        if ( clsNameEnd != -1 ) {
          clsNameEnd--;   // skip " " before spDisabled
          var newCls = cls.substring(0, clsNameEnd);
         
          button.setAttribute("class", newCls);
          button.setAttribute("mi:state", "enabled");

          var aNode = document.createElement("a");
          aNode.id = id;
          aNode.href = "#";
        }
      }
    }

    LiveSpace_enableButton("actionToolbarBlogPost");
    LiveSpace_enableButton("actionToolbarSave");

    ===脚本结束,拷贝时请不要包含这一行===

    然后将这个js文件拖放到Firefox窗口中,greasemonkey会弹出对话框询问是否安装,选择是,即可完成安装。

    然后,去Live Space的“添加日志”当中看看吧。

    如果看到“发布日志”和“保存为草稿”仍然没有启用的话,请看看greasemonkey当中配置的网直通配符是不是和你的网址一致,自己改改看看。在不行可以在这里回复。
    October 31

    通过HttpWebRequest 发送 POST 请求到一个网页服务器

    编写个程序实现自动用户登录,自动提交表单数据到网站等。
    假如某个页面有个如下的表单(Form):

    <form name="form1" action="http://www.breakn.com/login.asp" method="post">
    <input type="text" name="userid" value="">
    <input type="password" name="password" value="">
    </form>

    从表单可看到表单有两个表单域,一个是userid另一个是password,所以以POST形式提交的数据应该包含有这两项。
    其中POST的数据格式为:
    表单域名称1=值1&表单域名称2=值2&表单域名称3=值3……
    要注意的是“值”必须是经过HTMLEncode的,即不能包含“<>=&”这些符号。

    本例子要提交的数据应该是:
    userid=value1&password=value2

    用C#写提交程序:
    string strId = "guest";
    string strPassword= "123456";

    ASCIIEncoding encoding=new ASCIIEncoding();
    string postData="userid="+strId;
    postData += ("&password="+strPassword);

    byte[] data = encoding.GetBytes(postData);

    // Prepare web request...
    HttpWebRequest myRequest =
    (HttpWebRequest)WebRequest.Create("http://www.here.com/login.asp");

    myRequest.Method = "POST";
    myRequest.ContentType="application/x-www-form-urlencoded";
    myRequest.ContentLength = data.Length;
    Stream newStream=myRequest.GetRequestStream();

    // Send the data.
    newStream.Write(data,0,data.Length);
    newStream.Close();

    // Get response
    HttpWebResponse myResponse=(HttpWebResponse)myRequest.GetResponse();
    StreamReader reader = new StreamReader(response.GetResponseStream(),Encoding.Default);
    string content = reader.ReadToEnd();
    Response.Write(content);

    October 25

    利用yahoo天气实现自己的天气预报

    本文是对上面文件的一个修改,因为刚学,.,在上一篇里犯了错误,请教了下别人,解决了.
    感谢在过程中帮助我的人!
     
    <%@ Page language="c#" Debug="true"%>
    <%@import NameSpace = "System"%>
    <%@import NameSpace = "System.Collections"%>
    <%@import NameSpace = "System.ComponentModel"%>
    <%@import NameSpace = "System.Data"%>
    <%@import NameSpace = "System.Drawing"%>
    <%@import NameSpace = "System.Web"%>
    <%@import NameSpace = "System.Web.SessionState"%>
    <%@import NameSpace = "System.Web.UI"%>
    <%@import NameSpace = "System.Web.UI.WebControls"%>
    <%@import NameSpace = "System.Web.UI.HtmlControls"%>
    <%@import NameSpace = "System.IO"%>
    <%@import NameSpace = "System.Net"%>
    <%@import NameSpace = "System.Text"%>
    <script language="c#" runat="Server">
    //protected System.Web.UI.WebControls.Button WebClientButton;
    //protected System.Web.UI.WebControls.Button WebRequestButton;
    //protected System.Web.UI.WebControls.TextBox ContentHtml;
    //protected System.Web.UI.WebControls.TextBox UrlText;
    public string PageUrl = "http://weather.cn.yahoo.com/weather.html?city=";
    public string strWeather=null;
     void Page_Load(object sender, System.EventArgs e)
    {
       if(!this.IsPostBack)
        {
        UrlText.Text = "青岛";
           WebRequestButton_Click( sender, e );
     }
     else
     {
        WebRequestButton_Click( sender, e );
     }
    }
    void WebRequestButton_Click(object sender, System.EventArgs e)
    {
     PageUrl += Server.UrlEncode(UrlText.Text);
     //PageUrl = UrlText.Text;
     WebRequest request = WebRequest.Create(PageUrl);
     WebResponse response = request.GetResponse();
     Stream resStream = response.GetResponseStream();
     StreamReader sr = new StreamReader(resStream, Encoding.UTF8);
     strWeather = findWeather(sr.ReadToEnd());
     resStream.Close();
     sr.Close();
     response.Close();
     //request.Dispose();
     //Response.Write(strWeather);
    }
     void WebClientButton_Click(object sender, System.EventArgs e)
    {
     PageUrl += UrlText.Text;
     WebClient wc = new WebClient();
     wc.Credentials = CredentialCache.DefaultCredentials;
     ///方法一:
     Byte[] pageData = wc.DownloadData(PageUrl);
     strWeather = findWeather( Encoding.UTF8.GetString(pageData) );
     /// 方法二:
     /// ***************代码开始**********
     /// Stream resStream = wc.OpenRead(PageUrl);
     /// StreamReader sr = new StreamReader(resStream,System.Text.Encoding.Default);
     /// ContentHtml.Text = sr.ReadToEnd();
     /// resStream.Close();
     /// **************代码结束********
     ///
     wc.Dispose();
     Response.Write(strWeather);
    }
    public string findWeather(string str)
    {
         int startIndex = str.IndexOf("<!--{{start:今日 -->");
      if(startIndex < 0)
      {
        return "不支持该城市";
      }
         int endIndex = str.IndexOf("<!--}}end:今日-->");
      return str.Substring(startIndex,(endIndex-startIndex));
    }
    </script>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
    <HTML>
    <HEAD>
    <title>天气预报</title>
    <meta name="GENERATOR" Content="Microsoft Visual Studio 7.0">
    <meta name="CODE_LANGUAGE" Content="C#">
    <meta name="vs_defaultClientScript" content="JavaScript">
    <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5";>
    <script language="javascript" src="weather.js"></script>
    </HEAD>
    <body MS_POSITIONING="GridLayout">
    <form id="aspNetBuffer" method="post" runat="server">
    <div align="center" style="FONT-WEIGHT: bold">天气预报</div>
    <asp:TextBox id="UrlText" runat="server" Width="400px">http://dotnet.aspx.cc/content.aspx
    </asp:TextBox>
     <!--<asp:Button id="WebClientButton" Runat="server" Text="用WebClient得到" onClick="WebClientButton_Click"></asp:Button> -->
    <asp:Button id="WebRequestButton"  runat="server" onClick="WebRequestButton_Click" Text="查询"></asp:Button>
    <br/>
    <!--<asp:TextBox id="ContentHtml" runat="server" Width="100%" Height="360px" TextMode="MultiLine">
    </asp:TextBox>-->
    <%= strWeather %>
    </form>
    </body>
    </HTML>

    用wenrequest和webresponse获取页面代码

     今天使用webclient获取页面源代码,费了半天的劲,才完成很少的一部分功能。
    主要是在编码的问题上遇到了的麻烦,我们知道一般情况下读取的时候代码如下:
            WebRequest request = WebRequest.Create(Url);
     WebResponse response = request.GetResponse();
     Stream resStream = response.GetResponseStream();
     StreamReader sr = new StreamReader(resStream, Encoding.GetEncoding(Encoding.Default.EncodingName));
     string strCode = sr.ReadToEnd();
     resStream.Close();
     sr.Close();
     response.Close();
    strcode就是我们获取到的整个页面代码,这样我们读取的时候一半会出现中文乱码,
    我刚开始在网上查到要使用“gb2312”,但是仍没有用处,还是一堆乱码。最后才找到
    问题的原因。
      我们读取页面的时候 streamreader的编码要与页面编码保持一致(页面中的charset
    保持一致),如果我们读取特定的一个页面可以用固定的编码就可以,但是我们抓取各
    种网站的页面时,我们就需要判定页面的charset。
       下面是利用正则表达式获取页面的charser,然后在读取页面代码。(我们使用编码
       形式一般不影响代码中的英文字符),所以我使用如下代码:
            WebRequest request = WebRequest.Create(Url);
            WebResponse response = request.GetResponse();
            Stream resStream = response.GetResponseStream();
     StreamReader sr = new StreamReader(resStream, Encoding.GetEncoding(Encoding.Default.EncodingName));
     string strCode = sr.ReadToEnd();
     string strEncode = null;
     Regex regCharset = new Regex(@"charset\b\s*(?<charset>[^""]*)");
     if(regCharset.IsMatch(strCode))
     {
        strEncode = regCharset.Match(strCode).Groups["charset"].Value;
     }
     else
     {
        strEncode = Encoding.Default.EncodingName;
     }
        获取正确的charset以后,你就可以顺利的读取页面代码了。
         下面是我简单的获取了yahoo天气预报(估计用不了多长时间,就被yahoo嘎掉了),
         使用asp.net。
         <%@ Page language="c#" Debug="true"%>
    <%@import NameSpace = "System"%>
    <%@import NameSpace = "System.Collections"%>
    <%@import NameSpace = "System.ComponentModel"%>
    <%@import NameSpace = "System.Data"%>
    <%@import NameSpace = "System.Drawing"%>
    <%@import NameSpace = "System.Web"%>
    <%@import NameSpace = "System.Web.SessionState"%>
    <%@import NameSpace = "System.Web.UI"%>
    <%@import NameSpace = "System.Web.UI.WebControls"%>
    <%@import NameSpace = "System.Web.UI.HtmlControls"%>
    <%@import NameSpace = "System.IO"%>
    <%@import NameSpace = "System.Net"%>
    <%@import NameSpace = "System.Text"%>
    <script language="c#" runat="Server">
    //protected System.Web.UI.WebControls.Button WebClientButton;
    //protected System.Web.UI.WebControls.Button WebRequestButton;
    //protected System.Web.UI.WebControls.TextBox ContentHtml;
    //protected System.Web.UI.WebControls.TextBox UrlText;
    public string PageUrl = "http://weather.cn.yahoo.com/weather.html?city=";
     void Page_Load(object sender, System.EventArgs e)
    {
       if(!this.IsPostBack)
        {
        UrlText.Text = "";
     }
    }
    void WebRequestButton_Click(object sender, System.EventArgs e)
    {
     //PageUrl += Server.UrlEncode(UrlText.Text);
     PageUrl = UrlText.Text;
     WebRequest request = WebRequest.Create(PageUrl);
     WebResponse response = request.GetResponse();
     Stream resStream = response.GetResponseStream();
     StreamReader sr = new StreamReader(resStream, Encoding.UTF8);
            string strWeather = findWeather( sr.ReadToEnd() );
     resStream.Close();
     sr.Close();
     response.Close();
     if(strWeather == null)
     {
       Response.Write("不支持该城市");
     }
     Response.Write(strWeather);
     //request.Dispose();
     //ContentHtml.Text));
    }
     void WebClientButton_Click(object sender, System.EventArgs e)
    {
     PageUrl += UrlText.Text;
     WebClient wc = new WebClient();
     wc.Credentials = CredentialCache.DefaultCredentials;
     ///方法一:
     Byte[] pageData = wc.DownloadData(PageUrl);
     string strWeather = Encoding.UTF8.GetString(pageData);
     /// 方法二:
     /// ***************代码开始**********
     /// Stream resStream = wc.OpenRead(PageUrl);
     /// StreamReader sr = new StreamReader(resStream,System.Text.Encoding.Default);
     /// ContentHtml.Text = sr.ReadToEnd();
     /// resStream.Close();
     /// **************代码结束********
     ///
     wc.Dispose();
     Response.Write(findWeather(strWeather));
    }
    public string findWeather(string str)
    {
         int startIndex = str.IndexOf("<!--{{start:今日 -->");
         int endIndex = str.IndexOf("<!--}}end:今日-->");
         if(startIndex < 0 || endIndex < 0)
         {
           return null;
         }
         return str.Substring(startIndex,(endIndex-startIndex));
    }
    </script>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
    <HTML>
    <HEAD>
    <title>得到网页源代码</title>
    <meta name="GENERATOR" Content="Microsoft Visual Studio 7.0">
    <meta name="CODE_LANGUAGE" Content="C#">
    <meta name="vs_defaultClientScript" content="JavaScript">
    <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5";>
    <script language="javascript" src="weather.js"></script>
    </HEAD>
    <body MS_POSITIONING="GridLayout">
    <form id="aspNetBuffer" method="post" runat="server">
    <div align="center" style="FONT-WEIGHT: bold">天气预报</div>
    <asp:TextBox id="UrlText" runat="server" Width="400px">http://dotnet.aspx.cc/content.aspx
    </asp:TextBox>
     <asp:Button id="WebClientButton" Runat="server" Text="用WebClient得到" onClick="WebClientButton_Click"></asp:Button> -->
    <asp:Button id="WebRequestButton"  runat="server" onClick="WebRequestButton_Click" Text="用WebRequest得到"></asp:Button>
    <br/>
    </asp:TextBox>
    </form>
    </body>
    </HTML>
    代码没进行严格的错误处理,有心的可以自己帮忙写下。
    还有就是,搜索完一次后,再进行搜索则出错,问题未解决,希望高手
    给解决下,附上代码,大家共同努力!
    October 08

    如何实现javascript代码中的中文编码

         在直接利用javascript的时候, 我们使用document.write输出时,可能的不到想要的中文,这样可以在我们的
    <script >中加上charset="gb2312"属性,即可正常显示!

    如何使用ajax为<a>添加自定义提示(实现tooltip)

     
    把下面的代码引入到你的.html页面
    (function() {  // Anonymous function to hold all our symbols
        // Create the tool tip object we'll use
        var tooltip = new Tooltip();
        // Arrange to have the init() function called on document load
        if (window.addEventListener) window.addEventListener("load", init, false);
        else if (window.attachEvent) window.attachEvent("onload", init);
        // To be called when the document loads
        function init() {
            var links = document.getElementsByTagName('a');
           // Loop through all the links, adding event handlers to them
            for(var i = 0; i < links.length; i++)
                if (links[i].href) addTooltipToLink(links[i]);
        }
        // This is the function that adds event handlers
        function addTooltipToLink(link) {
            // Add event handlers
            if (link.addEventListener) {  // Standard technique
                link.addEventListener("mouseover", mouseover, false);
                link.addEventListener("mouseout", mouseout, false);
            }
            else if (link.attachEvent) {  // IE-specific technique
                link.attachEvent("onmouseover", mouseover);
                link.attachEvent("onmouseout", mouseout);
            }
            var timer; // Used with setTimeout/clearTimeout
            function mouseover(event) {
                var e = event || window.event;
                // Get mouse position, convert to document coordinates, add offset
              
       var x = e.clientX + Geometry.getHorizontalScroll() + 25;
       
                var y = e.clientY + Geometry.getVerticalScroll() + 15;
                // If a tool tip is pending, cancel it
                if (timer) window.clearTimeout(timer);
                // Schedule a tool tip to appear in half a second
                timer = window.setTimeout(showTooltip, 500);
                function showTooltip() {
                    // If it is an HTTP link, and if it is from the same host
                    // as this script is, we can use XMLHttpRequest
                    // to get more information about it.
                    if (link.protocol == "http:" && link.host == location.host) {
                        // Make an XMLHttpRequest for the headers of the link
                        HTTP.getHeaders(link.href, function(headers) {
                            // Use the headers to build a string of text
                            var tip = "URL: " + link.href + "<br>" +
                                "Type: " + headers["Content-Type"] + "<br>" +
                                "Size: " + headers["Content-Length"] + "<br>" +
                                "Date: " + headers["Last-Modified"];
                            // And display it as a tool tip
                            tooltip.show(tip, x, y);
                        });
                    }
                    else {
                        // Otherwise, if it is an off-site link, the
                        // tool tip is just the URL of the link
                        tooltip.show("URL: " + link.href, x, y);
                    }
                }
            }
            function mouseout(e) {
                // When the mouse leaves a link, clear any
                // pending tool tips or hide it if it is shown
                if (timer) window.clearTimeout(timer);
                timer = null;
                tooltip.hide();
            }
        }
    })();
    September 28

    利用javcsript和css实现的柱状图形

    /**
     * BarChart.js:
     * This file defines makeBarChart( ), a function that creates a bar chart to
     * display the numbers from the data[] array. The overall size of the chart
     * is specified by the optional width and height arguments, which include the
     * space required for the chart borders and internal padding. The optional
     * barcolor argument specifies the color of the bars. The function returns the
     * <div> element it creates, so the caller can further manipulate it by
     * setting a margin size, for example. The caller must insert the returned
     * element into the document in order to make the chart visible.
     **/
    function makeBarChart(data, width, height, barcolor) {
        // Provide default values for the optional arguments
        if (!width) width = 500;
        if (!height) height = 350;
        if (!barcolor) barcolor = "blue";
        // The width and height arguments specify the overall size of the
        // generated chart. We have to subtract the border and padding
        // sizes from this to get the size of the element we create.
        width -= 24;  // Subtract 10px padding and 2px border left and right
        height -= 14; // Subtract 10px top padding and 2px top and bottom border
        // Now create an element to hold the chart. Note that we make the chart
        // relatively positioned so that it can have absolutely positioned children
        // but still appear in the normal element flow.
        var chart = document.createElement("div");
        chart.style.position = "relative";          // Set relative positioning
        chart.style.width = width + "px";           // Set the chart width
        chart.style.height = height + "px";         // Set the chart height
        chart.style.border = "solid black 2px";     // Give it a border
        chart.style.paddingLeft = "10px";           // Add padding on the left
        chart.style.paddingRight = "10px";          // and on the right
        chart.style.paddingTop = "10px";            // and on the top
        chart.style.paddingBottom = "0px";          // but not on the bottom
        chart.style.backgroundColor = "white";      // Make chart background white
        // Compute the width of each bar
        var barwidth = Math.floor(width/data.length);
        // Find largest number in data[]. Note clever use of Function.apply( ).
        var maxdata = Math.max.apply(this, data);
        // The scaling factor for the chart: scale*data[i] gives height of a bar
        var scale = height/maxdata;
        // Now loop through the data array and create a bar for each datum
        for(var i = 0; i < data.length; i++) {
            var bar = document.createElement("div"); // Create div for bar
            var barheight = data[i] * scale;         // Compute height of bar
            bar.style.position = "absolute";         // Set bar position and size
            bar.style.left = (barwidth*i+1+10)+"px"; // Add bar border and chart pad
            bar.style.top = height-barheight+10+"px";// Add chart padding
            bar.style.width = (barwidth-2) + "px";   // -2 for the bar border
            bar.style.height = (barheight-1) + "px"; // -1 for the bar top border
            bar.style.border = "solid black 1px";    // Bar border style
            bar.style.backgroundColor = barcolor;    // Bar color
            bar.style.fontSize = "0px";              // IE workaround
            chart.appendChild(bar);                  // Add bar to chart
        }
        // Finally, return the chart element so the caller can manipulate it
        return chart;
    }
    在使用时,可以直接调用makebarchart()函数即可!
    September 07

    Microsoft AJAX Library Cheat Sheet:DomEvent类

     

    本文为翻译,英文原版的Cheat Sheet(PDF版本)在此下载:http://aspnetresources.com/downloads/ms_ajax_library_cheat_sheets1.zip

    原作版权声明:

    Copyright (c) 2004-2006, Milan Negovan 
    http://www.AspNetResources.com
    All rights reserved.
    
    Redistribution and use in source and binary forms, with or without 
    modification, are permitted provided that the following conditions 
    are met:
    
        * Redistributions of source code must retain the above copyright 
          notice, this list of conditions and the following disclaimer.
          
        * Redistributions in binary form must reproduce the above copyright 
          notice, this list of conditions and the following disclaimer in 
          the documentation and/or other materials provided with the 
          distribution.
          
        * The name of the author may not be used to endorse or promote products
          derived from this software without specific prior written permission.
    
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 
    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
    PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
    OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
    OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
    ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

     

    注:标注有[S]的为静态方法,无须实例化对象即可使用。

     

    [S] addHandler (element, eventName, handler)
    [S] $addHandler (element, eventName, handler)

    为DOM元素添加某一事件的处理函数,事件名称应去掉“on”前缀。

    注意:在事件处理函数中,this指向的是element,而不一定是发出该事件的元素。

    Sys.UI.DomEvent.addHandler (element, "click", clickHandler);
    // Same as $addHandler (element, "click", clickHandler);
    function clickHandler (e) { … }

     

    [S] addHandlers (element, events, handlerOwner)
    [S] $addHandlers (element, events, handlerOwner)

    为DOM元素添加多个事件处理函数,events是一个事件处理函数的字典。

    注意:在事件处理函数中,若指定了handlerOwner,那么this将指向该handlerOwner,否则将指向element。

    $addHandlers ($get ("article"), {
        mouseover: onMouseOver,
        mouseout: onMouseOut
    });
    function onMouseOver (e) { this.style.backgroundColor = 'yellow'; }
    function onMouseOut (e) { this.style.backgroundColor = 'white'; }

     

    [S] clearHandlers (element)
    [S] $clearHandlers (element)

    移除指定DOM元素所有的事件处理函数。

    Sys.UI.DomEvent.clearHandlers (element);
    // Same as $ clearHandlers (element);

     

    [S] removeHandler (element, eventName, handler)
    [S] $removeHandler (element, eventName, handler)

    为DOM元素移除指定的事件处理函数。

    Sys.UI.DomEvent.removeHandler (element, "click", clickHandler);
    // Same as $removeHandler (element, "click", clickHandler);

     

    preventDefault ()

    阻止执行默认的事件处理函数。例如若阻止了a元素的onclick事件,那么将不会引发页面导航。

    $addHandler ($get ("showMoreLink"), "click", showMore);
    function showMore (e) { e.preventDefault (); }

     

    stopPropagation ()

    阻止事件冒泡传递至父元素。

     

    Event对象的属性

    1. altKey:判断触发事件时Alt键是否被按下。
    2. button:得到触发事件的鼠标按键。可选值为Sys.UI.MouseButton枚举(leftButton、middleButton和rightButton)。
    3. charCode:得到触发事件时的键盘按键代码。可以为Sys.UI.Key枚举(backspace, tab, enter,esc, space, pageUp, pageDown, end, home, left, up, right, down, del)。
    4. clientX:鼠标指针相对于文档可见区域的X坐标。
    5. clientY:鼠标指针相对于文档可见区域的Y坐标。
    6. ctrlKey:判断触发事件时Ctrl键是否被按下。
    7. offsetX:鼠标指针相对于触发事件元素左侧边缘的偏移位置。
    8. offsetY:鼠标指针相对于触发事件元素上边缘的偏移位置。
    9. rawEvent:原始的DOM事件。
    10. screenX:鼠标指针相对于浏览者屏幕的X坐标。
    11. screenY:鼠标指针相对于浏览者屏幕的Y坐标。
    12. shiftKey:判断触发事件时Shift键是否被按下。
    13. target:触发事件的对象。
    14. type:事件名称(例如“click”)。
     

    October 22

    摘录高手的代码,关与win32下的线程


    线程同步是多线程程序设计的核心内容,它的目的是正确处理多线程并发时的各种问题,例如线程的等待、多个线程访问同一数据时的互斥,防死锁等。Win32提供多种内核对象和手段用于线程同步,如互斥量、信号量、事件、临界区等。所不同的是,互斥量、信号量、事件都是Windows的内核对象,当程序对这些对象进行控制时会自动转换到核心态,而临界区本身不是内核对象,它是工作在用户态的。我们知道从用户态转换到核心态是需要以时间为代价的,所以如果能在用户态就简单解决的问题,就可以不必劳烦核心态了。
    这里我要说的是两种用于C++的多线程同步类,通过对这两种类的使用就可以方便的实现对变量或代码段的加锁控制,从而防止多线程对变量不正确的操作。
    所谓加锁,就是说当我们要访问某关键变量之前,都需要首先获得允许才能继续,如果未获得允许则只有等待。一个关键变量拥有一把锁,一个线程必须先得到这把锁(其实称为钥匙可能更形象)才可以访问这个变量,而当某个变量持有这把锁的时候,其他线程就不能重复的得到它,只有等持有锁的线程把锁归还以后其他线程才有可能得到它。之所以这样做,就是为了防止一个线程读取某对象途中另一线程对它进行了修改,或两线程同时对一变量进行修改,例如:
     // 全局:
              struct  MyStruct  ... {  int  a, b; } ;
           MyStruct s;
     // 线程1:
             int  a  =  s.a;
            int  b  =  s.b;
     // 线程2:
            s.a ++ ;
           s.b -- ;
    如果实际的执行顺序就是上述书写的顺序那到没有什么,但如果线程2的执行打断了线程1,变为如下顺序:
           int a = s.a;      //线程1
           s.a++;            //线程2
           s.b++;            //线程2
           int b = s.b;      //线程1
    那么这时线程1读出来的a和b就会有问题了,因为a是在修改前读的,而b是在修改后读的,这样读出来的是不完整的数据,会对程序带来不可预料的后果。天知道两个程的调度顺序是什么样的。为了防止这种情况的出现,需要对变量s加锁,也就是当线程1得到锁以后就可以放心的访问s,这时如果线程2要修改s,只有等线程1访问完成以后将锁释放才可以,从而保证了上述两线程交叉访问变量的情况不会出现。
    使用Win32提供的临界区可以方便的实现这种锁:
     // 全局:
            CRITICAL_SECTION cs;
           InitializeCriticalSection( & cs);
     // 线程1:
            EnterCriticalSection( & cs);
            int  a  =  s.a;
            int  b  =  s.b;
           LeaveCriticalSection( & cs);
     // 线程2:
            EnterCriticalSection( & cs);
           s.a ++ ;
           s.b -- ;
           LeaveCriticalSection( & cs);
     // 最后:
            DeleteCriticalSection( & cs); 代码中的临界区变量(cs)就可以看作是变量s的锁,当函数EnterCriticalSection返回时,当前线程就获得了这把锁,之后就是对变量的访问了。访问完成后,调用LeaveCriticalSection表示释放这把锁,允许其他线程继续使用它。
    如果每当需要对一个变量进行加锁时都需要做这些操作,显得有些麻烦,而且变量cs与s只有逻辑上的锁关系,在语法上没有什么联系,这对于锁的管理带来了不小的麻烦。程序员总是最懒的,可以想出各种偷懒的办法来解决问题,例如让被锁的变量与加锁的变量形成物理上的联系,使得锁变量成为被锁变量不可分割的一部分,这听起来是个好主意。
    首先想到的是把锁封闭在一个类里,让类的构造函数和析构函数来管理对锁的初始化和锁毁动作,我们称这个锁为“实例锁”:
             class  InstanceLockBase
            ... {
                  CRITICAL_SECTION cs;
            protected :
                  InstanceLockBase()  ... { InitialCriticalSection( & cs); }
                    ~ InstanceLockBase()  ... { DeleteCriticalSection( & cs); }
           } ; 如果熟悉C++,看到这里一定知道后面我要干什么了,对了,就是继承,因为我把构造函数和析构函数都声明为保护的(protected),这样唯一的作用就是在子类里使用它。让我们的被保护数据从这个类继承,那么它们不就不可分割了吗:
             struct  MyStruct:  public  InstanceLockBase
            ... { … } ;
    什么?结构体还能从类继承?当然,C++中结构体和类除了成员的默认访问控制不同外没有什么不一样,class能做的struct也能做。此外,也许你还会问,如果被锁的是个简单类型,不能继承怎么办,那么要么用一个类对这个简单类型进行封装(记得Java里有int和Integer吗),要么只好手工管理它们的联系了。如果被锁类已经有了基类呢?没关系,C++是允许多继承的,多一个基类也没什么。
    现在我们的数据里面已经包含一把锁了,之后就是要添加加锁和解锁的动作,把它们作为InstanceLockBase类的成员函数再合适不过了:
             class  InstanceLockBase
            ... {
                  CRITICAL_SECTION cs;
                   void  Lock()  ... { EnterCriticalSection( & cs); }
                    void  Unlock()  ... { LeaveCriticalSection( & cs); }
                  …
    } ;
    看到这里可能会发现,我把Lock和Unlock函数都声明为私有了,那么如何访问这两个函数呢?是的,我们总是需要有一个地方来调用这两个函数以实现加锁和解锁的,而且它们总应该成对出现,但C++语法本身没能限制我们必须成对的调用两个函数,如果加完锁忘了解,那后果是严重的。这里有一个例外,就是C++对于构造函数和析构函数的调用是自动成对的,对了,那就把对Lock和Unlock的调用专门写在一个类的构造函数和析构函数中:
     class  InstanceLock
     ... {
                  InstanceLockBase *  _pObj;
     public :
                  InstanceLock(InstanceLockBase *  pObj)
                   ... {
                         _pObj  =  pObj;  // 这里会保存一份指向s的指针,用于解锁
                           if (NULL  !=  _pObj)
                                _pObj -> Lock();       // 这里加锁
                   }
                   ~ InstanceLock()
                   ... {
                          if (NULL  !=  _pObj)
                                _pObj -> Unlock();    // 这里解锁
                   }
    } ;
    最后别忘了在类InstanceLockBase中把InstanceLock声明为友元,使得它能正确访问Lock和Unlock这两个私有函数:
     class  InstanceLockBase
     ... {
                  friend  class  InstanceLock;
                  …
    } ;
    好了,有了上面的基础,现在对变量s的加解锁管理变成了对InstanceLock的实例的生命周期的管理了。假如我们有一个函数ModifyS中要对s进行修改,那么只要在函数一开始就声明一个InstaceLock的实例,这样整个函数就自动对s加锁,一旦进入这个函数,其他线程就都不能获得s的锁了:
             void  ModifyS()
            ... {
                  InstanceLock  lock ( & s);         // 这里已经实现加锁了
                   // some operations on s
            }                                                 // 一旦离开lock对象的作用域,自动解锁
    如果是要对某函数中一部分代码加锁,只要用一对大括号把它们括起来再声明一个lock就可以了:
            …
            ... {
                  InstanceLock  lock ( & s);
                   //  do something …
            }
           … 好了,就是这么简单。下面来看一个测试。
    首先准备一个输出函数,对我们理解程序有帮助。它会在输出我们想输出的内容同时打出行号和时间:
     void  Say( char *  text)
     ... {
                   static   int  count  =   0 ;
                  SYSTEMTIME st;
                  ::GetLocalTime( & st);
                  printf( " %03d [%02d:%02d:%02d.%03d]%s " ,  ++ count, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, text);
    }
    当然,原则上当多线程都调用这个函数时应该对其静态局部变量count进行加锁,这里就省略了。
    我们声明一个非常简单的被锁的类型,并生成一个实例:
     class  MyClass:  public  InstanceLockBase
     ... {} ;
    MyClass mc;
    子线程的任务就是对这个对象加锁,然后输出一些信息:
     DWORD CALLBACK ThreadProc(LPVOID param)
     ... {
                  InstanceLock il( & mc);
                  Say( " in sub thread, lock " );
                  Sleep( 2000 );
                  Say( " in sub thread, unlock " );
                   return   0 ;
    }
    这里会输出两条信息,一是在刚刚获得锁的时间,二是在释放锁的时候,中间通过Sleep来延迟2秒。
    主线程负责开启子线程,然后也对mc加锁:
     CreateThread( 0 ,  0 , ThreadProc,  0 ,  0 ,  0 );
            ... {
                  InstanceLock il( & mc);
                  Say( " in main thread, lock " );
                  Sleep( 3000 );
                  Say( " in main thread, lock " );
           } 运行此程序,得到的输出如下:
    001 [13:43:23.781]in main thread, lock
    002 [13:43:26.781]in main thread, lock
    003 [13:43:26.781]in sub thread, lock
    004 [13:43:28.781]in sub thread, unlock
    从其输出的行号和时间可以清楚的看到两个线程间的互斥:当主线程恰好首先获得锁时,它会延迟3秒,然后释放锁,之后子线程才得以继续进行。这个例子也证明我们的类工作的很好。
    总结一下,要使用InstanceLock系列类,要做的就是:
    1 让被锁类从InstanceLockBase继承
    2 所有要访问被锁对象的代码前面声明InstanceLock的实例,并传入被锁对象的指针。
     
    附:完整源代码:
     #pragma  once
    #include  < windows.h >
     
     class  InstanceLock;
     
     class  InstanceLockBase
     ... {
           friend  class  InstanceLock;
     
           CRITICAL_SECTION cs;
     
            void  Lock()
            ... {
                  ::EnterCriticalSection( & cs);
           }
     
            void  Unlock()
            ... {
                  ::LeaveCriticalSection( & cs);
           }
     
     protected :
           InstanceLockBase()
            ... {
                  ::InitializeCriticalSection( & cs);
           }
     
            ~ InstanceLockBase()
            ... {
                  ::DeleteCriticalSection( & cs);
           }
    } ;
     
     class  InstanceLock
     ... {
           InstanceLockBase *  _pObj;
     public :
           InstanceLock(InstanceLockBase *  pObj)
            ... {
                  _pObj  =  pObj;
                   if (NULL  !=  _pObj)
                         _pObj -> Lock();
           }
     
            ~ InstanceLock()
            ... {
                   if (NULL  !=  _pObj)
                         _pObj -> Unlock();
           }
    } ;
    October 16

    使用存储过程

    _CommandPtr pIDCommand;
     pIDCommand.CreateInstance(__uuidof(Command));
     _bstr_t storeproc("getIDbyName");
     _variant_t var;
     CString strValue;
     int IDvalue;
     try{ 
     pIDCommand->ActiveConnection=m_pConnection;
     pIDCommand->CommandText=storeproc;
     pIDCommand->CommandType=adCmdStoredProc;
     pIDCommand->Parameters->Refresh();
        pIDCommand->Parameters->Item[_variant_t((long)1)]->Value=_variant_t((LPCTSTR)dvdName);
     _RecordsetPtr pIDRecordset;
     pIDRecordset.CreateInstance(__uuidof(Recordset));
     
        pIDRecordset=pIDCommand->Execute(NULL,NULL,adCmdStoredProc);
     if((pIDRecordset->BOF)&&(pIDRecordset->adoEOF))
     {
      MessageBox("error!");
      pIDRecordset->Close();
      pIDRecordset=NULL;
      return -1;
     }
     var=pIDRecordset->GetCollect("DVDID");
     pIDRecordset->Close();
     pIDRecordset=NULL;

    sqlserver中数据库的创建以及表的创建

    创建数据库
    create database student
    on
    (name=student_dat,
     filename='E:\study\mydatabase\student.mdf',
     size=10,maxsize=50,filegrowth=2)
    log on(
     name=student_log,
      filename='E:\study\mydatabase\student.ldf',
      size=5,maxsize=50,filegrowth=20%)
    创建表 约束关系,主键、外键
    use student
    if exists(select * from sysobjects where name='teacher')
      drop table teacher
    go
    create table teacher(
     TID varchar(10) primary key,
     TName varchar(30) not null,
     TAge tinyint,
     TTitle varchar(10) not null,
     TSex char(2) check(TSex='男'or TSex='女')
    )
    go
    create table course
    ( CID int,
      CName varchar(30) not null,
      CScore tinyint not null,
      CParent int,
      CTime int,
      CTeacher varchar(10),
      primary key( CID),
     foreign key(CTeacher) references teacher(TID)
    )
    插入数据
    insert into stu(SID,SName,SSex,SFrom) values(0308010423,'dongdong','男','山东省')
    修改数据
    use student
    update  stu set SAge=23 where SID=0308010423
    修改列