成长空间

MiLife

常用链接

统计

积分与排名

Automation Testing Development

最新评论

2007年7月25日 #

gdb

基础:
http://blog.csai.cn/user3/50125/archives/2009/35140.html

多进程:
http://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/index.html

多线程:
http://www.91linux.com/html/article/program/20070406/1441.html

break [linespec] thread [threadno]
 http://www.linuxforum.net/forum/gshowflat.php?Cat=&Board=program&Number=692404&page=0&view=collapsed&sb=5&o=all

posted @ 2009-05-25 13:45 Picasso 阅读(339) | 评论 (0)编辑 收藏

sonmame - used to provide version backwards-compatibility information.

    In Unix operating systems, a soname is a field of data in a shared object file. The soname is a string (typically the filename of the library) which is used as a "logical name" describing the functionality of the object. This is often used to provide version backwards-compatibility information. For instance, if versions 1.0 through 1.9 of the shared library libx provide identical interface, they would all have the same soname, e.g. libx.so.1. If the system only includes version 1.3 of that shared object, libx.so.1.3, the soname field of the shared object tells the system that it can be used to fill the dependency for a binary which was originally compiled using version 1.2.

posted @ 2009-05-05 15:13 Picasso 阅读(360) | 评论 (0)编辑 收藏

转载:Linux内存管理(上)

     摘要: http://blog.csdn.net/kanghua/archive/2007/10/22/1837876.aspx http://blog.csdn.net/kanghua/archive/2007/10/22/1837872.aspx 摘要:本章首先以应用程序开发者的角度审视Linux的进程内存管理,在此基础上逐步深入到内核中讨论系统物理内存管理和内核内存地使用方法。力求从外自内、...  阅读全文

posted @ 2009-03-17 17:21 Picasso 阅读(1024) | 评论 (0)编辑 收藏

Linux 关于动态链接库以及静态链接库的一些概念

From http://os.rdxx.com/Linux/LinuxRudiment/2008/5/17017197011.shtml

库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀。例如:libhello.so libhello.a
为了在同一系统中使用不同版本的库,可以在库文件名后加上版本号为后缀,例如: libhello.so.1.0,由于程序连接默认以.so为文件后缀名。所以为了使用这些库,通常使用建立符号连接的方式。
ln -s libhello.so.1.0 libhello.so.1
ln -s libhello.so.1 libhello.so
使用库
当 要使用静态的程序库时,连接器会找出程序所需的函数,然后将它们拷贝到执行文件,由于这种拷贝是完整的,所以一旦连接成功,静态程序库也就不再需要了。然 而,对动态库而言,就不是这样。动态库会在执行程序内留下一个标记‘指明当程序执行时,首先必须载入这个库。由于动态库节省空间,linux下进行连接的 缺省操作是首先连接动态库,也就是说,如果同时存在静态和动态库,不特别指定的话,将与动态库相连接。
现在假设有一个叫hello的程序开发包,它提供一个静态库libhello.a 一个动态库libhello.so,一个头文件hello.h,头文件中提供sayhello()这个函数
/* hello.h */
void sayhello();
另外还有一些说明文档。这一个典型的程序开发包结构
1.与动态库连接
linux默认的就是与动态库连接,下面这段程序testlib.c使用hello库中的sayhello()函数
/*testlib.c*/
#include  
#include  
int main()
{
sayhello();
return 0;
}
使用如下命令进行编译
$gcc -c testlib.c -o testlib.o
用如下命令连接:
$gcc testlib.o -lhello -o testlib
在连接时要注意,假设libhello.o 和libhello.a都在缺省的库搜索路径下/usr/lib下,如果在其它位置要加上-L参数
与与静态库连接麻烦一些,主要是参数问题。还是上面的例子:
$gcc testlib.o -o testlib -WI,-Bstatic -lhello
注:这个特别的"-WI,-Bstatic"参数,实际上是传给了连接器ld.
指示它与静态库连接,如果系统中只有静态库当然就不需要这个参数了。
如果要和多个库相连接,而每个库的连接方式不一样,比如上面的程序既要和libhello进行静态连接,又要和libbye进行动态连接,其命令应为:
$gcc testlib.o -o testlib -WI,-Bstatic -lhello -WI,-Bdynamic -lbye
3.动态库的路径问题
为了让执行程序顺利找到动态库,有三种方法:
(1)把库拷贝到/usr/lib和/lib目录下。
(2)在LD_LIBRARY_PATH环境变量中加上库所在路径。例如动态库libhello.so在/home/ting/lib目录下,以bash为例,使用命令:
$export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/ting/lib
(3) 修改/etc/ld.so.conf文件,把库所在的路径加到文件末尾,并执行ldconfig刷新。这样,加入的目录下的所有库文件都可见、
4.查看库中的符号
有 时候可能需要查看一个库中到底有哪些函数,nm命令可以打印出库中的涉及到的所有符号。库既可以是静态的也可以是动态的。nm列出的符号有很多,常见的有 三种,一种是在库中被调用,但并没有在库中定义(表明需要其他库支持),用U表示;一种是库中定义的函数,用T表示,这是最常见的;另外一种是所谓的“弱 态”符号,它们虽然在库中被定义,但是可能被其他库中的同名符号覆盖,用W表示。例如,假设开发者希望知道上央提到的hello库中是否定义了 printf():
$nm libhello.so |grep printf
U printf
U表示符号printf被引用,但是并没有在函数内定义,由此可以推断,要正常使用hello库,必须有其它库支持,再使用ldd命令查看hello依赖于哪些库:
$ldd hello
libc.so.6=>/lib/libc.so.6(0x400la000)
/lib/ld-linux.so.2=>/lib/ld-linux.so.2 (0x40000000)
从上面的结果可以继续查看printf最终在哪里被定义,有兴趣可以go on
生成库
第一步要把源代码编绎成目标代码。以下面的代码为例,生成上面用到的hello库:

/* hello.c */
#include  
void sayhello()
{
printf("hello,world\n");
}
用gcc编绎该文件,在编绎时可以使用任何全法的编绎参数,例如-g加入调试代码等:
gcc -c hello.c -o hello.o
1.连接成静态库
连接成静态库使用ar命令,其实ar是archive的意思
$ar cqs libhello.a hello.o
2.连接成动态库
生成动态库用gcc来完成,由于可能存在多个版本,因此通常指定版本号:
$gcc -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0 hello.o
另外再建立两个符号连接:
$ln -s libhello.so.1.0 libhello.so.1
$ln -s libhello.so.1 libhello.so
这样一个libhello的动态连接库就生成了。最重要的是传gcc -shared 参数使其生成是动态库而不是普通执行程序。
-Wl 表示后面的参数也就是-soname,libhello.so.1直接传给连接器ld进行处理。实际上,每一个库都有一个soname,当连接器发现它正 在查找的程序库中有这样一个名称,连接器便会将soname嵌入连结中的二进制文件内,而不是它正在运行的实际文件名,在程序执行期间,程序会查找拥有 soname名字的文件,而不是库的文件名,换句话说,soname是库的区分标志。
这样做的目的主要是允许系统中多个版本的库文件共存,习惯上在命名库文件的时候通常与soname相同
libxxxx.so.major.minor
其中,xxxx是库的名字,major是主版本号,minor 是次版本号



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

摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Linux系统中都有动态库的概念,采用动态库可以有效的减少程序大小,节省空间,提高效率,增加程序的可扩展性,便于模块化管理。但不同操作系统的动态库由于格式 不同,在需要不同操作系统调用时需要进行动态库程序移植。本文分析和比较了两种操作系统动态库技术,并给出了将Visual C++编制的动态库移植到Linux上的方法和经验。
  
  1、引言
  
  动态库(Dynamic Link Library abbr,DLL)技术是程序设计中经常采用的技术。其目的减少程序的大小,节省空间,提高效率,具有很高的灵活性。采用动态库技术对于升级软件版本更加容易。与静态库(Static Link Library)不同,动态库里面的函数不是执行程序本身的一部分,而是根据执行需要按需载入,其执行代码可以同时在多个程序中共享。
  
  在Windows和Linux操作系统中,都可采用这种方式进行软件设计,但他们的调用方式以及程序编制方式不尽相同。本文首先分析了在这两种操作系统中通常采用的动态库调用方法以及程序编制方式,然后分析比较了这两种方式的不同之处,最后根据实际移植程序经验,介绍了将VC++编制的Windows动态库移植到Linux下的方法。
  
  2、动态库技术
  
  2.1 Windows动态库技术
  
  动态链接库是实现Windows应用程序共享资源、节省内存空间、提高使用效率的一个重要技术手段。常见的动态库包含外部函数和资源,也有一些动态库只包含资源,如Windows字体资源文件,称之为资源动态链接库。通常动态库以.dll,.drv、.fon等作为后缀。相应的windows静态库通常以.lib结尾,Windows自己就将一些主要的系统功能以动态库模块的形式实现。
  
  Windows动态库在运行时被系统加载到进程的虚拟空间中,使用从调用进程的虚拟地址空间分配的内存,成为调用进程的一部分。DLL也只能被该进程的线程所访问。DLL的句柄可以被调用进程使用;调用进程的句柄可以被DLL使用。DLL模块中包含各种导出函数,用于向外界提供服务。DLL可以有自己的数据段,但没有自己的堆栈,使用与调用它的应用程序相同的堆栈模式;一个DLL在内存中只有一个实例;DLL实现了代码封装性;DLL的编制与具体的编程语言及编译器无关,可以通过DLL来实现混合语言编程。DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。
  
  根据调用方式的不同,对动态库的调用可分为静态调用方式和动态调用方式。
  
  (1)静态调用,也称为隐式调用,由编译系统完成对DLL的加载和应用程序结束时DLL卸载的编码(Windows系统负责对DLL调用次数的计数),调用方式简单,能够满足通常的要求。通常采用的调用方式是把产生动态连接库时产生的.LIB文件加入到应用程序的工程中,想使用DLL中的函数时,只须在源文件中声明一下。 LIB文件包含了每一个DLL导出函数的符号名和可选择的标识号以及DLL文件名,不含有实际的代码。Lib文件包含的信息进入到生成的应用程序中,被调用的DLL文件会在应用程序加载时同时加载在到内存中。
  
  (2)动态调用,即显式调用方式,是由编程者用API函数加载和卸载DLL来达到调用DLL的目的,比较复杂,但能更加有效地使用内存,是编制大型应用程序时的重要方式。在Windows系统中,与动态库调用有关的函数包括:
  
  ①LoadLibrary(或MFC 的AfxLoadLibrary),装载动态库。
  ②GetProcAddress,获取要引入的函数,将符号名或标识号转换为DLL内部地址。
  ③FreeLibrary(或MFC的AfxFreeLibrary),释放动态链接库。
  
  在windows中创建动态库也非常方便和简单。在Visual C++中,可以创建不用MFC而直接用C语言写的DLL程序,也可以创建基于MFC类库的DLL程序。每一个DLL必须有一个入口点,在VC++中,DllMain是一个缺省的入口函数。DllMain负责初始化(Initialization)和结束(Termination)工作。动态库输出函数也有两种约定,分别是基于调用约定和名字修饰约定。DLL程序定义的函数分为内部函数和导出函数,动态库导出的函数供其它程序模块调用。通常可以有下面几种方法导出函数:
  
  ①采用模块定义文件的EXPORT部分指定要输入的函数或者变量。
  ②使用MFC提供的修饰符号_declspec(dllexport)。
  ③以命令行方式,采用/EXPORT命令行输出有关函数。
  
  在windows动态库中,有时需要编写模块定义文件(.DEF),它是用于描述DLL属性的模块语句组成的文本文件。
  
  2.2 Linux共享对象技术
  
  在Linux操作系统中,采用了很多共享对象技术(Shared Object),虽然它和Windows里的动态库相对应,但它并不称为动态库。相应的共享对象文件以.so作为后缀,为了方便,在本文中,对该概念不进行专门区分。Linux系统的/lib以及标准图形界面的/usr/X11R6/lib等目录里面,就有许多以so结尾的共享对象。同样,在Linux下,也有静态函数库这种调用方式,相应的后缀以.a结束。Linux采用该共享对象技术以方便程序间共享,节省程序占有空间,增加程序的可扩展性和灵活性。Linux还可以通过LD-PRELOAD变量让开发人员可以使用自己的程序库中的模块来替换系统模块。
  
  同Windows系统一样,在Linux中创建和使用动态库是比较容易的事情,在编译函数库源程序时加上-shared选项即可,这样所生成的执行程序就是动态链接库。通常这样的程序以so为后缀,在Linux动态库程序设计过程中,通常流程是编写用户的接口文件,通常是.h文件,编写实际的函数文件,以.c或.cpp为后缀,再编写makefile文件。对于较小的动态库程序可以不用如此,但这样设计使程序更加合理。
  
  编译生成动态连接库后,进而可以在程序中进行调用。在Linux中,可以采用多种调用方式,同Windows的系统目录(..\system32等)一样,可以将动态库文件拷贝到/lib目录或者在/lib目录里面建立符号连接,以便所有用户使用。下面介绍Linux调用动态库经常使用的函数,但在使用动态库时,源程序必须包含dlfcn.h头文件,该文件定义调用动态链接库的函数的原型。
  
  (1)_打开动态链接库:dlopen,函数原型void *dlopen (const char *filename, int flag);
  dlopen用于打开指定名字(filename)的动态链接库,并返回操作句柄。
  
  (2)取函数执行地址:dlsym,函数原型为: void *dlsym(void *handle, char *symbol);
  dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的函数的执行代码地址。
  
  (3)关闭动态链接库:dlclose,函数原型为: int dlclose (void *handle);
  dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。
  
  (4)动态库错误函数:dlerror,函数原型为: const char *dlerror(void); 当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。
  
  在取到函数执行地址后,就可以在动态库的使用程序里面根据动态库提供的函数接口声明调用动态库里面的函数。在编写调用动态库的程序的makefile文件时,需要加入编译选项-rdynamic和-ldl。
  
  除了采用这种方式编写和调用动态库之外,Linux操作系统也提供了一种更为方便的动态库调用方式,也方便了其它程序调用,这种方式与Windows系统的隐式链接类似。其动态库命名方式为“lib*.so.*”。在这个命名方式中,第一个*表示动态链接库的库名,第二个*通常表示该动态库的版本号,也可以没有版本号。在这种调用方式中,需要维护动态链接库的配置文件/etc/ld.so.conf来让动态链接库为系统所使用,通常将动态链接库所在目录名追加到动态链接库配置文件中。如具有X window窗口系统发行版该文件中都具有/usr/X11R6/lib,它指向X window窗口系统的动态链接库所在目录。为了使动态链接库能为系统所共享,还需运行动态链接库的管理命令./sbin/ldconfig。在编译所引用的动态库时,可以在gcc采用 ?l或-L选项或直接引用所需的动态链接库方式进行编译。在Linux里面,可以采用ldd命令来检查程序依赖共享库。
  
  3、两种系统动态库比较分析
  
  Windows和Linux采用动态链接库技术目的是基本一致的,但由于操作系统的不同,他们在许多方面还是不尽相同,下面从以下几个方面进行阐述。
  
  (1)动态库程序编写,在Windows系统下的执行文件格式是PE格式,动态库需要一个DllMain函数作为初始化的人口,通常在导出函数的声明时需要有_declspec(dllexport)关键字。Linux下的gcc编译的执行文件默认是ELF格式,不需要初始化入口,亦不需要到函数做特别声明,编写比较方便。
  
  (2)动态库编译,在windows系统下面,有方便的调试编译环境,通常不用自己去编写makefile文件,但在linux下面,需要自己动手去编写makefile文件,因此,必须掌握一定的makefile编写技巧,另外,通常Linux编译规则相对严格。
  
  (3)动态库调用方面,Windows和Linux对其下编制的动态库都可以采用显式调用或隐式调用,但具体的调用方式也不尽相同。
  
  (4)动态库输出函数查看,在Windows中,有许多工具和软件可以进行查看DLL中所输出的函数,例如命令行方式的dumpbin以及VC++工具中的DEPENDS程序。在Linux系统中通常采用nm来查看输出函数,也可以使用ldd查看程序隐式链接的共享对象文件。
  
  (5)对操作系统的依赖,这两种动态库运行依赖于各自的操作系统,不能跨平台使用。因此,对于实现相同功能的动态库,必须为两种不同的操作系统提供不同的动态库版本。
  
  4、动态库移植方法
  
  如果要编制在两个系统中都能使用的动态链接库,通常会先选择在Windows的VC++提供的调试环境中完成初始的开发,毕



posted @ 2009-01-21 15:56 Picasso 阅读(14910) | 评论 (0)编辑 收藏

转贴:ORA-01034 ORA-27121 错误

ORA-01034: ORACLE not available
ORA-27121: unable to determine size of shared memory segment
Linux Error: 13: Permission denied

主要是因为oracle安装程序没有给oracle这个可执行程序设置正确的setuid。这样设置一下:

$ cd $ORACLE_HOME/bin
$ chmod 6751 oracle

结果类似这样就行了。

$ ls -l $ORACLE_HOME/bin/oracle
-rwsr-s--x 1 oracle oinstall 23352783 Aug 14 2001 /home/oracle/app/oracle/product/8.1.6/bin/oracle


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

ORA-01034 ORA-27121 13: Permission denied

ORA-01034

ORA-27121

Error: 13: Permission denied

双实例 两个实例

日月明王      http://sunmoonking.spaces.live.com

环境               
HP-UX jmc080 B.11.11 U 9000/800 1805586595 unlimited-user license
 
SQL*Plus: Release 9.2.0.1.0 - Production on Mon Oct 16 16:48:45 2006
Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.1.0 - 64bit Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.1.0 – Production
装两个数据库db1db2,分别有两个用户db1userdb2user,分别属于ORADBA1,ORADBA2,共同属于oragroup安装组。装好两个库后出现如下错误
现象
SQL> connect db2user/db2user@db2
ERROR:
ORA-01034: ORACLE not available
ORA-27121: unable to determine size of shared memory segment
HP-UX Error: 13: Permission denied
此时
$ ls -alt $ORACLE_HOME/bin/oracle
 
 Warning! One or more of your selected locales are not available.
 Please invoke the commands "locale" and "locale -a" to verify your
 selections and the available locales.
 
 Continuing processing using the "C" locale.
 
-rwsrwsrwx   1 oracle1    oragroup   77765688 Sep  7 16:00 /usr/sap3/oracle/product/920/bin/oracle    (原权限是6751
如果把/usr/sap3/oracle/product/920/bin/oracle的所有者改成oracle2则可以启动DB2,但是DB1却出现同样错误,无法连接。于是判断是某个文件的权限不对。于是一步一步检查。
看谁拥有内存
$ ipcs -a
IPC status from /dev/kmem as of Mon Oct 16 18:05:13 2006
T         ID     KEY        MODE        OWNER     GROUP   CREATOR    CGROUP CBYTES  QNUM QBYTES LSPID LRPID   STIME    RTIME    CTIME
Message Queues:
q          0 0x3c200731 -Rrw--w--w-      root      root      root      root     0     0  65535     0     0 no-entry no-entry 19:46:07
q          1 0x3e200731 --rw-r--r--      root      root      root      root     0     0    264     0     0 no-entry no-entry 19:46:07
T         ID     KEY        MODE        OWNER     GROUP   CREATOR    CGROUP NATTCH      SEGSZ  CPID  LPID   ATIME    DTIME    CTIME
Shared Memory:
m          0 0x412007a8 --rw-rw-rw-      root      root      root      root      0        348   607   607 19:46:17 19:46:17 19:46:11
m          1 0x4e0c0002 --rw-rw-rw-      root      root      root      root      1      61760   607   607 19:46:13 19:46:17 19:46:11
m          2 0x411809a4 --rw-rw-rw-      root      root      root      root      1       8192   607   619 19:46:13 19:46:11 19:46:11
m          3 0x30203ebc --rw-rw-rw-      root      root      root      root      2    1048576  1282  1302 19:49:19 no-entry 19:48:40
m      17412 0x5e14045d --rw-------      root      root      root      root      1        512  1667  1667 19:49:13 no-entry 19:49:13
m     312325 0x7bf2fe68 --rw-------   oracle1     users   oracle1     users     13  873955328 20914 22016 18:04:49 18:04:49 16:22:30
m       4102 0x36ba48e8 --rw-rw----   oracle2     users   oracle2     users     14  706183168 21014 21991 18:03:37 18:03:37 16:26:16
T         ID     KEY        MODE        OWNER     GROUP   CREATOR    CGROUP NSEMS   OTIME    CTIME
Semaphores:
s          0 0x412007a8 --ra-ra-ra-      root      root      root      root     1 19:46:17 19:46:11
s          1 0x4e0c0002 --ra-ra-ra-      root      root      root      root     2 19:46:13 19:46:11
s          2 0x411809a4 --ra-ra-ra-      root      root      root      root     2 no-entry 19:46:11
s          3 0x00446f6e --ra-r--r--      root      root      root      root     1 no-entry 19:46:50
s          4 0x00446f6d --ra-r--r--      root      root      root      root     1 no-entry 19:46:50
s          5 0x01090522 --ra-r--r--      root      root      root      root     1 no-entry 19:47:09
s          6 0x41207339 --ra-ra-ra-      root      root      root      root     1 19:48:35 19:48:35
s          7 0x31203ebc --ra-ra-ra-      root      root      root      root     1 19:49:19 19:48:40
s          8 0x611804f5 --ra-ra-ra-      root      root      root      root     1 19:53:03 19:49:04
s          9 0x731804f5 --ra-ra-ra-      root      root      root      root     1 19:59:47 19:49:04
s         10 0x701804f5 --ra-ra-ra-      root      root      root      root     1 19:53:43 19:49:04
s         11 0x691804f5 --ra-ra-ra-      root      root      root      root     1 19:53:01 19:49:04
s         12 0x751804f5 --ra-ra-ra-      root      root      root      root     1 19:49:04 19:49:04
s         13 0x631804f5 --ra-ra-ra-      root      root      root      root     1 19:49:04 19:49:04
s         14 0x641804f5 --ra-ra-ra-      root      root      root      root     1 19:53:04 19:49:04
s         15 0x661804f5 --ra-ra-ra-      root      root      root      root     1 no-entry 19:49:04
s         16 0x6c1804f5 --ra-ra-ra-      root      root      root      root     1 19:53:03 19:49:04
s         17 0x6d1804f5 --ra-ra-ra-      root      root      root      root     1 19:59:47 19:49:04
s         18 0x6f1804f5 --ra-ra-ra-      root      root      root      root     1 no-entry 19:49:04
s         19 0x410c01e0 --ra-ra-ra-      root      root      root      root     1 19:49:09 19:49:09
s         20 0x00000001 --ra-ra-ra-      root      root      root      root     1 19:49:49 19:49:13
s         21 0x4528e5bf --ra-ra-ra-      root      root      root      root     1 no-entry 19:49:19
s         22 0x4528e5c0 --ra-ra-ra-      root      root      root      root     1 19:49:19 19:49:19
s         23 0x521804f5 --ra-ra-ra-      root      root      root      root     1 19:59:47 19:53:04
s     182624 0xfc6c0898 --ra-------   oracle1     users   oracle1     users   154 18:05:06 16:22:32
s      49825 0xa01e08b0 --ra-ra----   oracle2     users   oracle2     users   154 18:04:44 16:26:17
没看出什么明显问题。
首先设置UMAKS 000
在设置/var/opt/oracle/oratab
DB1:/usr/sap3/oracle/product/920:Y
DB2:/usr/sap3/oracle/product/920:Y 
chown -R oracle1:oragroup $ORACLE_BASE
chmod -R 777 $ORACLE_BASE
chmod 6777 $ORACLE_HOME/bin/oracle

posted @ 2009-01-11 14:55 Picasso 阅读(2311) | 评论 (0)编辑 收藏

转贴: 让进程在后台可靠运行的几种方法

让进程在后台可靠运行的几种方法

想让进程在断开连接后依然保持运行?如果该进程已经开始运行了该如何补救? 如果有大量这类需求如何简化操作?

    我们经常会碰到这样的问题,用 telnet/ssh 登录了远程的 Linux 服务器,运行了一些耗时较长的任务, 结果却由于网络的不稳定导致任务中途失败。如何让命令提交后不受本地关闭终端窗口/网络断开连接的干扰呢?下面举了一些例子, 您可以针对不同的场景选择不同的方式来处理这个问题。

    nohup/setsid/&

    场景:

    如果只是临时有一个命令需要长时间运行,什么方法能最简便的保证它在后台稳定运行呢?

    解决方法:

    我们知道,当用户注销(logout)或者网络断开时,终端会收到 HUP(hangup)信号从而关闭其所有子进程。因此,我们的解决办法就有两种途径:要么让进程忽略 HUP 信号,要么让进程运行在新的会话里从而成为不属于此终端的子进程。

    1. nohup

    nohup 无疑是我们首先想到的办法。顾名思义,nohup 的用途就是让提交的命令忽略 hangup(在 Unix 的早期版本中,每个终端都会通过 modem 和系统通讯。当用户 logout 时,modem 就会挂断(hang up)电话。 同理,当 modem 断开连接时,就会给终端发送 hangup 信号来通知其关闭所有子进程。) 信号。让我们先来看一下 nohup 的帮助信息
NOHUP(1)                        User Commands                        NOHUP(1)

NAME
       nohup - run a command immune to hangups, with output to a non-tty

SYNOPSIS
       nohup COMMAND [ARG]...
       nohup OPTION

DESCRIPTION
       Run COMMAND, ignoring hangup signals.

       --help display this help and exit

       --version
              output version information and exit 


    可见,nohup 的使用是十分方便的,只需在要处理的命令前加上 nohup 即可,标准输出和标准错误缺省会被重定向到 nohup.out 文件中。一般我们可在结尾加上"&"来将命令同时放入后台运行,也可用">filename 2>&1"来更改缺省的重定向文件名。

    nohup 示例

   [root@pvcent107 ~]# nohup ping www.ibm.com &
[1] 3059
nohup: appending output to `nohup.out'
[root@pvcent107 ~]# ps -ef |grep 3059
root      3059   984  0 21:06 pts/3    00:00:00 ping www.ibm.com
root      3067   984  0 21:06 pts/3    00:00:00 grep 3059
[root@pvcent107 ~]#


    2。setsid

    nohup 无疑能通过忽略 HUP 信号来使我们的进程避免中途被中断,但如果我们换个角度思考,如果我们的进程不属于接受 HUP 信号的终端的子进程,那么自然也就不会受到 HUP 信号的影响了。setsid 就能帮助我们做到这一点。让我们先来看一下 setsid 的帮助信息:

    
SETSID(8) Linux Programmer’s Manual SETSID(8) NAME setsid - run a program in a new session SYNOPSIS setsid program [ arg ... ] DESCRIPTION setsid runs a program in a new session. 


    可见 setsid 的使用也是非常方便的,也只需在要处理的命令前加上 setsid 即可。

    setsid 示例

 [root@pvcent107 ~]# setsid ping www.ibm.com
[root@pvcent107 ~]# ps -ef |grep www.ibm.com
root     31094     1  0 07:28 ?        00:00:00 ping www.ibm.com
root     31102 29217  0 07:29 pts/4    00:00:00 grep www.ibm.com
[root@pvcent107 ~]#   


    值得注意的是,上例中我们的进程 ID(PID)为31094,而它的父 ID(PPID)为1(即为 init 进程 ID),并不是当前终端的进程 ID。请将此例与nohup 例中的父 ID 做比较。

    3。&
    这里还有一个关于 subshell 的小技巧。我们知道,将一个或多个命名包含在“()”中就能让这些命令在子 shell 中运行中,从而扩展出很多有趣的功能,我们现在要讨论的就是其中之一。

    当我们将"&"也放入“()”内之后,我们就会发现所提交的作业并不在作业列表中,也就是说,是无法通过jobs来查看的。让我们来看看为什么这样就能躲过 HUP 信号的影响吧。

    subshell 示例

     [root@pvcent107 ~]# (ping www.ibm.com &)
[root@pvcent107 ~]# ps -ef |grep www.ibm.com
root     16270     1  0 14:13 pts/4    00:00:00 ping www.ibm.com
root     16278 15362  0 14:13 pts/4    00:00:00 grep www.ibm.com
[root@pvcent107 ~]#   


    从上例中可以看出,新提交的进程的父 ID(PPID)为1(init 进程的 PID),并不是当前终端的进程 ID。因此并不属于当前终端的子进程,从而也就不会受到当前终端的 HUP 信号的影响了
screen

    场景:

    我们已经知道了如何让进程免受 HUP 信号的影响,但是如果有大量这种命令需要在稳定的后台里运行,如何避免对每条命令都做这样的操作呢?

    解决方法:

    此时最方便的方法就是 screen 了。简单的说,screen 提供了 ANSI/VT100 的终端模拟器,使它能够在一个真实终端下运行多个全屏的伪终端。screen 的参数很多,具有很强大的功能,我们在此仅介绍其常用功能以及简要分析一下为什么使用 screen 能够避免 HUP 信号的影响。我们先看一下 screen 的帮助信息:

     SCREEN(1)                                                           SCREEN(1)

NAME
       screen - screen manager with VT100/ANSI terminal emulation

SYNOPSIS
       screen [ -options ] [ cmd [ args ] ]
       screen -r [[pid.]tty[.host]]
       screen -r sessionowner/[[pid.]tty[.host]]

DESCRIPTION
       Screen  is  a  full-screen  window manager that multiplexes a physical
       terminal between several  processes  (typically  interactive  shells).
       Each  virtual  terminal provides the functions of a DEC VT100 terminal
       and, in addition, several control functions from the  ISO  6429  (ECMA
       48,  ANSI  X3.64)  and ISO 2022 standards (e.g. insert/delete line and
       support for multiple character sets).  There is a  scrollback  history
       buffer  for  each virtual terminal and a copy-and-paste mechanism that
       allows moving text regions between windows.


    使用 screen 很方便,有以下几个常用选项:

    用screen -dmS session name 来建立一个处于断开模式下的会话(并指定其会话名)。
    用screen -list 来列出所有会话。
    用screen -r session name 来重新连接指定会话。
    用快捷键CTRL-a d 来暂时断开当前会话。

    screen 示例

     [root@pvcent107 ~]# screen -dmS Urumchi
[root@pvcent107 ~]# screen -list
There is a screen on:
        12842.Urumchi   (Detached)
1 Socket in /tmp/screens/S-root.

[root@pvcent107 ~]# screen -r Urumchi


    当我们用“-r”连接到 screen 会话后,我们就可以在这个伪终端里面为所欲为,再也不用担心 HUP 信号会对我们的进程造成影响,也不用给每个命令前都加上“nohup”或者“setsid”了。这是为什么呢?让我来看一下下面两个例子吧。

    1. 未使用 screen 时新进程的进程树

     [root@pvcent107 ~]# ping www.google.com &
[1] 9499
[root@pvcent107 ~]# pstree -H 9499
init─┬─Xvnc
     ├─acpid
     ├─atd
     ├─2*[sendmail]
     ├─sshd─┬─sshd───bash───pstree
     │      └─sshd───bash───ping
            


    我们可以看出,未使用 screen 时我们所处的 bash 是 sshd 的子进程,当 ssh 断开连接时,HUP 信号自然会影响到它下面的所有子进程(包括我们新建立的 ping 进程)。

    2. 使用了 screen 后新进程的进程树

     [root@pvcent107 ~]# screen -r Urumchi
[root@pvcent107 ~]# ping www.ibm.com &
[1] 9488
[root@pvcent107 ~]# pstree -H 9488
init─┬─Xvnc
     ├─acpid
     ├─atd
     ├─screen───bash───ping
     ├─2*[sendmail]


    而使用了 screen 后就不同了,此时 bash 是 screen 的子进程,而 screen 是 init(PID为1)的子进程。那么当 ssh 断开连接时,HUP 信号自然不会影响到 screen 下面的子进程了。

    总结

    现在几种方法已经介绍完毕,我们可以根据不同的场景来选择不同的方案。nohup/setsid 无疑是临时需要时最方便的方法,disown 能帮助我们来事后补救当前已经在运行了的作业,而 screen 则是在大批量操作时不二的选择了

posted @ 2009-01-10 13:48 Picasso 阅读(273) | 评论 (0)编辑 收藏

更改Suse 主机名、IP

Q: 在SLES8中如何修改主机名(hostname)
A: SLES8中可以用yast network来修改主机名(hostname),也可以通过修改配置文件的方式并运行命令
实现这个目的

方法1. 通过yast2管理工具进行配置
在console中运行yast2工具修改主机名(hostname)
# yast2 network
对于配置未经配置的网卡
"Network cards configuration"中"Network cards configuration"中“Configure...”
对于修改已配置网卡的设置
"Network cards configuration"中"Network cards configuration"中“Changev...”

“Network address setup”中“Detailed settings”单击“Host name and name server”
在“Host name”输入框中输入主机名,在“Domain name”中数入域名,如果没有域名,接受缺省的
“local”

方法2. 通过修改配置文件的方式并运行命令修改主机名
修改/etc/HOSTNAME文件,在此文件中保存主机名,例如:
linuxserv1

然后运行命令设置主机名
# /etc/rc.d/boot.localnet start

方法3. 运行 sysctl 动态改变主机名
# sysctl -w kernel.hostname=linuxserv1



Q:如何更改网卡配置IP

# vi /etc/sysconfig/network/ifcfg-eth-id-00\:0d\:61\:cd\:31\:f2


BOOTPROTO='static'
BROADCAST=''
ETHTOOL_OPTIONS=''
IPADDR='192.168.1.70'
MTU=''
NAME='Giga-byte GA-7VM400M/7VT600 Motherboard'
NETMASK='255.255.255.0'
NETWORK=''
REMOTE_IPADDR=''
STARTMODE='auto'
UNIQUE='rBUF.0ayJ55PfLqC'
USERCONTROL='no'
_nm_name='bus-pci-0000:01:05.0'

posted @ 2009-01-04 16:20 Picasso 阅读(3073) | 评论 (0)编辑 收藏

AIX 下的 core dump 分析入门

     摘要:   http://www.ibm.com/developerworks/cn/aix/library/0806_chench_core/index.html ...  阅读全文

posted @ 2008-11-10 10:52 Picasso 阅读(1540) | 评论 (0)编辑 收藏

转载:ldconfig几个需要注意的地方

     摘要:   阅读全文

posted @ 2008-10-07 22:24 Picasso 阅读(483) | 评论 (0)编辑 收藏

转载: 用vi 编辑文件时“终端太宽”(Terminal too wide)

    
用vi 编辑文件时“终端太宽”(Terminal too wide)

#stty -a    check you columns setting .
#stty columns 132    may solve it .

posted @ 2008-09-02 09:07 Picasso| 编辑 收藏

转载: root用户ftp-telnet 登陆设置

root用户ftp-telnet 登陆设置

root用户ftp-telnet 登陆设置
--------------------------------------
Linux 精华---root用户ftp/telnet 登陆设置  (笔者原版---共享)
--------------------------------------------------------
笔者以FedCore 4(2.6.11)为蓝本,一般情况下系统默认的 root用户不能远程ftp 和 telnet 服务器.网络上有些更改
远程登陆的文章,笔者还是认为都不够全面,经过自己一个小时的折腾终于解决了.
1),解决root用户 ftp登陆的问题
  一般情况下,由于种种原因ftp是不让root用户远程登陆,但只要你修改以个文件就可以登陆了.
   a ,去掉或注释掉  /etc/vsftpd/ftpusers 中的root
   b ,去掉或注释掉  /etc/vsftpd/user_list  中的root
2),修改ftp的默认的路径
我的硬盘空间有限,如何把帐号ftp默认的路径/var/ftp更改到别处?或者是,我的linux所有的目录都放在/根分区,因为空间紧张,我能否把ftp这个用户的默认路径放到别的分区?
可以,应该如下操作!
首先要把ftp这个用户删除
  #userdel -r ftp
会有错误信息,不过不用理,这是正常的。
然后我们再把这个用户添加上,比如我想为帐号ftp的家目录设置在/mnt/LinG/ftp,我们就可以如下操作
  [root@linuxsir001 root]# mkdir /root/ftp
   [root@linuxsir001 root]# adduser -d /root/ftp -g ftp -s /sbin/nologin ftp
仅仅是这样做还不行,因为这样还是不能让匿名用户找到它的家目录,所以我们必须改变/mnt/LinG/ftp这个目录的权限。
  [root@linuxsir001 root]# chmod 755 /root/ftp/  
    [root@linuxsir001 root]# chown -R root.root /root/ftp/
3),root用户登陆 telnet
  a,检查你的服务器是否安装 telnet 服务器
   rpm -qa | grep  telnet-server[root@fedorasvr tmp]# ls
   telnet-server-0.17-35.i386.rpm
[root@fedorasvr tmp]# rpm -i telnet-server-0.17-35.i386.rpm
warning: telnet-server-0.17-35.i386.rpm: Header V3 DSA signature: NOKEY, key ID 4f2a6fd2
error: Failed dependencies:
xinetd is needed by telnet-server-0.17-35.i386
-------------哦是什么出错了呢?????
检查,检查可能是没有安装 xinetd ,因为linux的安装包依赖性可能强,好安装一下了,在安1.rpm -ivh xinetd-2.3.13-6.i386.rpm
2.service xinetd start
3.rpm-ivh telnet-server-0.17-35.i386.rpm
4.chkconfig telnet on
装telnet-server 等
测试 telnet 服务器已经安装好了,
   b),开启root用户的telnet功能
    1,编辑/etc/default/login文件.
        添加内容:CONSOLE=/dev/console
        2,编辑/etc/securetty   文件,加上下面几行:   
    pts/0   
        pts/1   
        pts/2   
        pts/3
           测试root用户直接telnet登陆成功,
      特别提示:对了最好不要使用root用户telnet 登陆,也不要使用telnet功能,因为它太不安全了,最好使用 ssh2登陆.
----------------------------------------------------
Linux 精华---root用户ftp/telnet 登陆设置  (笔者原版---共享)
--------------------------------------------------------
笔者以FedCore 4(2.6.11)为蓝本,一般情况下系统默认的 root用户不能远程ftp 和 telnet 服务器.网络上有些更改
远程登陆的文章,笔者还是认为都不够全面,经过自己一个小时的折腾终于解决了.
1),解决root用户 ftp登陆的问题
  一般情况下,由于种种原因ftp是不让root用户远程登陆,但只要你修改以个文件就可以登陆了.
   a ,去掉或注释掉  /etc/vsftpd/ftpusers 中的root
   b ,去掉或注释掉  /etc/vsftpd/user_list  中的root
2),修改ftp的默认的路径
我的硬盘空间有限,如何把帐号ftp默认的路径/var/ftp更改到别处?或者是,我的linux所有的目录都放在/根分区,因为空间紧张,我能否把ftp这个用户的默认路径放到别的分区?
可以,应该如下操作!
首先要把ftp这个用户删除
  #userdel -r ftp
会有错误信息,不过不用理,这是正常的。
然后我们再把这个用户添加上,比如我想为帐号ftp的家目录设置在/mnt/LinG/ftp,我们就可以如下操作
  [root@linuxsir001 root]# mkdir /root/ftp
   [root@linuxsir001 root]# adduser -d /root/ftp -g ftp -s /sbin/nologin ftp
仅仅是这样做还不行,因为这样还是不能让匿名用户找到它的家目录,所以我们必须改变/mnt/LinG/ftp这个目录的权限。
  [root@linuxsir001 root]# chmod 755 /root/ftp/  
    [root@linuxsir001 root]# chown -R root.root /root/ftp/
3),root用户登陆 telnet
  a,检查你的服务器是否安装 telnet 服务器
   rpm -qa | grep  telnet-server[root@fedorasvr tmp]# ls
   telnet-server-0.17-35.i386.rpm
[root@fedorasvr tmp]# rpm -i telnet-server-0.17-35.i386.rpm
warning: telnet-server-0.17-35.i386.rpm: Header V3 DSA signature: NOKEY, key ID 4f2a6fd2
error: Failed dependencies:
xinetd is needed by telnet-server-0.17-35.i386
-------------哦是什么出错了呢?????
检查,检查可能是没有安装 xinetd ,因为linux的安装包依赖性可能强,好安装一下了,在安1.rpm -ivh xinetd-2.3.13-6.i386.rpm
2.service xinetd start
3.rpm-ivh telnet-server-0.17-35.i386.rpm
4.chkconfig telnet on
装telnet-server 等
测试 telnet 服务器已经安装好了,
   b),开启root用户的telnet功能
    1,编辑/etc/default/login文件.
        添加内容:CONSOLE=/dev/console
        2,编辑/etc/securetty   文件,加上下面几行:   
    pts/0   
        pts/1   
        pts/2   
        pts/3
           测试root用户直接telnet登陆成功,
      特别提示:对了最好不要使用root用户telnet 登陆,也不要使用telnet功能,因为它太不安全了,最好使用 ssh2登陆.
----------------------------------------------------

posted @ 2008-09-01 20:22 Picasso| 编辑 收藏

Solaris NIS NFS 配置

一.NFS Server设置:

    启动NFS Server服务:
# /etc/rc3.d/S15nfs.server start

    Share目录:
       编辑文件/etc/dfs/dfstab:
share -F nfs -o rw=10.0.0.13,root=10.0.0.13 /home
       然后运行shareall将目录share出去,或者不编辑该文件,直接在命令行输入效果一样.

        查看是否成功share"
       # dfshares
RESOURCE                                  SERVER ACCESS    TRANSPORT
   solaris:/home                         solaris  -         -


二.NIS设置:

    复制配置文件:
# cp /etc/nsswitch.nis /etc/nsswitch.conf

    设置域名:
# domainname congli
# echo congli > /etc/defaultdomain

    初始化及启动服务:
# ypinit -m
# /usr/lib/netsvc/yp/ypstart


客户端(Solaris 9)

一.NFS Client设置: 

    启动NFS Client服务:
# /etc/rc2.d/S73nfs.client start

    编辑/etc/vfstab:
10.0.0.12:/home - /home nfs - yes soft,bg

    把NFS文件系统挂上:
# mountall -r


二.NIS设置:

    复制配置文件:
# cp /etc/nsswitch.nis /etc/nsswitch.conf

    设置域名:
# domainname congli
# echo congli > /etc/defaultdomain

    把NIS服务端的IP加到/etc/hosts:
10.0.0.12       solaris

    初始化及启动服务:
# ypinit -m    (填上NIS服务端的hostname,Ctrl+D结束)
# /usr/lib/netsvc/yp/ypstart

posted @ 2008-09-01 20:18 Picasso| 编辑 收藏

Unix Basic

     摘要: 1 UNIX起源、流派及标准 1.1 UNIX的发展简史 60年代由麻省理工学院、通用电器公司、AT&T贝尔试验室组成一个专家小组,研制一个MULICS,是一个灵活的交互式操作系统。 60年后期,BELL脱离该组织,失去了灵活的交互式操作系统。 1990年,有一个叫Ken.Tompson写了一个SPACE TRAVEL的游戏,是在PDP-7上写的,为了更有效地发挥PDP-7的强大功...  阅读全文

posted @ 2008-06-25 15:24 Picasso 阅读(513) | 评论 (0)编辑 收藏

Unix Basic

     摘要: 1 UNIX起源、流派及标准 1.1 UNIX的发展简史 60年代由麻省理工学院、通用电器公司、AT&T贝尔试验室组成一个专家小组,研制一个MULICS,是一个灵活的交互式操作系统。 60年后期,BELL脱离该组织,失去了灵活的交互式操作系统。 1990年,有一个叫Ken.Tompson写了一个SPACE TRAVEL的游戏,是在PDP-7上写的,为了更有效地发挥PDP-7的强大功...  阅读全文

posted @ 2008-06-25 15:18 Picasso 阅读(240) | 评论 (0)编辑 收藏

STL 的排序算法差异

http://blog.csdn.net/taodm/archive/2003/04/16/15756.aspx

posted @ 2008-01-09 15:12 Picasso 阅读(194) | 评论 (0)编辑 收藏

VMWare Workstation、GSX Server、ESX Server有什么区别?

http://keith.ecjtu.com/article.asp?id=657

总结的比较全,但对esx snapshot的功能说得不对, esx server 支持多级snapshots,应该是权限受到了控制的原因.

posted @ 2008-01-02 16:35 Picasso 阅读(2071) | 评论 (1)编辑 收藏

Technical Area for new GUI design related

ASP.net
WCF
Flex
Siverlight

Web Service
WPF

posted @ 2007-10-17 16:34 Picasso 阅读(354) | 评论 (2)编辑 收藏

使用 VMware ESX Server 在 Linux 虚拟机上安装 DB2 Enterprise 9

posted @ 2007-10-10 15:57 Picasso 阅读(194) | 评论 (0)编辑 收藏

SAS硬盘

 不知不觉已经进入06年,业界在数年前就已经提出的SAS(Serial Attached SCSI)硬盘规格也早已有成品上市,但是SAS的推广时机在05年还不够成熟,存储设备提供商也只是推出几款产品作为先头部队,SAS硬盘的大规模普及还要看06年,根据国外相关市场预测机构的估计,在今年,SAS硬盘将会抢占SCSI市场的三分之一,这个数目确实不小,而且这种新的硬盘设计规格也拥有更多的优势,我们相信在06年,SAS硬盘一定会在中高端市场有所作为。因此,今天我们就来谈谈SAS技术和SAS硬盘。

  存储设备的分类

  网络存储设备目前大致可分为3类,即高端、中端和近端(Near-Line)。高端存储设备主要是光纤通道,应用于任务级的关键数据的大容量实时存储。中端存储设备主要是SCSI,应用于商业级的关键数据的大容量存储。近端是近年来新出现的存储领域,其产品主要是串行ATA(Serial ATA,缩写为SATA),应用于非关键数据的大容量存储,目的是替代以前使用磁带的数据备份。由于SATA的硬盘价格越来越低,容量越来越大,可以用于数据备份。用硬盘作数据备份还有一个优点,就是携带和存储方便。传统的企业级存储由于考虑到性能和稳定性,以SCSI硬盘和光纤通道为主要存储平台,ATA则多用于非关键性资料或桌面个人计算机上,不过SATA的兴起正逐渐改变企业存储的形式。

  前迈拓公司全球服务器产品部门营销总监Brendan Collins表示,SAS技术将大幅改变企业内部存储结构,并在若干年后成为存储设备的主要标准。由于成本的降低和性能的提高,基于SAS技术的硬盘将取代SCSI硬盘甚至光纤通道,成为未来企业存储系统或服务器硬盘的主流。

  什么是SAS

  SAS是新一代的SCSI技术,和现在流行的Serial ATA(SATA)硬盘相同,都是采用串行技术以获得更高的传输速度,并通过缩短连结线改善内部空间等。SAS是并行SCSI接口之后开发出的全新接口。此接口的设计是为了改善存储系统的效能、可用性和扩充性,提供与串行ATA (Serial ATA,缩写为SATA)硬盘的兼容性。

  SAS的接口技术可以向下兼容SATA。SAS系统的背板(Backplane)既可以连接具有双端口、高性能的SAS驱动器,也可以连接高容量、低成本的SATA驱动器。因为SAS驱动器的端口与SATA驱动器的端口形状看上去类似,所以SAS驱动器和SATA驱动器可以同时存在于一个存储系统之中。但需要注意的是,SATA系统并不兼容SAS,所以SAS驱动器不能连接到SATA背板上。由于SAS系统的兼容性,IT人员能够运用不同接口的硬盘来满足各类应用在容量上或效能上的需求,因此在扩充存储系统时拥有更多的弹性,让存储设备发挥最大的投资效益。

  SAS技术还有简化内部连接设计的优势,存储设备厂商目前投入相当多的成本以支持包括光纤通道阵列、SATA阵列等不同的存储设备,而SAS连接技术将可以通过共用组件降低设计成本。

  SAS的特点

  串行SCSI是点到点的结构,可以建立磁盘到控制器的直接连接。具有以下特点:

  1、更好的性能:

  点到点的技术减少了地址冲突以及菊花链连结的减速;
  为每个设备提供了专用的信号通路来保证最大的带宽;
  全双工方式下的数据操作保证最有效的数据吞吐量;

  2、简便的线缆连结:

  更细的电缆搭配更小的连接器;

  3、更好的扩展性:

  可以同时连结更多的磁盘设备。
  由于串行SCSI(SAS)是点到点的结构,因此除了提高性能之外,每个设备连接到指定的数据通路上提高了带宽。SAS的电缆结构节省了空间,从而提高了使用SAS硬盘服务器的散热、通风能力。一般情况下,较大的并行电缆会带来电子干扰,SAS的电缆结构可以解决这个问题。此外SAS结构有非常好的扩展能力,最多可以连接16384个磁盘设备。

  串行SCSI(SAS)硬盘使用与S-ATA相同的接口,但是使用较多的信号,因此SAS硬盘不能与S-ATA硬盘控制器连结。SAS是通用接口,支持SAS和S-ATA,SAS控制器可以支持SAS和SATA磁盘。S-ATA使用SAS控制器的信号子集,因此SAS控制器支持S-ATA硬盘。

  初期的SAS硬盘使用2.5英寸封装,这样可以使机架服务器支持更多的硬盘,现在已经有厂商推出标准3.5英寸的SAS硬盘;初期产品的转速是10000RPM,而现在15000RPM的产品也已经问世。SAS硬盘与相同转速的SCSI硬盘相比有相同或者更好的性能。串行接口减少了线缆的尺寸,允许更快的传输速度,SAS硬盘传输数据可以达到3.0Gbit/sec。

  每个SAS电缆有4根电缆,2根输入2根输出。SAS可以同时进行数据的读写,全双工的数据操作提高数据的吞吐效率。

  SAS的发展史

  2001年11月26日,Compaq、IBM、LSI逻辑、MaxtorSeagate联合宣布成立SAS工作组。

  在2003年的CEBIT大会上,惠普希捷早已推出了SAS界面的硬盘样品。当时,英特尔和Emulex也表示,将计划开发支持SAS和SATA界面的处理器。去年11月,Adaptec也推出了SAS控制器出样,新品的平均数据带宽为3Gbps,峰值带宽达5Gbps。

  未来,第二代和第三代的SAS界面将提供6-12Gbps的数据带宽,并支持HostRAID。

  现在开发SAS架构的存储设备企业包括希捷、前迈拓、LSI Logic和Adaptec等。

  SAS产品市场的发展趋势

  在新一代以SAS为基础的应用结构下,SAS与SATA企业用硬盘是彼此能够截长补短非常理想的储存组件。SAS硬盘是为需求量较大及具备关键性处理任务的应用装置所设计的产品,而SATA硬盘则适合于近线储存及其它对于储存需求量较小的中小型企业所应用。

  预计今年,低端的存储系统将由SATA取代SCSI硬盘,而高、中端的外部存储系统将大部分采用光纤通道。但存储系统价格的迅速下滑等因素却让业界对SAS硬盘的态度大幅改变。在产品价格快速下降的趋势下,存储设备厂商势必通过更具有成本优势的技术制造存储设备,而SAS硬盘正是符合这种需求的产品。另外,SAS系统和SATA系统的兼容性,以及I-SCSI连接标准的实行,也都会推动SAS系统的发展。

  由于企业市场一向对新技术较为保守,也许SAS技术的普及不会像SATA技术那样迅速,但是这也只是时间问题。前迈拓公司预计,到2009年将有三分之二的外部存储设备采用SAS技术,以连接SAS或SATA硬盘。

  SAS硬盘应用

  存储设备的反应速度,除了各环节间的配合与操作系统的影响之外,硬盘的反应速度其实具有关键性的地位。企业级的工作站或存储设备,一般来说,都采用光纤信道(Fibre Channel,FC)与SCSI硬盘作为内部的存储媒体。但是随着SCSI硬盘在扩增性上的限制,SAS(Serial Attached SCSI)硬盘展露头角。由于服务器厂商有越来越多采用SAS硬盘作为内部的存储媒体,那么在存储市场里,SAS硬盘是否会成为FC硬盘的劲敌?NetApp表示小型负载的应用可以采用SAS硬盘,可兼具预算与效能的考虑。

  既然SAS硬盘比较适合小型负载的应用,那么哪些应用为小型负载的状况呢?NetApp解释,例如在1,000人以下的电子邮件系统,或者规模不大的ERP、CRM系统,很多国内中小企业就相当适合。而像是大型的ERP、CRM系统,或是在线实时交易系统等,因为传输量大,反应速度需要实时快速,所以还是应当采用更高端的光纤信道硬盘。

 SAS适配器

  SAS适配器其实就类似于SCSI控制芯片,因为现在的主板上基本都没有集成支持SAS的刂菩酒孕枰褂枚钔獾睦┱箍ǎ屠嗨朴赟CSI控制卡这种概念。目前提供这种控制卡的主要是业界著名的LSI Logic和Adaptec。

  ★LSI Logic

  LSI最新的支持SAS接口的硬盘卡去年8月在东京也已经开始销售,型号为SAS3442X,采用服务器主板常见的PCI-X接口,售价在5万8590日元。此款产品仅提供了1个SAS硬盘接口,付送的数据线提供了4个扩展硬盘接口。

  LSI逻辑去年9月则宣布已开始向主要的OEM客户供应LSI 3Gb/s串行 SCSI(SAS)28和36端口扩展器IC样品,该新品--LSISASx28 和 LSISASx36进一步拓宽了LSI逻辑在IC、HBA、MegaRAID卡以及SAS ROMB解决方案等领域业界领先的SAS产品线,也更增强了其作为技术创新者的市场地位。

  主要的产品特性包括:用于网络安全应用及启动设备功能的基于物理层的分区(phy-based zoning for network security applications and initiator functionality),如自动检测和自动配置(self-discovery and self-configuration)。该产品主要通过一个ARM处理器实现处理及扩展SAS功能。LSI逻辑目前正积极进行在客户端的产品演示工作。

  LSISASx28 和 x36扩展器IC为内、外部 SEP提供了一个通用的可编程模块,便于产品开发及客户的无缝移植(seamless customer migration)。此外,还可以为客户降低向后兼容LSISASx12 和LSISASx12A外部SEP接口的风险。这两种高端口数扩展器每个端口都支持1.5和3Gb/s SATA和SAS的数据传输速率,并提供了一种灵活、可升级、高性能的解决方案。大量的测试已验证了该SAS扩展器 IC 和LSI逻辑的其他SAS元器件产品完全的互操作性。

  LSI逻辑新的高端口数扩展器建立在业界最完善的SAS产品线基础上,该产品线包括12端口扩展器、4和8端口PCI-X及PCI Express控制器IC,LSISAS1078 PCI Express到片上SAS RAID(RAID-on-Chip)解决方案、HBA、MegaRAID适配器卡以及ROMB解决方案。

  根据最新的报道,LSI逻辑(LSI Logic)公司已经于近日宣布出货LSI 3Gb/s SAS(Serial Attached SCSI)36端口和28端口扩展器(expander)的量产单元。

  ★Adaptec

  Adaptec不是第一个在市场上推出SAS产品的厂商,不过,Adaptec一出手就不凡,发布了包括SAS HBA、RAID卡、内部存储和外部子系统在内的最宽广的SAS产品线。

  去年年底,Adaptec同时推出了4块板卡、1款软件和两个外部存储阵列。串行连接SCSI 48300卡具有8个3.0Gb/s SAS/SATA端口,用于提高多媒体和I/O密集型应用的性能,提供RAID 0、1和10数据保护;串行连接SCSI RAID 4800SAS和4805SAS控制器是高性能8端口SAS RAID卡,可通过PCI-X(4800SAS)或PCIe(4805SAS)主机接口安装到服务器,并且都支持SAS或SATA硬盘,配置了128MB带ECC保护的DDR2 DRAM和标准的RAID 0、1、10、5和50功能,控制器核心采用Adaptec RAID Code(ARC),提供增强型数据保护并简化包括热插拔、热备、RAID类别转换、在线容量扩展和优化磁盘利用在内的众多RAID功能的维护;335SAS是高可靠、带4个可热插拔3.5英寸硬盘仓的内部存储柜,可接入SAS和SATA硬盘,包括一个小巧的CD-ROM仓,具有理想的性能和可靠性,每个SAS或SATA Ⅱ RAID控制器卡可支持最多两个存储柜;SANbloc 5000f RAID子系统是FC-SAS外部存储解决方案,适用于DAS或SAN,提供高性能输入输出,可安装SAS硬盘作为高可靠的主存储,或接入SATA硬盘提供经济有效的存储容量,也可以在同一系统中混接两种硬盘,并可通过SANbloc S50 JBOD获得容量扩充,支持SMI-S和Microsoft VDS等行业软件标准;SANbloc S50 JBOD是高性能SAS-SAS JBOD产品,可用作DAS、基于主机的RAID阵列,或作为Adaptec SANbloc 5000f的扩展存储,支持SAS或SATA硬盘。

  SAS硬盘

  在希捷收购迈拓之前,迈拓已经推出了自己的SAS硬盘,而且还计划发布更高容量的产品,不过现在在SAS唱主角的也就只剩希捷了,而日立富士通则 只是推出了相关产品而无法大量供货。

  ★希捷

  Seagate在04年推出过两款SAS硬盘,分别是Cheetah 15k.4和Savvio 10k.1,采用SAS接口,可以提高硬盘的性能,包括更强的系统稳定性以及总体而言更低的系统维护管理的开销。值得一提的是Savvio 10k.1是一款2.5英寸硬盘。

  去年年底,采用Serial Attached SCSI (SAS)接口介面,容量为37GB的希捷Cheetah 15K.4硬盘(型号:ST336754SS)终于上市,其电机转速高达15000RPM,内建8MB数据缓存,平均搜寻时间为3.5毫秒,最低零售价为4万1790日元(约合人民币2900元)。

  目前市面上看到的SAS硬盘基本都是希捷的Savvio,Cheetah还不多见。

  ★前迈拓

  迈拓被收购之前推出过两款很经典的Atlas 10K V和Atlas 15K II,这两款硬盘还曾经获奖,而业界第一款300GB的高容量SAS硬盘--Atlas 10K V也是迈拓的杰作。

  Atlas 15K II和 Atlas 10K V在型号上就已经标出了各自的硬盘转数,分别是15000RPM和10000RPM,而两款硬盘都采用了双通道SAS接口,使企业存储系统的可用性更高。

  ★日立

  去年下半年,日立公司最新的采用Serial Attached SCSI(SAS)和4Gb/s Fibre Channel(4GFC)接口的Ultrastar 15K147系列硬盘产品已经进入量产阶段。

  日立的3.5英寸 Ultrastar 15K147硬盘提供了超高的性能,平均搜寻时间为3.3毫秒,平均潜伏周期2毫秒,马达转速15,000rpm,内置16MB容量的缓存,分别提供36GB,73GB,147GB三种不同容量版本。

  4GFC规格硬盘设计用于网络,文件共享,工作组,科研和工程学环境等方面的数据存储。半双工模式下每个端口的接口数据传输率高达400MB/S,全双工模式则可以达到800MB/S。高性能的4GFC接口全兼容之前的2Gb/s和1Gb/s规格硬件,并在保持原有设备的优势性功能特性基础上,提供高达2倍的数据传输性能。

  ★富士通

  富士通美国分公司在SAS Plugfest 2004大会上展出了他们的小型架构(SFF)硬盘新品

  去年3月,富士通正式发布了自己首款采用Serial Attached SCSI(SAS)规格的硬盘产品—MAV20xxRC,这也将是世界上第一款采用SAS规格的硬盘产品。该产品转速为10000rpm,大小为2.5英寸,平均寻道时间为4ms、快取容量为8Mb、SAS传送速度理论值达3Gbps,并且其工作时的耗电量仅为4.5W。首次推出的产品容量将为73Gb与36Gb两种。

  总结

  作为一种新的存储接口技术,SAS不仅在功能上可与Fibre Channel媲美,还具有兼容SATA的能力,因而被业界公认为取代并行SCSI的不二之选。据吴刚介绍,SAS的优势主要体现在:灵活性,可以兼容SATA,为用户节省投资;扩展性,一个SAS域最多可以直连16384个设备;性能卓越,点对点的架构使性能随端口数量增加而提高;更合理的电缆设计,在高密度环境中提供更有效的散热。衡量一种技术的优劣通常有4个基本指标,即性能、可靠性、可扩展性和成本。回顾串行磁盘技术的发展历史,从光纤通道,到SATA,再到SAS,几种技术各有所长。光纤通道最早出现的串行化存储技术,可以满足高性能、高可靠和高扩展性的存储需要,但是价格居高不下;SATA硬盘成本倒是降下来了,但主要是用于近线存储和非关键性应用,毕竟在性能等方面差强人意;SAS应该算是个全才,可以支持SAS和SATA磁盘,很方便地满足不同性价比的存储需求,是具有高性能、高可靠和高扩展性的解决方案。

posted @ 2007-10-10 15:28 Picasso 阅读(519) | 评论 (0)编辑 收藏

Vmware wiki and SATA support on ESX

百科全书的summary
http://zh.wikipedia.org/wiki/VMware#VMware_ESX.E6.9C.8D.E5.8A.A1.E5.99.A8

终于完成了vmware server 到 ESX 的porting, 不容易。

还是要有探索精神,虽然手册上写ESX不适合装在SATA硬盘上,但2950的SCSI controller还是很
大家都想用SATA硬盘上ESX,这样可以节省很大一部份资金,所以我建议大家能否把支持SATA硬盘的阵列卡型列出来,如果有图更好,有资源的朋友进行一下测试,通过后,大家预定,或根椐该卡的图去电脑城购买呀,我就打算等哪位兄弟例出兼容的卡,去电脑城找。大家觉的怎样呀,大家一起动手,就不用花冤枉钱呀
LSI MegaRaid SATA 150-4 / 150-6 Raid card

Adaptec 2610SA RAID card

Dell Cerc 1.5/6ch Raid

Intel SRCS14L SATA Raid


以上四种SATA Raid卡确认支持VMWare ESX Server ...
咱们要先从没到有,再从有到寻找到最便宜又实用的卡,这几个卡,偶今天去查查看都要多少钱

经查LSI MegaRaid SATA 150-4 / 150-6 Raid card   要3800左右
Adaptec 2610SA RAID card      1500左右    6个SATA接口,raid 5 0 1支持  64位PCI接口,不能上普通PC PCI口,家用机没希望 上 郁闷


另外两个末知,呵呵,看来这个adaptec是我们首选 了,如果有更便宜的我会继续跟进。
大家可以参考http://www.vmprofessional.com/index.php?content=sata_faq

Confirmed Working
Controller Driver vmware-devices.map lspci
LSILogic MegaRAID 150-4 megaraid2 unknown unknown
LSILogic MegaRAID 150-6 megaraid2 unknown unknown
Dell Cerc 1.5/6ch aacraid-115 device,0x9005,0x0285,scsi,CERC SATA RAID 2 PCI SATA 6ch (DellCorsair) RAID bus controller: Adaptec Adaptec SCSI (rev 01)
Adaptec 2610SA aacraid-115 device,0x9005,0x0285,scsi,AAR-2610SA PCI SATA 6ch RAID bus controller: Adaptec Adaptec SCSI (rev 01)
Intel SRCS14L gdth device,0x8086,0x0600,scsi,RAID Controller RAID bus controller: Intel Corporation RAID Controller


Suspected to work Controller Driver vmware-devices.map lspci
Adaptec 2410SA aacraid-115 device,0x9005,0x0285,scsi,AAR-2410SA PCI SATA 4ch (Jaguar II) RAID bus controller: Adaptec Adaptec SCSI (rev 01)
HP P600 unknown unknown unknown


Confirmed not Working Controller Driver vmware-devices.map lspci
Intel SRCS28X unknown unknown unknown

posted @ 2007-10-10 15:24 Picasso 阅读(1052) | 评论 (0)编辑 收藏

WPF——微软的UI革命(转)

http://www.cnblogs.com/cuihongyu3503319/archive/2007/02/25/655660.html

posted @ 2007-09-25 14:51 Picasso 阅读(146) | 评论 (0)编辑 收藏

http://www.cnblogs.com/tonyqus/archive/2006/11/30/577097.html

posted @ 2007-09-25 14:40 Picasso 阅读(167) | 评论 (0)编辑 收藏

Tape information

原来百科全书这种东西也总结了,收纳
http://en.wikipedia.org/wiki/Linear_Tape-Open

posted @ 2007-09-05 17:33 Picasso 阅读(180) | 评论 (0)编辑 收藏

SSL的证书验证

SSL协议与数字证书原理 1楼

SSL 协议的握手和通讯

  为了便于更好的认识和理解 SSL 协议,这里着重介绍 SSL 协议的握手协议。SSL 协议既用到了公钥加密技术又用到了对称加密技术,对称加密技术虽然比公钥加密技术的速度快,可是公钥加密技术提供了更好的身份认证技术。SSL 的握手协议非常有效的让客户和服务器之间完成相互之间的身份认证,其主要过程如下:
  ① 客户端的浏览器向服务器传送客户端 SSL 协议的版本号,加密算法的种类,产生的随机数,以及其他服务器和客户端之间通讯所需要的各种信息。
  ② 服务器向客户端传送 SSL 协议的版本号,加密算法的种类,随机数以及其他相关信息,同时服务器还将向客户端传送自己的证书。
  ③ 客户利用服务器传过来的信息验证服务器的合法性,服务器的合法性包括:证书是否过期,发行服务器证书的 CA 是否可靠,发行者证书的公钥能否正确解开服务器证书的“发行者的数字签名”,服务器证书上的域名是否和服务器的实际域名相匹配。如果合法性验证没有通过,通讯将断开;如果合法性验证通过,将继续进行第四步。
  ④ 用户端随机产生一个用于后面通讯的“对称密码”,然后用服务器的公钥(服务器的公钥从步骤②中的服务器的证书中获得)对其加密,然后将加密后的“预主密码”传给服务器。
  ⑤ 如果服务器要求客户的身份认证(在握手过程中为可选),用户可以建立一个随机数然后对其进行数据签名,将这个含有签名的随机数和客户自己的证书以及加密过的“预主密码”一起传给服务器。
  ⑥ 如果服务器要求客户的身份认证,服务器必须检验客户证书和签名随机数的合法性,具体的合法性验证过程包括:客户的证书使用日期是否有效,为客户提供证书的 CA 是否可靠,发行 CA 的公钥能否正确解开客户证书的发行 CA 的数字签名,检查客户的证书是否在证书废止列表(CRL)中。检验如果没有通过,通讯立刻中断;如果验证通过,服务器将用自己的私钥解开加密的“预主密码”,然后执行一系列步骤来产生主通讯密码(客户端也将通过同样的方法产生相同的主通讯密码)。
  ⑦ 服务器和客户端用相同的主密码即“通话密码”,一个对称密钥用于 SSL 协议的安全数据通讯的加解密通讯。同时在 SSL 通讯过程中还要完成数据通讯的完整性,防止数据通讯中的任何变化。
  ⑧ 客户端向服务器端发出信息,指明后面的数据通讯将使用的步骤⑦中的主密码为对称密钥,同时通知服务器客户端的握手过程结束。
  ⑨ 服务器向客户端发出信息,指明后面的数据通讯将使用的步骤⑦中的主密码为对称密钥,同时通知客户端服务器端的握手过程结束。
  ⑩ SSL 的握手部分结束,SSL 安全通道的数据通讯开始,客户和服务器开始使用相同的对称密钥进行数据通讯,同时进行通讯完整性的检验。


  双向认证 SSL 协议的具体过程
   ① 浏览器发送一个连接请求给安全服务器。
  ② 服务器将自己的证书,以及同证书相关的信息发送给客户浏览器。
  ③ 客户浏览器检查服务器送过来的证书是否是由自己信赖的 CA 中心所签发的。如果是,就继续执行协议;如果不是,客户浏览器就给客户一个警告消息:警告客户这个证书不是可以信赖的,询问客户是否需要继续。
   ④ 接着客户浏览器比较证书里的消息,例如域名和公钥,与服务器刚刚发送的相关消息是否一致,如果是一致的,客户浏览器认可这个服务器的合法身份。
   ⑤ 服务器要求客户发送客户自己的证书。收到后,服务器验证客户的证书,如果没有通过验证,拒绝连接;如果通过验证,服务器获得用户的公钥。
   ⑥ 客户浏览器告诉服务器自己所能够支持的通讯对称密码方案。
   ⑦ 服务器从客户发送过来的密码方案中,选择一种加密程度最高的密码方案,用客户的公钥加过密后通知浏览器。
   ⑧ 浏览器针对这个密码方案,选择一个通话密钥,接着用服务器的公钥加过密后发送给服务器。
   ⑨ 服务器接收到浏览器送过来的消息,用自己的私钥解密,获得通话密钥。
   ⑩ 服务器、浏览器接下来的通讯都是用对称密码方案,对称密钥是加过密的。
   上面所述的是双向认证 SSL 协议的具体通讯过程,这种情况要求服务器和用户双方都有证书。单向认证 SSL 协议不需要客户拥有 CA 证书,具体的过程相对于上面的步骤,只需将服务器端验证客户证书的过程去掉,以及在协商对称密码方案,对称通话密钥时,服务器发送给客户的是没有加过密的(这并不影响 SSL 过程的安全性)密码方案。 这样,双方具体的通讯内容,就是加过密的数据,如果有第三方攻击,获得的只是加密的数据,第三方要获得有用的信息,就需要对加密的数据进行解密,这时候的安全就依赖于密码方案的安全。而幸运的是,目前所用的密码方案,只要通讯密钥长度足够的长,就足够的安全。这也是我们强调要求使用 128 位加密通讯的原因。



证 书 各 部 分 的 含 义
Version 证书版本号,不同版本的证书格式不同
Serial Number 序列号,同一身份验证机构签发的证书序列号唯一
Algorithm Identifier 签名算法,包括必要的参数 Issuer 身份验证机构的标识信息
Period of Validity 有效期
Subject 证书持有人的标识信息
Subject’s Public Key 证书持有人的公钥
Signature 身份验证机构对证书的签名


  证书的格式  认证中心所发放的证书均遵循 X.509 V3 标准,其基本格式如下:

证书版本号(Certificate Format Version) 含义:用来指定证书格式采用的 X.509 版本号。
证书序列号(Certificate Serial Number) 含义:用来指定证书的唯一序列号,以标识 CA 发出的所有公钥证书。
签名(Signature) 算法标识(Algorithm Identifier) 含义:用来指定 CA 签发证书所用的签名算法。
签发此证书的 CA 名称(Issuer ) 含义:用来指定签发证书的 CA 的 X.500 唯一名称(DN, Distinguished Name)。
证书有效期(Validity Period) 起始日期(notBefore) 终止日期(notAfter) 含义:用来指定证书起始日期和终止日期。
用户名称(Subject) 含义:用来指定证书用户的 X.500 唯一名称(DN,Distinguished Name)。
用户公钥信息(Subject Public Key Information) 算法(algorithm) 算法标识(Algorithm Identifier) 用户公钥(subject Public Key) 含义:用来标识公钥使用的算法,并包含公钥本身。
证书扩充部分(扩展域)(Extensions) 含义:用来指定额外信息。 
X.509 V3 证书的扩充部分(扩展域)及实现方法如下: CA 的公钥标识(Authority Key Identifier) 公钥标识(SET 未使用)(Key Identifier) 签发证书者证书的签发者的甄别名(Certificate Issuer) 签发证书者证书的序列号(Certificate Serial Number)

 X.509 V3 证书的扩充部分(扩展域)及实现CA 的公钥标识(Authority Key Identifier) 公钥标识(SET 未使用)(Key Identifier) 签发证书者证书的签发者的甄别名(Certificat签发证书者证书的序列号(Certificate Serial N含义:CA 签名证书所用的密钥对的唯一标识用户的公钥标识(Subject Key Identifier) 含义:用来标识与证书中公钥相关的特定密钥进行解密。 证书中的公钥用途(Key Usage) 含义:用来指定公钥用途。
用户的私钥有效期(Private Key Usage Period) 起始日期(Note Before) 终止日期(Note After) 含义:用来指定用户签名私钥的起始日期和终止日期。 CA 承认的证书政策列表(Certificate Policies) 含义:用来指定用户证书所适用的政策,证书政策可由对象标识符表示。 用户的代用名(Substitutional Name) 含义:用来指定用户的代用名。 CA 的代用名(Issuer Alt Name) 含义:用来指定 CA 的代用名。 基本制约(Basic Constraints) 含义:用来表明证书用户是最终用户还是 CA。 在 SET 系统中有一些私有扩充部分(扩展域)Hashed Root Key 含义:只在根证书中使用,用于证书更新时进行回溯。 证书类型(Certificate Type) 含义:用来区别不同的实体。该项是必选的。 商户数据(Merchant Data) 含义:包含支付网关需要的所有商户信息。 持卡人证书需求(Card Cert Required) 含义:显示支付网关是否支持与没有证书的持卡人进行交易。 SET 扩展(SETExtensions) 含义:列出支付网关支持的支付命令的 SET 信息扩展。 CRL 数据定义版本(Version) 含义:显示 CRL 的版本号。
CRL 的签发者(Issuer) 含义:指明签发 CRL 的 CA 的甄别名。 CRL 发布时间(this Update) 预计下一个 CRL 更新时间(Next Update) 撤销证书信息目录(Revoked Certificates) CRL 扩展(CRL Extension) CA 的公钥标识(Authority Key Identifier) CRL 号(CRL Number)

posted @ 2007-09-04 18:05 Picasso 阅读(3709) | 评论 (0)编辑 收藏

BQ中的DST 处理

最近BQ关于时间处理出问题, 是因为时间的计算上没有处理好DST,以前做计费的时候老碰到,还做了专题,疏忽了,微软倒有详细的解释,抄录如下:
http://support.microsoft.com/kb/932955/zh-cn

posted @ 2007-09-04 14:50 Picasso 阅读(199) | 评论 (0)编辑 收藏

有志之人立志常,无志之人常立志

偶尔听到的

posted @ 2007-08-30 20:27 Picasso 阅读(157) | 评论 (0)编辑 收藏

WPF automation

产品的GUI Automation准备:
1.书籍:
http://www.cnblogs.com/tonyqus/archive/2007/08/01/835071.html

这本书是由Adam Nathan和Daniel Lehenbauer写的,这两个人都是WPF Team的,而且都是核心开发工程师,技术级别自然是很高的。全书共有600页左右,原版书采用全彩印刷,于2007年初由SAMS出版社出版发行。作为一本Unleashed级别的书,自然要适合初、中、高各个层次的开发者。

本书共分为6个部分,其实严格意义上讲是5部分,因为第6部分是附录。让我们看看这五部分分别讲了什么:
第一部分 背景

这部分主要讲WPF的由来、为什么要使用WPF,以及一些WPF的基础知识。总的来说,这一部分是为接下来的几个部分作铺垫的,可以算是打基础。对于初学者来说,看完这一部分你就可以基本了解WPF是什么、为什么要学习WPF以及WPF的发展方向,说白了就是让你找到学习的方向。我个人对于这种写作风格十分喜欢,一开始就告诉你这个技术的用途,而且用了大篇幅来讲一些实际的例子,让读者可以有一个感性的认识。

第二部分 构建一个WPF应用程序

顾名思义,这部分讲的是构建一个WPF应用程序所需要的知识。但这一部分要比上一部分中的基础知识深入多了,讲的都是很实用的东西,直接可以在开发中使用,比如控件、变换等,当然这一部分主要还是着重于打基础,但与你所想象的不同,它并不是一步一步教你构建一个类似于Hello World的程序,而是把涉及的一些概念讲得比较深入,作者似乎是想让读者在充分理解的基础上创建第一个WPF应用程序。

第三部分为专业开发人员设计的功能

这部分算是第二部分的提高篇,讲到了资源、数据绑定、样式、模板等,这些可都是做高端开发所必须的,但由于是一些相对较难理解的东西,所以作者把它放在这部分里一切讲解。

第四部分 富媒体使你的程序领先于时代

这部分围绕着富媒体展开,这也是WPF真正牛的地方,比如说2D和3D功能、动画、视频、音频等,WPF的最大优点就在于它把使用这些富媒体的门槛降低了,所以如果你想真正开发出科幻般的应用程序的话,这一部分自然是必须看的。

第五部分 高级主题

这部分相对于前几部分有相当的难度,所以才叫高级主题!我个人觉得这一章完全是为高级开发人员准备的,其中涉及的内容都是关于定制控件开发、互操作性之类的,要看这一章你必须对前面的部分有充分的理解。

这本书的写作风格也很有特点,其中有大量的提示、警告和深入挖掘。所谓提示,就是一些技巧性的东西,根据正文讲的东西展开;所谓警告,则是告诉我们哪些东西可以用,哪些不可以用,这一技术有什么技巧;所谓深入挖掘,就是对正文所提到的东西深入讲解一番,可以有效帮助我们加深对一些知识点的理解。

大家可以去http://adamnathan.net/wpf/ 下载这本书的代码,不过貌似没有找到勘误信息,可能作者对这本书的质量比较有自信吧。

这几年软件开发的重点在Web,但Charles Petzold依然固守在Client端的GUI程序设计,我原本以为,他会渐渐没落,事实上,《Programming Microsoft Windows with C#》的销售也不能算很好。但是随着WPF技术的出现,Charles Petzold的这本《Applications = Code + Markup》将会让他再度成为重要的书籍作者。

这是一本「学习用书」而非「参考用书」。尽管如此,本书的读者必须熟悉C#语言并具备.NET Framework的经验,没有经验的读者,可以阅读Charles Petzold写的在线免费书籍《.NET Book Zero: What the C or C++ Programmer Needs to Know about C# and the .NET Framework》。

Applications = Code + Markup》介绍如何使用WPF编写微软Windows平台的程序。WPF的程序可以是一般的独立Windows应用(这样的程序现在常称为 Client应用),或者是分布式(Distributed)应用的前端(也就是RIARich Internet Application),未来也可能利用WPF/E取代一部分的Web技术,例如:ASP.NETWPF被认为是Windows Vista的主要API,但是也可以用在已安装.NET 3.0Windows XP/SP2Windows Server 2003

WPF
其实包含「两个」互相关连的程序设计接口。你可以利用C#(或其它.NET语言)编写WPF程序。WPF也具备一个让人兴奋的XML语言, 称为XAML,甚至可以只用XAML开发某些应用。但是一般来说,你会同时利用程序代码(Code)和标记(Makeup)一同开发出你的应用。现在,你应 该能够体会,为什么这本书的书名为《Application = Code + Markup》。在WPF的观念中,我们使用XAMLMarkup)定义使用者接口视觉的部分(包括图形和动画),然后写程序代码(Code)处理使用者 的输入。

WPF
支持两种非常不同的程序设计接口,每个程序设计员都应该要对于WPFCode部分建立稳固的根基,写起Markup的时候才不会遇到障 碍。因此,本书分成两个部分,各约半本书。第一部分先引导读者如何利用C#写出整个WPF程序(完全不用到XAML),第二部分再介绍XAML
二部分将焦点转移到XAML。展示如何只用XAML建立小型的应用,以及如何结合XAMLC#以建立更大型、更复杂的应用。因为XAML 是用来建立应用的视觉部分,所以本书大部分和图形相关的内容,会放在第二部分。XAML的档案大多数是用工具所产生出来的。然而,我们还是有必要具备「亲自动手编写XAML」的能力,本书试图要教我们这么做。

再过几年Windows Forms也会被淘汰,而WPF才是未来的主流。虽然WPF尚未像Windows Forms提供这么多控件和标准对话框,但是未来却很有发展潜力。特别是,如果你需要做很多客制化控件和绘图,WPF会是你需要的。如果你想好好地学 习WPFCharles Petzold写的这本《Applications = Code + Markup》,不会让你失望的。
2. WPF->net Framework里的UIAutomation 需要了解.
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1634518&SiteID=1
http://msdn.microsoft.com/msdnmag/issues/07/03/Bugslayer/
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=769221&SiteID=1







posted @ 2007-08-08 15:48 Picasso 阅读(668) | 评论 (0)编辑 收藏

批处理控制VMWare虚拟机


http://myblog.iweb.net.cn/read.php?66
VMWare 确实是好东西,不过安装之后会增加四个自动启动的服务以及两个虚拟的网络连接。我是比较讨厌这种没事就占着系统资源的东西,何况也不是经常要用着 VMWare ,所以写了个批处理脚本来自动启动/关闭 VMWare 虚拟机以及相关的服务和网络连接。
完整批处理文件内容如下:


1 @echo On  
2 @PROMPT [VMWareController]#  
3  
4 @if "%1" == "" goto Help  
5 @if "%1" == "help" goto Help  
6 @if "%1" == "/?" goto Help  
7  
8 @SET oprType=%1  
9 @SET netOpr=%oprType%  
10  
11 @if "%oprType%" == "start" @SET netOpr=enable  
12 @if "%oprType%" == "stop" @SET netOpr=disable  
13  
14 @SET vmxFile=%2  
15 @Rem 如果没有提供第二个参数vmx full path,将尝试使用这里设定的缺省虚拟机  
16 @Rem 根据需要把这个文件修改为实际希望启动的vmx文件  
17 @if "%vmxFile%" == "" @SET vmxFile=D:\VMWare\Red Hat Enterprise Linux 3.vmx  
18  
19 @Rem VMWare的安装目录,根据需要进行修改  
20 @SET vmwareFolder=E:\AppTool\VMWare  
21  
22 @Rem 把VMWare相关的四个服务设置为手动  
23 sc config VMAuthdService start= demand  
24 sc config VMnetDHCP start= demand  
25 sc config "VMware NAT Service" start= demand  
26 sc config vmount2 start= demand  
27  
28 @Rem 启动/停止VMWare相关的四个服务  
29 net %oprType% "VMware Authorization Service"  
30 net %oprType% "VMware DHCP Service"  
31 net %oprType% "VMware NAT Service"  
32 net %oprType% "VMware Virtual Mount Manager Extended"  
33  
34 @Rem 这里使用通配符来停用/启用所有vmnet相关的网络连接  
35 devcon %netOpr% *vmnet*  
36  
37 @Rem 使用vmrun来运行指定的虚拟机  
38 "%vmwareFolder%\vmrun" %oprType% "%vmxFile%"    
39  
40 @goto EndMission  
41  
42 :Help  
43 @echo 自动启动/停止指定的 VMWare 虚拟机以及相关的服务和网络连接  
44 @echo 需要 devcon 工具来控制网络连接。工具下载地址:  
45 @echo http://support.microsoft.com/kb/311272/zh-cn  
46 @echo 命令行参数:  
47 @echo %0 [start^|stop] ^  
48 @echo ^为缺省启动的虚拟机配置文件  
49 @pause  
50 goto EndMission  
51  
52 :EndMission  
view plain | print | copy to clipboard | ?
@echo On
@PROMPT [VMWareController]#

@if "%1" == "" goto Help
@if "%1" == "help" goto Help
@if "%1" == "/?" goto Help

@SET oprType=%1
@SET netOpr=%oprType%

@if "%oprType%" == "start" @SET netOpr=enable
@if "%oprType%" == "stop" @SET netOpr=disable

@SET vmxFile=%2
@Rem 如果没有提供第二个参数vmx full path,将尝试使用这里设定的缺省虚拟机
@Rem 根据需要把这个文件修改为实际希望启动的vmx文件
@if "%vmxFile%" == "" @SET vmxFile=D:\VMWare\Red Hat Enterprise Linux 3.vmx

@Rem VMWare的安装目录,根据需要进行修改
@SET vmwareFolder=E:\AppTool\VMWare

@Rem 把VMWare相关的四个服务设置为手动
sc config VMAuthdService start= demand
sc config VMnetDHCP start= demand
sc config "VMware NAT Service" start= demand
sc config vmount2 start= demand

@Rem 启动/停止VMWare相关的四个服务
net %oprType% "VMware Authorization Service"
net %oprType% "VMware DHCP Service"
net %oprType% "VMware NAT Service"
net %oprType% "VMware Virtual Mount Manager Extended"

@Rem 这里使用通配符来停用/启用所有vmnet相关的网络连接
devcon %netOpr% *vmnet*

@Rem 使用vmrun来运行指定的虚拟机
"%vmwareFolder%\vmrun" %oprType% "%vmxFile%"

@goto EndMission

:Help
@echo 自动启动/停止指定的 VMWare 虚拟机以及相关的服务和网络连接
@echo 需要 devcon 工具来控制网络连接。工具下载地址:
@echo http://support.microsoft.com/kb/311272/zh-cn
@echo 命令行参数:
@echo %0 [start^|stop] ^
@echo ^为缺省启动的虚拟机配置文件
@pause
goto EndMission

:EndMission


  把以上代码保存为 .bat 文件,并创建两个指向该 .bat 文件的快捷方式,并分别给两个快捷方式加上 start / stop 参数(也可以再提供第二个参数来指定启动特定的虚拟机配置文件),就可以通过快捷方式直接启动/停止 VMWare 相关的虚拟机和服务。

  其中使用了 devcon 工具来控制网络连接的停用/启用,需要到微软网站下载该工具。

  注意:如果你的系统中存在其他硬件ID包含 *vmnet* 字符串的话会把所有相关的设备同时都禁用/启用。你可以在命令行下输入 devcon find *vmnet* 先检查一下是否只匹配到 VMWare 所添加的两个虚拟网络连接。

  用 vmrun 关闭虚拟机的时候作用等同于在操作界面的 Power Off 按钮。所以最好在执行批处理之前使用虚拟操作系统的 shutdown 命令先安全退出操作系统。

posted @ 2007-08-01 06:59 Picasso 阅读(1408) | 评论 (0)编辑 收藏

SOAP协议初级指南

http://www.yesky.com/229/1739729_8.shtml
http://www0.ccidnet.com/tech/app/2001/09/21/58_3322.html
http://www0.ccidnet.com/tech/app/2001/09/21/58_3321.html
http://www0.ccidnet.com/tech/app/2001/09/21/58_3320.html
http://www0.ccidnet.com/tech/app/2001/09/21/58_3319.html

posted @ 2007-07-26 11:47 Picasso 阅读(196) | 评论 (0)编辑 收藏

XML NameSpace

http://zhangjunhd.blog.51cto.com/113473/18934

posted @ 2007-07-26 11:14 Picasso 阅读(202) | 评论 (0)编辑 收藏

Single Sign on 2

Java based:
http://www.ibm.com/developerworks/cn/websphere/library/techarticles/xiaojing/SSOprepare/SSOprepare.html


MS based:
http://www.microsoft.com/china/community/MsSpecialist/1.mspx

posted @ 2007-07-25 18:50 Picasso 阅读(170) | 评论 (0)编辑 收藏

单点登陆 single sign-on

    只有注册用户登录后才能阅读该文。阅读全文

posted @ 2007-07-25 18:44 Picasso 阅读(66) | 评论 (0)编辑 收藏

ADO and ADO.net

ADO是什么,它是如何操作数据库的?

  答:ADO的全名是ActiveX Data Object(ActiveX数据对象),是一组优化的访问数据库的专用对象集,它为ASP提供了完整的站点数据库解决方案,它作用在服务器端,提供含有数据库信息的主页内容,通过执行SQL命令,让用户在浏览器画面中输入,更新和删除站点数据库的信息。

  ADO主要包括Connection,Recordset和Command三个对象, 它们的主要功能如下:

  ·Connection对象:负责打开或连接数据库文件;
  ·Recordset对象:存取数据库的内容;
  ·Command对象:对数据库下达行动查询指令,以及执行SQL Server的存储过程。

使用Recordset对象和Command对象来访问数据库的区别在哪里?

  答:Recordset对象会要求数据库传送所有的数据,那么数据量很大的时候就会造成网络的阻塞和数据库服务器的负荷过重,因此整体的执行效率会降低。
利用Command对象直接调用SQL语句,所执行的操作是在数据库服务器中进行的,显然会有很高的执行效率。特别是在服务器端执行创建完成的存储过程,可以降低网络流量,另外,由于事先进行了语法分析,可以提高整体的执行效率。


什么是ADO.NET架构

如今大部分的应用程序都需要后台的数据库来为其提供大量的数据来源,而应用程序与数据库之间的交流称为数据访问。而ASP.NET则使用ADO.NETActive X Data Object)作为数据的访问与操作的协议,从而使得我们可以在Internet上操作这些数据。

ADO.NET的数据访问分为两大部分:数据集(DataSet)与数据提供源(Data Provider,我并不清楚中文该怎么翻译,就叫它数据提供源好了,不要和“数据源”—Data Source搞混)

 

数据集:

数据集是一个非在线,完全由内存表示的一系列数据,可以被看作一份本地磁盘数据库中部分数据的拷贝。数据集完全驻留内存,可以被独立于数据库地访问或者修改。当数据集的修改完成后,更改可以被再次写入数据库,从而保留我们所做过的更改。数据集中的数据可以由任何数据源(Data Source)提供,比如SQL Server或者Oracle

 

数据提供源:

数据提供源用于提供并维护应用程序与数据库之间的连接。

数据提供源是一系列为了提供更有效率的访问而协同工作的组件。如今微软在ADO.NET中提供了两组数据提供源,一组叫做SQL Data ProviderSQL数据提供源),用于提供应用程序与SQL Server 7.0或者更高版本的访问。另一组叫做OleDb DataProviderObject Linking and Embedding DataBase DataProvider),可以允许我们访问例如Oracle 之类的第三方数据源。

每组数据提供源中都包含了如下四个对象:

Connect对象提供了对数据库的连接。

Command对象可以用来执行命令。

DataReader对象提供了只读的数据记录集。

DataAdapter对象提供了对数据集更新或者修改的操作。

 

总体来说,使用ADO.NET访问数据可以被概括为以下步骤:

首先应用程序创建一个Connect对象用来建立与数据库之间的连接。然后Command对象提供了执行命令的接口,可以对数据库执行相应的命令。当命令执行后数据库返回了大于零个数据时,DataReader会被返回从而提供对返回的结果集的数据访问。或者,DataAdapter可以被用来填充数据集,然后数据库可以由Command对象或者DataAdapter对象进行相应的更改。

具体来看数据提供源的四种对象

 

Connect 对象

Connect对象用来提供对数据库的连接,Microsoft Visual Studio .Net中微软提供了两种Connect对象,分别为SqlConnection对象,用来提供对SQL Server 7.0或更高版本的连接,同时还有OleDbConnection对象,用来提供对Access与其他第三方数据库的连接。

 

Command 对象

同样,Command对象分为两组,SqlCommandOleDbCommandCommand对象被用来执行针对数据库的命令,比如执行数据库的存储过程(Stored Procedure)SQL命令,或者直接返回一个完整的表。Command对象提供三种方法(Methods)用来执行上述操作。

ExecuteNonQuery用来执行一个不需返回数据的命令,比如表的插入,更新或者删除操作。

ExecuteScalar返回从一个查询得到的单独的值。

ExecuteReader用来返回一个从DataReader来的结果集。

 

DataReader对象

DataReader提供了forward-only, read-only, connected stream的结果集。

这里的forward-only表示数据只能够向前,如果我们访问了一条数据后想要再次访问这条数据就必须重新开始。

Read-only表示只读,不能够对结果集进行操作。

Connected stream表示DataReader对象是面向流连接的。所谓的流可以把它看作是管道,这边放进去东西那边就可以得到,实际上TCP协议就是面向连接的流协议。

不同于其他的三种对象,DataReader不能够被用户直接创建,必须也只能由ExecuteReader返回。

SqlCommand.ExecuteReader返回SqlDataReader

同理,OleDbCommand.ExecuteReader返回OleDbDataReader

需要注意的是,DataReader对应用程序提供行级访问(每次只能访问数据的一行),当你需要多行的时候就需要多次的访问这个对象。这样做的好处就是内存中永远只需要保留一行的数据,缺点就是每次访问都要开启Connect的连接。

 

DataAdapter对象

DataAdapter对象是ADO.NET数据访问的核心。实际上它是数据集与数据库的中间层。DataAdapter可以使用Fill方法来为DataTable或者DataSet填充数据。然后当内存操作完成后DataAdapter可以确认之前的操作从而对真正存于数据库上的数据进行修改。

DataAdapter包含四种属性用来代表不同的数据库命令:

SelectCommand用来查询数据

InsertCommand用来插入数据

DeleteCommand用来删除数据

UpdateCommand用来更新数据Update方法被调用后,数据集中的数据被更改然后拷贝回数据库,紧接着使用InsertCommand, DeleteCommand, UpdateCommand中合适一个来进行数据更新。

posted @ 2007-07-25 16:46 Picasso 阅读(263) | 评论 (0)编辑 收藏

DOM简介

http://book.csdn.net/bookfiles/110/1001107072.shtml

DOM教程(什么是DOM)
                        作为结构的 DOM
      DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中导航仪寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而 DOM 被认为是基于树或基于对象的。
      对于特别大的文档,解析和加载整个文档可能很慢且很耗资源,因此使用其他手段来处理这样的数据会更好。这些基于事件的模型,比如 Simple API for XML(SAX),适用于处理数据流,即随着数据的流动而依次处理数据。基于事件的 API 消除了在内存中构造树的需要,但是却不允许开发人员实际更改原始文档中的数据。
     另一方面,DOM 还提供了一个 API,允许开发人员添加、编辑、移动或删除树中任意位置的节点,从而创建一个引用程序。
     解析器是一个软件应用程序,设计用于分析文档(这里是指 XML 文件),以及做一些特定于该信息的事情。在诸如 SAX 这样基于事件的 API 中,解析器将向某种监听器发送事件。在诸如 DOM 这样基于树的 API 中,解析器将在内存中构造一颗数据树。
作为 API 的 DOM
     从 DOM Level 1 开始,DOM API 包含了一些接口,用于表示可从 XML 文档中找到的所有不同类型的信息。它还包含使用这些对象所必需的方法和属性。
Level 1 包括对 XML 1.0 和 HTML 的支持,每个 HTML 元素被表示为一个接口。它包括用于添加、编辑、移动和读取节点中包含的信息的方法,等等。然而,它没有包括对 XML 名称空间(XML Namespace)的支持,XML 名称空间提供分割文档中的信息的能力。
     DOM Level 2 添加了名称空间支持。Level 2 扩展了 Level 1,允许开发人员检测和使用可能适用于某个节点的名称空间信息。Level 2 还增加了几个新的模块,以支持级联样式表、事件和增强的树操作。
     当前正处于定稿阶段的 DOM Level 3 包括对创建 Document 对象(以前的版本将这个任务留给实现,使得创建通用应用程序很困难)的更好支持、增强的名称空间支持,以及用来处理文档加载和保存、验证以及 XPath 的新模块;XPath 是在 XSL 转换(XSL Transformation)以及其他 XML 技术中用来选择节点的手段。
     DOM 的模块化意味着作为开发人员,您必须知道自己希望使用的特性是否受正在使用的 DOM 实现所支持。
                                        确定特性可用性
     DOM 推荐标准的模块性质允许实现者挑选将要包括到产品中的部分,因而在使用某个特定的特性之前,首先确定该特性是否可用可能是必要的。本教程仅使用 DOM Level 2 Core API,不过在着手您自己的项目时,了解如何能够检测特性是有所帮助的。
     DOM 中定义的接口之一就是 DOMImplementation。通过使用 hasFeature() 方法,您可以确定某个特定的特性是否受支持。DOM Level 2 中不存在创建DOMImplementation 的标准方法,不过下面的代码将展示如何使用 hasFeature() 来确定 DOM Level 2 样式表模块在某个 Java 应用程序中是否受支持。
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.DOMImplementation;
public class ShowDomImpl {
   public static void main (String args[]) {
      try {
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
         DocumentBuilder docb = dbf.newDocumentBuilder();
         DOMImplementation domImpl = docb.getDOMImplementation();
         if (domImpl.hasFeature("StyleSheets", "2.0")) {
            System.out.println("Style Sheets are supported.");
         } else {
            System.out.println("Style Sheets are not supported.");
         }
      } catch (Exception e) {}      
 }
}
(DOM Level 3 将包括用于创建 DOMImplementation 的标准方法。)
     本教程将使用单个文档来展示 DOM Level 2 Core API 的对象和方法。
                                        基本的 XML 文件
     本教程中的所有例子都是用了一个包含如下节点的 XML 文件,它表示输入某个商业系统的订单。回顾一下,XML 文件的基本组成部分包括:
     XML 声明:基本的声明 <?xml version"1.0"?> 将这个文件定义为 XML 文档。在声明中指定一种字符编码的情况并不鲜见,如下所示。通过这种方式,不管该 XML 文件使用的语言或字符编码是什么,只要解析器理解特定的编码,它就能够正确地读取该 XML 文件。 
     DOCTYPE 声明:XML 是人机之间交换信息的便利手段,但是要使它能够顺利地工作,必须要有一个公共的词汇表。可选的 DOCTYPE 声明可用于指定一个应该用来与此文件做比较的文档(在本例中为 orders.dtd),以确保不会产生任何混淆或丢失信息(例如,丢失一个 userid 或错误拼写某个元素名称)。以这种方式处理过的文档称为有效的文档。成功的有效性检查并不是 XML 所必需的,后面的例子实际上从文档中省略了 DOCTYPE 声明。 
     数据本身:XML 文档中的数据必须包含在单个根元素内,比如下面的 orders 元素。要使 XML 文档得到处理,它必须是格式良好的(well-formed)。 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ORDERS SYSTEM "orders.dtd">
<orders>
   <order>
      <customerid limit="1000">12341</customerid>
      <status>pending</status>
      <item instock="Y" itemid="SA15">
         <name>Silver Show Saddle, 16 inch</name>
         <price>825.00</price>
         <qty>1</qty>
      </item>
      <item instock="N" itemid="C49">
         <name>Premium Cinch</name>
         <price>49.00</price>
         <qty>1</qty>
      </item>
   </order>
   <order>
      <customerid limit="150">251222</customerid>
      <status>pending</status>
      <item instock="Y" itemid="WB78">
         <name>Winter Blanket (78 inch)</name>
         <price>20</price>
         <qty>10</qty>
      </item>
   </order>
</orders>
    在 DOM 中,使用 XML 信息意味着首先将它划分为节点。

posted @ 2007-07-25 16:34 Picasso 阅读(255) | 评论 (0)编辑 收藏

COM与.NET的交互

 
 Advanced COM Interop


.NET framework 是从COM的一种自然地进步,因为这两个模型共享了许多中心的主题,包括组件重用和语言中立。为了支持向后兼容,COM interop提供了不需要修改现有组件而能访问现有COM组件的方法。可以通过使用COM interop工具导入相关的COM类型来合并COM组件到.NET Framework的应用中。一旦导入,COM的类型就可以使用了。

COM interop 同时也提供了向前兼容使得COM的客户可以像访问其他的COM对象一样访问托管的代码,COM interop又一次的提供了所谓的无缝从程序集中导出元数据(metadata)到类型库并且像传统COM组件一样注册托管组件的方法。无论是导出还是导入工具处理的结果都与COM规范一致。在运行时,如果需要的话common language runtime在COM对象和托管代码之间列集(marshals)数据


1. COM Wrappers
COM在以下几个方面与.NET Framework的对象模型有所不同:
• COM对象的客户程序必须管理这些对象的生命期;在.NET Framework 中CLR管理这些对象的生命期
• COM的客户通过请求一个接口并得到接口的指针来查询一个服务是否有效,.NET的客户可以通过反射(reflection)来得到一个对象的功能的描述
• .NET的对象驻留在.NET Framework执行环境管理的内存中,执行环境可以因为性能的原因删除内存中的对象并且更新它删除的对象的所有引用。非托管的客户,得到一个对象的指针,依赖于对象保留在相同的位置。这种客户没有那种处理在内存中不在固定位置的对象的机制。


为了克服这些不同,runtime提供了包装类使得托管代码和非托管代码的客户都认为他们在自己的环境中调用对象的方法。当托管客户调用一个COM对象的方法时,runtime创建一个runtime callable wrapper (RCW)。RCWs抽象了托管代码和非托管代码引用机制的不同。Runtime还创建了一个COM callable wrapper (CCW)来实现其逆过程,使得COM的客户能够无缝的调用.NET对象的方法。如下图所示


COM wrapper overview



在大多数情况下,标准的RCW或者CCW由runtime生成,为跨越COM和.NET Framework的边界调用提供了足够的列集。使用自定义的属性,可以随意的调整runtime表示托管代码和非托管代码的方式

Runtime Callable Wrapper


CLR(common language runtime)通过一个叫做runtime callable wrapper (RCW)的代理(proxy)暴露COM 对象. 虽然RCW对于.NET的客户似乎是一个普通的.NET对象,但是它的主要功能却是在.NET客户和COM对象之间列集调用。


运行时正确的为每个COM对象创建一个RCW,而不管那个对象上存在的引用的个数。如下图所示:任意数量的托管客户可以保持一个暴露INew 和INewer 接口的COM对象的引用。运行时为每个COM对象维护一个单独的RCW。


Accessing COM objects through the runtime callable wrapper



使用来源于类型库(type library)的元数据(metadata),运行库(runtime)创建将被调用COM对象和这个对象的包装(wrapper)。每个RCW维护它所包装的COM对象的接口指针并且在RCW不再需要时释放COM对象。运行库(runtime)在RCW之上作垃圾收集。


在其他的活动中,RCW代表所包装的对象在托管和非托管代码之间列集(marshals)数据。特别的是,RCW在客户和服务有不同的数据表现形式,并需要在他们之间传递数据时,提供方法参数和方法返回值得列集。


标准的wrapper执行内置(built-in)的列集规则。例如:当.NET的客户传递一个String类型作为参数的一部分给托管对象的时候,wrapper把string类型那个转化为BSTR类型。当COM对象返回一个BSTR给托管的调用着的时候,调用着收到一个string。无论是客户还是服务端接受和发送数据都使用自己熟悉的类型。还有一些其他的类型不需要变化,例如:一个标准的wrapper将在托管和非托管代码之间一直传递4-byte integer而不做任何变化。


RCW的主要目标就是隐藏托管代码模型和非托管代码模型之间的差别,实现无缝的传输。RCW使用选择的接口而不把它们暴露给.NET的客户端,如下图所示


COM interfaces and the runtime callable wrapper



当创建一个早期的COM对象的时候,RCW是一个特殊的类型。它实现了COM对象实现的一些接口并且暴露它们的方法,属性和时间。如图所示:RCW暴露了INew接口,但是使用了IUnknown 和IDispatch接口。RCW向.NET客户暴露了INew的所有成员


COM Callable Wrapper


当COM的客户调用.NET的对象时,CLR创建这个托管的对象和这个托管的对象COM callable wrapper(CCW),COM客户可以使用CCW作为托管对象的一个代理,而不能够直接使用.NET的对象。

 
Runtime正确的创建托管对象的CCW,不管要求这个服务的COM客户的数量。如下图所示,多个COM客户可以保持包含INew 接口的CCW的引用,CCW,反过来包含一个实现了接口和垃圾收集的托管对象的单独的引用。COM和.NET的客户可以同时在相同的托管对象是发起调用。


Accessing .NET objects through COM callable wrapper


COM callable wrappers对于运行在.NET Framework上的其他类是不可见的。它们的主要目的是在托管和非托管代码之间列集(marshal)调用,而且CCWs同时也管理着它所包含对象的identity和对象的生存期(lifetime)


Object Identity
运行时(runtime)在它的能够垃圾回收的堆里(garbage-collected heap)为.NET对象分配内存,这能使runtime需要的时候在内存中移动对象。相反,runtime在不能进行垃圾收集的堆上为CCW分配内存,使COM客户能够直接引用它。


Object Lifetime
与它所包含的.NET 对象不同,CCW是一个基于引用计数的传统的COM。当CCW的引用计数减少到0,wrapper释放自己在托管对象上的引用。没有引用的托管的对象在下一次垃圾收集的周期内将被收集。


Customizing Standard Wrappers
这部分将描述如何自定义标准的runtime callable wrappers(RCW) and COM callable wrappers.(CCW)


Runtime Callable Wrappers
当.NET激活一个COM对象时,运行时(runtime)生成一个包含COM类型的runtime callable wrapper (RCW),如下图所示, 运行时(runtime)使用从导入的类型库而得到的元数据(metadata)来生成RCW。Wrapper根据interop marshaling service定义的规则列集数据。


RCW generation and method calls




有两个方式可以自定义RCW。如果你可以修改Interface Definition Language (IDL)的源文件,你可以给type library file (TLB) 添加属性然后导入TLB。还可以应用interop-specific attributes来导入类型生成新的程序集(assembly)支持自定义的标准RCWs被这些attributes限制


To modify the IDL source

1. Apply TLB attributes to libraries, types, members, and parameters. Use the custom keyword and an attribute value to change metadata. By applying TLB attributes, you can:
• Specify the managed name of an imported COM type, instead of allowing the import utility to select the name according to standard conversion rules.
• Explicitly define a destination namespace for the types in a COM library.
2. Compile the IDL source code.
3. Generate an assembly from the resulting type library file or from a dynamic link library file (DLL) that contains the type you intend to implement.


To modify an imported assembly
1. Import the type library file. Use the Type Library Importer (Tlbimp.exe) to generate an assembly DLL.
2. Create a text file from the imported assembly by using the MSIL Disassembler (Ildasm.exe).
3. Apply interop attributes to the text file.
4. Generate a new assembly from the modified text file by using the MSIL Assembler (Ilasm.exe).


 COM Callable Wrappers
COM callable wrapper (CCW) 向COM导出NET Framework对象. 通过把一个托管的工程编译成一个DLL的程序集, 可以自动的创建需要的元数据来描述程序集中的类型. 当一个COM的客户激活托管对象时,运行时使用元数据来生成CCW.
自定义CCW,你的托管的代码要遵循交互规范属性(interop-specific attributes),并且把编译代码编译成程序集,如下图所示,在这个例子中,Tlbexp.exe把托管类型编译为COM


CCW 的生成和方法调用



通过在代码中添加属性,可以在交互列集服务限定的范围内改变接口和数据的列集行为。例如,可以你可以控制方法参数传递的格式,也可以控制程序集中的什么类型暴露给COM


2 .托管和非托管的线程(Managed and Unmanaged Threading)


COM组件使用套间(apartments)来同步资源的访问。与之对应的是,托管对象使用同步区域(synchronized regions),同步原语例如互斥量(mutexes)锁定和完成异步端口,同步上下文来保证所有的共享资源以线程安全的方式被使用。


对于可交互性来说,CLR(common language runtime)在调用COM对象时,创建并初始化一个套间,一个托管的线程可以创建并且进入一个包含一个线程的single-threaded apartment (STA)或者包含多个线程的multi-threaded apartment (MTA)。当COM的套间和线程的套间兼容的时候,COM允许调用的线程直接调用COM对象的方法,如果套间不兼容,COM创建兼容的套间并通过代理列集(marshals)所有的调用。

 
在第一个对非托管代码的调用时,运行时调用CoInitializeEx来初始化MTA或者STA的COM套间。可以使用System.Threading.ApartmentState属性来控制创建的套间的类型是MTA, STA, 或者Unknown.在代理存根或者TLB已经注册后,不一定义定设定要设定这个属性。
下表列出了ApartmentState的枚举值和对应的COM套间初始化调用

ApartmentState enumeration value
COM apartment initialization
MTA
CoInitializeEx(NULL, COINIT_MULTITHREADED)
STA
CoIntializeEx(NULL, COINIT_APARTMENTTHREADED)
Unknown
CoInitializeEx(NULL, COINIT_MULTITHREADED)

COM对象和托管线程在不兼容的套间时,所有的调用都通过COM创建的代理,下面的代码例子显示了怎么在托管代码重创建一个STA套间模型的COM对象AptSimple


[C#]
using System.Threading;
using APTOBJLib;
...
AptSimple obj = new AptSimple ();
obj.Counter = 1;
为了消除代理存根,显著的提高性能,注意创建对象之前的ApartmentState
[C#]
using System.Threading;
using APTOBJLib;
...
Thread.CurrentThread.ApartmentState = ApartmentState.STA;
AptSimple obj = new AptSimple ();
obj.Counter = 1;
设定套间状态之后,可以向下面那样通过程序查询状态
[C#]
Thread.CurrentThread.ApartmentState = ApartmentState.STA;
if (Thread.CurrentThread.ApartmentState == ApartmentState.STA) {
// All is OK.
}
else {
// Incompatible apartment state.
}

3 托管和非托管的事件(Managed and Unmanaged Events)

.NET Framework的事件模型与传统的COM的事件模型不同。托管的事件模型基于委托(delegate),er非托管的事件(在COM中)基于连接点(connection points)。两个模型都是紧耦合的事件系统,因为客户(事件接受者)和服务(事件发送者)必须同时的运行。

这一部分描述了怎样过渡托管和非托管的事件系统,使得对象可以跨域交互边界发送和接收事件。

COM 事件
这部分提供关于连接点的概要介绍以及用来说明COM事件相关的通用术语
连接点在客户和COM的服务器之间确立了一种双向de通信机制。通过这种机制,COM服务器在事件发生时可以回调客户。例如,服务器(像Microsoft Internet Explorer)可以发出一个事件来向客户程序报告一个变化(例如标题变化)。客户创建了一个叫做event sink内部的COM对象来响应通知,当收到通知,客户可以执行事件相关的操作。


event sink提供了向服务器暴露事件相关方法的接口。服务器通过这些事件相关的方法激发事件。客户像实现普通的COM接口一样实现event sink接口。服务器声明这个接口为出接口,COM服务的作者在类型库中队这个接口应用source 属性。服务器使用event sink接口的定义来确定sink并且invoke方法


实现了event sink接口的COM客户通常叫做event sink,或者简单的称为sink。
在下图中,sink实现了ISinkEvents接口,服务器可以激发事件
连接点事件模型(Connection point event model)



event sink的接口确定之后,sink必须与源对象建立连接,连接点的机制使用下面的过程连接sink和source:
1. The sink queries a server object for the IConnectionPointContainer interface. If the object supports connection points, it returns a pointer.
2. Using methods on the container object, the sink locates the IConnectionPoint interface representing a specific connection point. Since a server can support multiple outgoing interfaces, a client must match its sink to the interface identifier (IID) of a particular connection point interface.
3. Having obtained the correct connection point object, the sink calls IConnectionPoint::Advise to register its sink interface pointer. The server (source) holds the connection (and raises events to it) until the client breaks the connection by calling IConnectionPoint::Unadvise.


处理COM源发出的事件(Handling Events Raised by a COM Source)
如果你不熟悉.NET Framework提供的基于委托(delegate-based)的事件模型,参考Handling and Raising Events。

An imported delegate signature comprises the sink event interface, an underscore, the event name, and the word EventHandler: SinkEventInterface_EventNameEventHandler.
.NET的客户(event sink)可以接受现存的COM服务器(event source)的事件。COM interop在你的托管客户的元数据中产生必要的委托。一个导入的委托签名(signature)由sink event接口,一个下划线,事件名称和EventHandler组成


与现存的COM事件源交互(To interoperate with an existing COM event source)
1. Obtain the primary interop assembly for the COM server if the COM types are to be shared by other applications. A primary interop assembly contains metadata representing the converted type library and is signed by the publisher.
Note If the primary interop assembly is not available or if the assembly is to be used privately, you can import the type library by using Tlbimp.exe or an equivalent API.
The conversion process generates a delegate for each event; however, you only have to sink the events that interest you.
2. You can use a metadata browser, such as Ildasm.exe, to identify events delegates.
3. Consume events from the COM event source the same way you consume events from a managed event source.
下面的例子说明了怎样打开一个Internet Explorer窗口,得到Internet Explorer对象发出的事件并在托管的代码中处理。Internet Explorer的类型(包括事件委托)的定义从被SHDocVw.dll导入为元数据,例子激发TitleChange事件
 

[C#]
namespace InternetExplorer
{
    using System;
    using System.Runtime.InteropServices;
    using SHDocVw;
 
    public class Explorer
    {
        public static void Main()
        {
            Explorer explorer = new Explorer();
            explorer.Run();
        }
        public void Run()
        {
            Object o = null;
            String s;
 
            try
            {
                // Starts the browser.
                m_IExplorer = new SHDocVw.InternetExplorer();
            }
            catch(Exception e)
            {
                Console.WriteLine("Exception when creating Internet
                Explorer object {0}", e);
                return;
            }
 
            // Wires your event handlers to m_IExplorer.
            SetAllEvents();
 
            try
            { 
                // Goes to the home page.
                m_WebBrowser = (IWebBrowserApp) m_IExplorer;
                m_WebBrowser.Visible = true;
                m_WebBrowser.GoHome();
 
                // Starts navigating to different URLs.
                Console.Write("Enter URL (or enter to quit): ");
                s = Console.ReadLine();
                while (s != "" && m_IExplorer != null &&
                    m_WebBrowser != null)
                {
                    m_WebBrowser.Navigate(s, ref o, ref o, ref o,
                          ref o);
                    Console.Write("Enter URL (or enter to quit): ");     
                    s = Console.ReadLine();
                }
 
                m_WebBrowser.Quit();
            }
            catch(Exception sE)
            {
                if (m_IExplorer == null && m_WebBrowser == null)
                {
                    Console.WriteLine("Internet Explorer has gone away");
                }
                else
                {
                    Console.WriteLine("Exception happens {0}", sE);
                }
            }
        }
        // Uses the += syntax for adding delegates to events.
        void SetAllEvents()
        {
            if (m_IExplorer != null)
            {
                // Title Change event
                // DWebBrowserEvents2 is the name of the sink event
                //interface.
                // TitleChange is the name of the event.
                // DWebBrowserEvents2_TitleChangeEventHandler is the
                // delegate name assigned by TlbImp.exe.
                DWebBrowserEvents2_TitleChangeEventHandler
     DTitleChangeE = new DWebBrowserEvents2_TitleChangeEventHandler(OnTitleChange);
              m_IExplorer.TitleChange += DTitleChangeE;
            }
        }
///////////////////////////////////////////////////////////////////////
        // Define event handlers.
        // Document title changed
        static void OnTitleChange(String Text)
        {
            Console.WriteLine("Title changes to {0}", Text);
        }
  
//////////////////////////////////////////////////////////////////////////
        // The following are class fields.
        static private SHDocVw.InternetExplorer m_IExplorer = null;
        static private IWebBrowserApp m_WebBrowser = null;
    }
}

posted @ 2007-07-25 11:19 Picasso 阅读(2454) | 评论 (0)编辑 收藏