当前位置:Linux教程 - 编程技术 - 编程技术 - TCPIP完整的一套基础介绍

编程技术 - TCPIP完整的一套基础介绍

TCPIP完整的一套基础介绍
2004-04-23 15:18 pm
来自:Linux文档
现载:Www.8s8s.coM
地址:无名

TCP/IP应该是个协议集,根据OS的七层理论,TCP/IP分为四层.分别是应用,传输,Interne和网络界面.

我们一般说TCP在传输层,而IP在Internet层.

TCP/IP的应用程序包括我们平时经常用到的Ping,Telnet,Ftp,Finger等等

配置TCP/IP包括IP地址,子网掩码和缺省网关

正确检测TCP/IP的四个步骤:PIng 127.0.0.1(回环地址)如果通表示TCP/IP已经装入,Ping自己表明客户机正常(主要是网卡),Ping网关表示局域网正常,Ping路由外地址表示完全正常,当然你也可以直接进行第四步,一般来说没这么麻烦的,但理论是基础:-)

IP地址是四段八位的二进制数组成的,IP分为A,B,C,D,E五类地址

A类高端为0,从1.x.y.z~126.x.y.z .B类高端为10,从128.x.y.z~191.x.y.z C类高端为110,从192.x.y.z~223.x.y.z D类高端为1110是保留的IP地址 E类高端为1111,是科研用的IP地址

其中255是广播地址,127是内部回送函数

以上算是开头,以后一点点增加,实在是现在还有很多事情等着去做,不好意思了 :-)

以下内容是子网的设定

若公司不上Internet,那一定不会烦恼IPAddress的问题,因 为可以任意使用所有的IPAddress,不管是AClass或是BClass, 这个时候不会想到要用SubNet,但若是上Internet那IPAddress 便弥足珍贵了,目前全球一阵Internet热,IPAddress已经愈 来愈少了,而所申请的IPAddress目前也趋保守,而且只有 经申请的IPAddress能在Internet使用,但对某些公司只能申 请到一个CCLass的IPAddress,但又有多个点需要使用,那这 时便需要使用到Subnet,这篇短文说明Subnet的原理及如 何规划。

SubnetMask的介绍
设定任何网路上的任何设备不管是主机、PC、Router等 皆需要设定IPAddress,而跟随著IPAddress的是所谓的NetMask, 这个NetMask主要的目的是由IPAddress中也能获得NetworkNumber ,也就是说IPAddress和NetMask作AND而得到NetworkNumber,如下所 示


IPAddress 192.10.10.611000000.00001010.00001010.00000110
NetMask 255.255.255.011111111.11111111.11111111.00000000
AND -------------------------------------------------------------------
etworkNumber 192.10.10.011000000.00001010.00001010.00000000


NetMask有所谓的预设值,如下所示

ClassIPAddress范围NetMask
A 1.0.0.0-126.255.255.255255.0.0.0
B 128.0.0.0-191.255.255.255255.255.0.0
C 192.0.0.0-223.255.255.255255.255.255.0



在预设的NetMask都只有255的值,在谈到SubnetMask时这个值 便不一定是255了。
在完整一组CClass中如203.67.10.0-203.67.10.255NetMask255.255.255.0, 203.67.10.0称之NetworkNumber(将IPAddress和Netmask作AND),而 203.67.10.255是Broadcast的IPAddress,所以这?两者皆不能使用,实 际只能使用203.67.10.1--203.67.10.254等254个IPAddress,这是以 255.255.255.0作NetMask的结果,而所谓SubnetMsk尚可将整组C Class分成数组NetworkNumber,这要在NEtMask作手脚,若是要将 整组CCLass分成2个NetworkNumber那NetMask设定为255.255.255.192, 若是要将整组CCLass分成8组NetworkNumber则NetMask要为 255.255.255.224,这是怎麽来的,由以上知道NetworkNumber是由IP Address和NetMask作AND而来的,而且将NetMask以二进位表示 法知道是1的会保留,而为0的去掉



192.10.10.193--11000000.00001010.00001010.10000001
255.255.255.0--11111111.11111111.11111111.00000000
--------------------------------------------------------------
192.10.10.0--11000000.00001010.00001010.00000000


以上是以255.255.255.0为NetMask的结果,NetworkNumber是192.10.10.0, 若是使用255.255.255.224作NetMask结果便有所不同


192.10.10.193--11000000.00001010.00001010.10000000
255.255.255.224--11111111.11111111.11111111.11100000
--------------------------------------------------------------
192.10.10.192--11000000.00001010.00001010.10000000


此时NetworkNumber变成了192.10.10.192,这便是Subnet。
那要如何决定所使用的NetMask,255.255.255.224以二进位表示 法为11111111.11111111.11111111.11100000,变化是在最後一组,11100000 便是224,以三个Bit可表示2的3次方便是8个NetworkNumber

NetMask二进位表示法可分几个Network

255.255.255.0 11111111.11111111.11111111.000000001
255.255.255.128 11111111.11111111.11111111.100000002
255.255.255.192 11111111.11111111.11111111.110000004
255.255.255.224 11111111.11111111.11111111.111000008
255.255.255.240 11111111.11111111.11111111.1111000016
255.255.255.248 11111111.11111111.11111111.1111100032
255.255.255.252 11111111.11111111.11111111.1111110064



以下使用255.255.255.224将C Class203.67.10.0分成8组NetworkNumber,各 个NetworkNumber及其BroadcastIPAddress及可使用之IPAddress

序号NetworkNumberBroadcast可使用之IPAddress

1 203.67.10.0 203.67.10.31 203.67.10.1-203.67.10.30
2 203.67.10.32 203.67.10.63 203.67.10.33-203.67.10.62
3 203.67.10.64 203.67.10.95 203.67.10.65-203.67.10.94
4 203.67.10.96 203.67.10.127 203.67.10.97-203.67.10.126
5 203.67.10.128 203.67.10.159 203.67.10.129-203.67.10.158
6 203.67.10.160 203.67.10.191 203.67.10.161-203.67.10.190
7 203.67.10.192 203.67.10.223 203.67.10.193-203.67.10.222
8 203.67.10.224 203.67.10.255 203.67.10.225-203.67.10.254



可验证所使用的IPAddress是否如上表所示

203.67.10.115--11001011.01000011.00001010.01110011
255.255.255.224--11111111.11111111.11111111.11100000
--------------------------------------------------------------
203.67.10.96--11001011.01000011.00001010.01100000

203.67.10.55--11001011.01000011.00001010.00110111
255.255.255.224--11111111.11111111.11111111.11100000
--------------------------------------------------------------
203.67.10.32--11001011.01000011.00001010.00100000

其他的NetMask所分成的NetworkNumber可自行以上述方法自行推演出来。

Subnet的应用
使用Subnet是要解决只有一组CClass但需要数个NetworkNumber的问题,并不是解决IPAddress不够用的问题,因为使用 Subnet反而能使用的IPAddress会变少,Subnet通常是使用在总公司在台北,但分公司在台中,两者之间使用Router连线 ,同时也上Internet,但只申请到一组CCLassIPAddress,过Router又需不同的Network,所以此时就必须使用到Subnet,当然二 办公司间可以RemoteBridge连接,那便没有使用Subnet的问题,这点在此不讨论,所以在以上情况下的网路连线架 构及IPAddress的使用


TCP/IP(传输控制协议/网间协议)是一种网络通信协议,它规范了网络上的所有通信设备,尤其是一个主机与另一个主机之间的数据往来格式以及传送方式。TCP/IP是INTERNET的基础协议,也是一种电脑数据打包和寻址的标准方法。在数据传送中,可以形象地理解为有两个信封,TCP和IP就像是信封,要传递的信息被划分成若干段,每一段塞入一个TCP信封,并在该信封面上记录有分段号的信息,再将TCP信封塞入IP大信封,发送上网。在接受端,一个TCP软件包收集信封,抽出数据,按发送前的顺序还原,并加以校验,若发现差错,TCP将会要求重发。因此,TCP/IP在INTERNET中几乎可以无差错地传送数据。


在任何一个物理网络中,各站点都有一个机器可识别的地址,该地址叫做物理地址.物理地址有两个

特点:
物理地址的长度,格式等是物理网络技术的一部分,物理网络不同,物理地址也不同.
同一类型不同网络上的站点可能拥有相同的物理地址.
以上两点决定了,不能用物理网络进行网间网通讯.

在网络术语中,协议中,协议是为了在两台计算机之间交换数据而预先规定的标准。TCP/IP并不是一个而是许多协议,这就是为什么你经常听到它代表一个协议集的原因,而TCP和IP只是其中两个基本协议而已。

你装在计算机-的TCP/IP软件提供了一个包括TCP、IP以及TCP/IP协议集中其它协议的工具平台。特别是它包括一些高层次的应用程序和FTP(文件传输协议),它允许用户在命令行上进行网络文件传输。

TCP/IP是美国政府资助的高级研究计划署(ARPA)在二十世纪七十年代的一个研究成果,用来使全球的研究网络联在一起形成一个虚拟网络,也就是国际互联网。原始的

Internet通过将已有的网络如ARPAnet转换到TCP/IP上来而形成,而这个Internet最终成为如今的国际互联网的骨干网。

如今TCP/IP如此重要的原因,在于它允许独立的网格加入到Internet或组织在一起形成私有的内部网(Intranet)。构成内部网的每个网络通过一种-做路由器或IP路由器的设备在物理上联接在一起。路由器是一台用来从一个网络到另一个网络传输数据包的计算机。在一个使用TCP/IP的内部网中,信息通过使用一种独立的叫做IP包(IPpacket)或IP数据报(IPdatagrams)的数据单元进--传输。TCP/IP软件使得每台联到网络上的计算机同其它计算机“看”起来一模一样,事实上它隐藏了路由器和基本的网络体系结构并使其各方面看起来都像一个大网。如同联入以太网时需要确认一个48位的以太网地址一样,联入一个内部网也需要确认一个32位的IP地址。我们将它用带点的十进制数表示,如128.10.2.3。给定一个远程计算机的IP地址,在某个内部网或Internet上的本地计算机就可以像处在同一个物理网络中的两台计算机那样向远程计算机发送数据。

TCP/IP提供了一个方案用来解决属于同一个内部网而分属不同物理网的两台计算机之间怎样交换数据的问题。这个方案包括许多部分,而TCP/IP协议集的每个成员则用来解决问题的某一部分。如TCP/IP协议集中最基本的协议-IP协议用来在内部网中交换数据并且执行一项重要的功能:路由选择--选择数据报从A主机到B主机将要经过的路径以及利用合适的路由器完成不同网络之间的跨越(hop)。

TCP是一个更高层次的它允许运行在在不同主机上的应用程序相互交换数据流。TCP将数据流分成小段叫做TCP数据段(TCPsegments),并利用IP协议进行传输。在大多数情况下,每个TCP数据段装在一个IP数据报中进行发送。但如需要的话,TCP将把数据段分成多个数据报,而IP数据报则与同一网络不同主机间传输位流和字节流的物理数据帧相容。由于IP并不能保证接收的数据报的顺序相一致,TCP会在收信端装配TCP数据段并形成一个不间断的数据流。FTP和Telnet就是两个非常流行的依靠TCP的TCP/IP应用程序。

另一个重要的TCP/IP协议集的成员是用户数据报协议(UDP),它同TCP相似但比TCP原始许多。TCP是一个可靠的协议,因为它有错误检查和握手确认来保证数据完整的到达目的地。UDP是一个“不可靠”的协议,因为它不能保证数据报的接收顺序同发送顺序相同,甚至不能保证它们是否全部到达。如果有可靠性要求,则应用程序避免使用它。同许多TCP/IP工具同时提供的SNMP(简单网络管理协议)就是一个使用UDP协议的应用例子。

其它TCP/IP协议在TCP/IP网络中工作在幕后,但同样也发挥着重要作用。例如地址转换协议(ARP)将IP地址转换为物理网络地址如以太网地址。而与其对应的反向地址转换协议(RARP)做相反的工作,即将物理网络地址转换为IP地址。网际控制报文协议(ICMP)则是一个支持性协议,它利用IP完成IP数据报在传输时的控制信息和错误信息的传输。例如,如果一个路由器不能向前发送一个IP数据报,它就会利用ICMP来告诉发送者这里出现了问题。


网络设计者在解决网络体系结构时经常使用ISO/OSI( 国际标准化组织/开放系统互连)七层模型,该模型每 一层代表一定层次的网络功能。最下面是物理层,它 代表着进行数据转输的物理介质,换句话说,即网络 电缆。其上是数据链路层,它通过网络接口卡提供服 务。最上层是应用层,这里运行着使用网络服务的应 用程序。

TCP/IP是同ISO/OSI模型等价的。当一个数据单元 从网络应用程序下流到网络接口卡,它通过了一列的TCP/IP 模块。这其中的每一步,数据单元都会同网络另一端 对等TCP/IP模块所需的信息一起打成包。这样当数据最 终传到网卡时,它成了一个标准的以太帧(假设物理 网络是以太网)。而接收端的TCP/IP软件通过剥去以太网 帧并将数据向上传输过TCP/IP栈来为处于接收状态的应 用程序重新恢复原始数据(一种最好的了解TCP/IP工作实 质的方法,是使用探测程序来观察网络中的到处流动 的帧中被不同TCP/IP模块所加上的信息)。

为了勾勒TCP/IP在现实网络世界中所扮演的角色, 请考虑当使用HTTP(超文本传输协议)的Web浏览器从连接 在Internet上的Web服务器上获取一页HTML数据时所发生的情 况。为形成同Web服务器的虚链路,浏览器使用一种被 抽象地称为套接口(socket)的高层软件。为了获 取Web页,它通过向套接口向套接口写入HTTPGET命令来向Web 服务器发出该指令。接下来套接口软件使用TCP协议向 Web服务器发出包含GET命令的字节流和位流,TCP将数据 分段并将各独立段传到IP模块,该模块将数据段转换 成数据报并发送给Web服务器。

如果浏览器和服务器运--在不同物理网络的计 算机上(一般情况如此),数据报从一个网络传到另一 个网络,直到抵达服务器所在的那个网。最终,数据 被传输到目的地址并被重新装配,这样Web服务器通过 读自己的套接口来获得数据主干,并进而查看连续的 数据流。对浏览器和服务器来说,数据在这一端写入 套接口而在另一端出现如同魔术一般,但这只是底 下发生的各种复杂的交互,它创造了数据经过网络无 缝传输的假象。

这就是TCP/IP所做的:将许多小网联成一个大网。 并在这个大网也就是Internet上提供应用程序所需要的 相互通信的服务。

评论:

对于TCP/IP有许多可谈的,但这里仅讲三个关键 点:

·TCP/IP是一族用来把不同的物理网络联在一 起构成网际网的协议。TCP/IP联接独立的网络形成一个 虚拟的网,在网内用来确认各种独立的不是物理网络 地址,而是IP地址。

·TCP/IP使用多层体系结构,该结构清晰定义了 每个协议的责任。TCP和UDP向网络应用程序提供了高层 的数据传输服务,并都需要IP来传输数据包。IP有责任 为数据包到达目的地选择合适的路由。

·在Internet主机上,两个运行着的应用程序之 间传送要通过主机的TCP/IP堆栈上下移动。在发送端TCP/IP 模块加在数据上的信息将在接收端对应的TCP/IP模块上 滤掉,并将最终恢复原始数据。

如果你有兴趣学习更多的TCP/IP知识,这里有两个 较高层次的信息源RFC(RequestforComment)1180——叫做“TCP/IP Tutorial”的文档,你可以从许多普及的RFC的Internet节点上 下载。另一个是InternetworkingwithTCP/IP的第一卷:Principles,Protocols,and Architectures,作者DouglasE.Comer(1995,Prentice-Hall)。作为该系三部 曲中的第一部分,许多人把看成是一本TCP/IP圣经。(原 文刊载于Vol.15No.20)



二、传输层的安全性

在Internet应用编程序中,通常使用广义的进程间通信(IPC)机制来与不同层次的安全协议打交道。比较流行的两个IPC编程界面是BSD Sockets和传输层界面(TLI),在Unix系统V命令里可以找到。

在Internet中提供安全服务的首先一个想法便是强化它的IPC界面,如BSD Sockets等,具体做法包括双端实体的认证,数据加密密钥的交换等。Netscape通信公司遵循了这个思路,制定了建立在可靠的传输服务(如TCP/IP所提供)基础上的安全套接层协议(SSL)。SSL版本3(SSL v3)于1995年12月制定。它主要包含以下两个协议:

SSL记录协议 它涉及应用程序提供的信息的分段、压缩、数据认证和加密。SSL v3提供对数据认证用的MD5和SHA以及数据加密用的R4和DES等的支持,用来对数据进行认证和加密的密钥可以通过SSL的握手协议来协商。
SSL握手协议 用来交换版本号、加密算法、(相互)身份认证并交换密钥。SSL v3 提供对Deffie-Hellman密钥交换算法、基于RSA的密钥交换机制和另一种实现在 Fortezza chip上的密钥交换机制的支持。
Netscape通信公司已经向公众推出了SSL的参考实现(称为SSLref)。另一免费的SSL实现叫做SSLeay。SSLref和SSLeay均可给任何TCP/IP应用提供SSL功能。Internet号码分配当局(IANA)已经为具备SSL功能的应用分配了固定端口号,例如,带SSL的 HTTP(https)被分配的端口号为443,带SSL的SMTP(ssmtp)被分配的端口号为465,带SSL的NNTP(snntp)被分配的端口号为563。

微软推出了SSL2的改进版本称为PCT(私人通信技术)。至少从它使用的记录格式来看,SSL和PCT是十分相似的。它们的主要差别是它们在版本号字段的最显著位(The Most Significant Bit)上的取值有所不同: SSL该位取0,PCT该位取1。这样区分之后,就可以对这两个协议都给以支持。

1996年4月,IETF授权一个传输层安全(TLS)工作组着手制定一个传输层安全协议(TLSP),以便作为标准提案向IESG正式提交。TLSP将会在许多地方酷似SSL。

前面已介绍Internet层安全机制的主要优点是它的透明性,即安全服务的提供不要求应用层做任何改变。这对传输层来说是做不到的。原则上,任何TCP/IP应用,只要应用传输层安全协议,比如说SSL或PCT,就必定要进行若干修改以增加相应的功能,并使用(稍微)不同的IPC界面。于是,传输层安全机制的主要缺点就是要对传输层IPC界面和应用程序两端都进行修改。可是,比起Internet层和应用层的安全机制来,这里的修改还是相当小的。另一个缺点是,基于UDP的通信很难在传输层建立起安全机制来。同网络层安全机制相比,传输层安全机制的主要优点是它提供基于进程对进程的(而不是主机对主机的)安全服务。这一成就如果再加上应用级的安全服务,就可以再向前跨越一大步了。




三、应用层的安全性
必须牢记(且须仔细品味): 网络层(传输层)的安全协议允许为主机(进程)之间的数据通道增加安全属性。本质上,这意味着真正的(或许再加上机密的)数据通道还是建立在主机(或进程)之间,但却不可能区分在同一通道上传输的一个具体文件的安全性要求。比如说,如果一个主机与另一个主机之间建立起一条安全的IP通道,那么所有在这条通道上传输的IP包就都要自动地被加密。同样,如果一个进程和另一个进程之间通过传输层安全协议建立起了一条安全的数据通道,那么两个进程间传输的所有消息就都要自动地被加密。

如果确实想要区分一个具体文件的不同的安全性要求,那就必须借助于应用层的安全性。提供应用层的安全服务实际上是最灵活的处理单个文件安全性的手段。例如一个电子邮件系统可能需要对要发出的信件的个别段落实施数据签名。较低层的协议提供的安全功能一般不会知道任何要发出的信件的段落结构,从而不可能知道该对哪一部分进行签名。只有应用层是唯一能够提供这种安全服务的层次。

一般来说,在应用层提供安全服务有几种可能的做法,第一个想到的做法大概就是对每个应用(及应用协议)分别进行修改。一些重要的TCP/IP应用已经这样做了。在RFC 1421至1424中,IETF规定了私用强化邮件(PEM)来为基于SMTP的电子邮件系统提供安全服务。由于种种理由,Internet业界采纳PEM的步子还是太慢,一个主要的原因是PEM依赖于一个既存的、完全可操作的PKI(公钥基础结构)。PEM PKI是按层次组织的,由下述三个层次构成:

顶层为Internet安全政策登记机构(IPRA)
次层为安全政策证书颁发机构(PCA)
底层为证书颁发机构(CA)
建立一个符合PEM规范的PKI也是一个政治性的过程,因为它需要多方在一个共同点上达成信任。不幸的是,历史表明,政治性的过程总是需要时间的,作为一个中间步骤,Phil Zimmermann开发了一个软件包,叫做PGP(pretty Good Privacy)。PGP符合PEM的绝大多数规范,但不必要求PKI的存在。相反,它采用了分布式的信任模型,即由每个用户自己决定该信任哪些其他用户。因此,PGP不是去推广一个全局的PKI,而是让用户自己建立自己的信任之网。这就立刻产生一个问题,就是分布式的信任模型下,密钥废除了怎么办。

S-HTTP是Web上使用的超文本传输协议(HTTP)的安全增强版本,由企业集成技术公司设计。S-HTTP提供了文件级的安全机制,因此每个文件都可以被设成私人/签字状态。用作加密及签名的算法可以由参与通信的收发双方协商。S-HTTP提供了对多种单向散列(Hash)函数的支持,如: MD2,MD5及SHA; 对多种单钥体制的支持,如:DES,三元DES,RC2,RC4,以及CDMF; 对数字签名体制的支持,如: RSA和DSS。

目前还没有Web安全性的公认标准。这样的标准只能由WWW Consortium,IETF或其他有关的标准化组织来制定。而正式的标准化过程是漫长的,可能要拖上好几年,直到所有的标准化组织都充分认识到Web安全的重要性。S-HTTP和SSL是从不同角度提供Web的安全性的。S-HTTP对单个文件作"私人/签字"之区分,而SSL则把参与通信的相应进程之间的数据通道按"私用"和"已认证"进行监管。Terisa公司的SecureWeb工具软件包可以用来为任何Web应用提供安全功能。该工具软件包提供有 RSA数据安全公司的加密算法库,并提供对SSL和S-HTTP的全面支持。

另一个重要的应用是电子商务,尤其是信用卡交易。为使Internet上的信用卡交易安全起见,MasterCard公司(同IBM,Netscape,GTE和Cybercash一道) 制定了安全电子付费协议(SEPP),Visa国际公司和微软(和其他一些公司一道)制定了安全交易技术(STT)协议。同时,MasterCard,Visa国际和微软已经同意联手推出Internet上的安全信用卡交易服务。他们发布了相应的安全电子交易(SET)协议,其中规定了信用卡持卡人用其信用卡通过Internet进行付费的方法。这套机制的后台有一个证书颁发的基础结构,提供对X.509证书的支持。

上面提到的所有这些加安全功能的应用都会面临一个主要的问题,就是每个这样的应用都要单独进行相应的修改。因此,如果能有一个统一的修改手段,那就好多了。通往这个方向的一个步骤就是赫尔辛基大学的Tatu Yloenen开发的安全shell(SSH)。SSH允许其用户安全地登录到远程主机上,执行命令,传输文件。它实现了一个密钥交换协议,以及主机及客户端认证协议。SSH有当今流行的多种Unix系统平台上的免费版本,也有由Data Fellows公司包装上市的商品化版本。

把SSH的思路再往前推进一步,就到了认证和密钥分配系统。本质上,认证和密钥分配系统提供的是一个应用编程界面(API),它可以用来为任何网络应用程序提供安全服务,例如: 认证、数据机密性和完整性、访问控制以及非否认服务。目前已经有一些实用的认证和密钥分配系统,如: MIT的Kerberos(V4与V5),IBM的CryptoKnight和Netwrok Security Program,DEC的SPX,Karlsruhe大学的指数安全系统(TESS)等,都是得到广泛采用的实例。甚至可以见到对有些认证和密钥分配系统的修改和扩充。例如,SESAME和OSF DCE对Kerberos V5作了增加访问控制服务的扩充,Yaksha对Kerberos V5作了增加非否认服务的扩充。

关于认证和密钥分配系统的一个经常遇到的问题是关于它们在Internet上所受到的冷遇。一个原因是它仍要求对应用本身做出改动。考虑到这一点,对一个认证和密钥分配系统来说,提供一个标准化的安全API就显得格外重要。能做到这一点,开发人员就不必再为增加很少的安全功能而对整个应用程序大动手术了。因此,认证系统设计领域内最主要的进展之一就是制定了标准化的安全API,即通用安全服务API(GSS-API)。GSS-API(v1及v2)对于一个非安全专家的编程人员来说可能仍显得过于技术化了些,但德州Austin大学的研究者们开发的安全网络编程(SNP),把界面做到了比GSS-API更高的层次,使同网络安全性有关的编程更加方便了。


局域网在网络层有什么不安全的地方?

NAI公司 供稿

不安全的地方

由于局域网中采用广播方式,因此,若在某个广播域中可以侦听到所有的信息包,黑客就对可以对信息包进行分析,那么本广播域的信息传递都会暴露在黑客面前。

网络分段

网络分段是保证安全的一项重要措施,同时也是一项基本措施,其指导思想在于将非法用户与网络资源相互隔离,从而达到限制用户非法访问的目的。

网络分段可分为物理分段和逻辑分段两种方式:
物理分段通常是指将网络从物理层和数据链路层(ISO/OSI模型中的第一层和第二层)上分为若干网段,各网段相互之间无法进行直接通讯。目前,许多交换机都有一定的访问控制能力,可实现对网络的物理分段。逻辑分段则是指将整个系统在网络层(ISO/OSI模型中的第三层)上进行分段。例如,对于TCP/IP网络,可把网络分成若干IP子网,各子网间必须通过路由器、路由交换机、网关或防火墙等设备进行连接,利用这些中间设备(含软件、硬件)的安全机制来控制各子网间的访问。在实际应用过程中,通常采取物理分段与逻辑分段相结合的方法来实现对网络系统的安全性控制。


VLAN的实现


虚拟网技术主要基于近年发展的局域网交换技术(ATM和以太网交换)。交换技术将传统的基于广播的局域网技术发展为面向连接的技术。因此,网管系统有能力限制局域网通讯的范围而无需通过开销很大的路由器。

以太网从本质上基于广播机制,但应用了交换器和VLAN技术后,实际上转变为点到点通讯,除非设置了监听口,信息交换也不会存在监听和插入(改变)问题。

由以上运行机制带来的网络安全的好处是显而易见的:
信息只到达应该到达的地点。因此、防止了大部分基于网络监听的入侵手段。
通过虚拟网设置的访问控制,使在虚拟网外的网络节点不能直接访问虚拟网内节点。

但是,虚拟网技术也带来了新的安全问题:
执行虚拟网交换的设备越来越复杂,从而成为被攻击的对象。基于网络广播原理的入侵监控技术在高速交换网络内需要特殊的设置。基于MAC的VLAN不能防止MAC欺骗攻击。
采用基于MAC的VLAN划分将面临假冒MAC地址的攻击。因此,VLAN的划分最好基于交换机端口。但这要求整个网络桌面使用交换端口或每个交换端口所在的网段机器均属于相同的VLAN。


VLAN之间的划分原则

VLAN的划分方式的目的是保证系统的安全性。因此,可以按照系统的安全性来划分VLAN;可以将总部中的服务器系统单独划作一个VLAN,如数据库服务器、电子邮件服务器等。也可以按照机构的设置来划分VLAN,如将领导所在的网络单独作为一个Leader VLAN(LVLAN), 其他司局(或下级机构)分别作为一个VLAN,并且控制LVLAN与其他VLAN之间的单向信息流向,即允许LVLAN查看其他VLAN的相关信息,其他VLAN不能访问LVLAN的信息。VLAN之内的连接采用交换实现, VLAN与VLAN之间采用路由实现。由于路由控制的能力有限,不能实现LVLAN与其他VLAN之间的单向信息流动,需要在LVLAN与其他VLAN之间设置一个Gauntlet防火墙作为安全隔离设备,控制VLAN与VLAN之间的信息交流
 
□…… 共享软件前景分析
- + 返回页首 + -
近年来,随着互联网的迅速发展和普及,用户应用水平的不断提高, 以及对实用软件的需求日益加大,商业软件已难以满足网民的多方面需求,于是各种共享软件的出现逐渐开始“填补”商业软件的市场“空白”。

共享软件由于价廉物美,有些甚至是完全免费且附带源代码,所以用户增长很快,部分共享软件的用户甚至超过了商业软件。无疑,共享软件的交流是促进科技转化为生产力的一种途径, 其中不乏有经过多年潜心研究的具有较高学术价值的科研成果, 笔者所见的一些商业软件的开发思路都是从这些数目庞大的共享软件中产生的。

然而,我们看到或听到更多的是,一些软件作者因为各种原因而无法进行“扩大再生产”的故事。许多优秀的共享软件中途夭折,甚至作者本人因心灰意冷而离开了“共享软件”的阵营。而一直以来,共享软件作者和媒体宣传者给国产共享软件涂上了过多的艰苦奋斗和惨淡的悲情色彩,大叹“付出没有回报”的同时又以极其羡慕和嫉妒的目光注视着国外Winzip、ACDSee等著名的共享软件,这些国外同行们凭着注册费用就获得了不菲的收入,甚至支撑了整个公司的运营。

全都挤到一座独木桥上,焉能不一个个下马就擒

随便进入国内任何一个下载站点的国产共享软件栏目,都可以看到这样的一个事实:满眼尽是Email收发软件,搜索辅助软件,视(音)频播放软件,财务和股票软件:重复的无意义劳动太多!由于有了各种各样的“可视化”编程工具,以及互联网上星罗棋布的“控件”和源代码,使得编写入门程序变得轻松容易起来。再加上,多年来激烈的竞争使题材与表现手法的创新变得很难,往往是某个好软件刚走红,马上就会被淹没在模仿者的“汪洋大海”之中,“撞车”现象比比皆是。全都挤到一座独木桥上,焉能不一个个下马就擒。而当用户需要面临许多选择时,他们的选择往往是不再选择。

此是共享软件没有创新思想和市场观念的一面。

一个成熟的市场是富有层次的市场。对于潜在的消费群体,应该根据其年龄、职业、收入、文化程度、社区环境等各种因素进行合理有效的细分,从而明确需求,正确地定位软件内容和营销手段,最终达到预期的商业目的,这就是现代市场营销学理论所强调的市场细分。实际上,系统而细致的细分工作是将市场这块“蛋糕”做大、做好的前提。在此过程中,还要考虑到其他诸如地域特征、购买力等因素。于是便很容易构建出一个多维的立体空间。在这样广阔的天地里,相信每一个共享软件作者都应该而且能够找到适合自己的位置。

事实上,别人做普通的Email,你可以做专门用于hotmail等web免费邮箱客户端Email收发,或专门用来投稿或联系VC的Mail等等。记得新加坡过去有个带宠物的Email软件就很是红火了两年。

原有的共享软件作者在转变思路之后,完全可以摆脱悲剧的阴影

笔者所认识的共享软件作者中有一些还只是满足于把软件“做出来”,然后渴望被大的软件下载站点收录并评个X星级什么的,其他的用户咨询、答疑和升级就都不管了,还挂出个“终结版”的大旗,大有舍我其谁的气概。而有的人写共享软件也只是向大家表明:自己会以编程来招揽软件开发任务。更有甚者,写共享软件只是为了最终找到一份满意的工作。

世界第二大独立软件公司CA(Computer Associates International Inc.)的掌门人王嘉廉曾这样说过:“中国有优秀的软件人才,但中国缺少的是系统开发能力、软件产品商品化的能力,以及在全球市场经销软件产品的经验。”

王先生的话笔者是非常赞成的。但是,我们不能过高地期望软件作者可以与大的软件公司一样完成集成和规模开发,也不能强迫以“自由”为根本特征的共享软件作者会走到一起来集体开发规模软件。很多“集团开发”失败的案例已经充分证明了这一点。我们只是希望原来的共享软件作者可以摆脱过去“诉苦”、“委屈”、“悲哀”的悲剧阴影,而且会有越来越多的人加入到共享软件的“欢乐大本营”中来。

共享软件也是一种商品,它也需要进行策略性的市场推广

事实上,共享软件和商业软件一样都是一种商品,而并不在于收费多少或者免费。商品的“销售”需要售前和售后服务,更需要进行策略性的市场推广。

国外那些共享软件能够获得巨大的成功,我想,如果他们仅仅满足于温饱,或许早就停止了开放的步伐。而事实上,他们通过市场运营做得越来越好,很多人都知道,zipmagic比起Winzip来可能还要好用,但绝对不如Winzip挣钱挣得多,它输在哪里,不是输在软件的品质,而是市场的运作上。

我们就看共享软件的推广最基本的一个方面:“免费”。这里的“免费”可以是开始的版本“免费”,或提供“免费”的限制功能版。“免费”的目的是使得软件上市初始价格的无限最小化,这样通过圈定特定的使用人群来获得自己的市场领地和份额。

然而,免费也需要策略和最终目的,从开始免费之前就应首先考虑将来如何收费。笔者曾见到这样一种现象:有些优秀的软件进入“免费”的怪圈而不可自拔,最终作者本人不能得到他的收益又怨天尤人,却未曾想自己的失败之处和免费给他带来的名誉与用户。

当然,我们在就目前存在的问题来分析共享软件的同时,也应看到未来的趋势:不久,我们将面临软件行业的重新定位。软件作为一种服务,被捆绑在其他的服务之上,如:网络游戏软件可能成为宽带网络ISP所提供服务的一种,收费方式更加灵活,而不需要人们购买任何有形的东西即可得到这种服务。

面对如此多的阻碍与困难,站在今天的起点遥看中国共享软件的前途,我只能用一句话来表达:路还很长。
 
□…… Windows 2000下的Raw Socket编程
- + 返回页首 + -
Windows2000在TCP/IP协议组件上做了很多改进,功能也有增强。比如在协议栈上的调整,增大了默认窗口大小,以及高延迟链接新算法。同时在安全性上,可应用IPSec加强安全性,比NT下有不少的改进。

Microsoft TCP/IP 组件包含“核心协议”、“服务”及两者之间的“接口”。传输驱动程序接口 (TDI) 与网络设备接口规范 (NDIS) 是公用的。 此外,还有许多用户模型应用程序的更高级接口。最常用的接口是 Windows Sockets、远程过程调用 (RPC) 和 NetBIOS。

Windows Sockets 是一个编程接口,它是在加州大学伯克利分校开发的套接字接口的基础上定义的。它包括了一组扩展件,以充分利用 Microsoft Windows 消息驱动的特点。规范的 1.1 版是在 1993 年 1 月发行的,2.2.0 版在 1996 年 5 月发行。Windows 2000 支持 Winsock 2.2 版。在Winsock2中,支持多个传输协议的原始套接字,重叠I/O模型、服务质量控制等。

这里介绍Windows Sockets的一些关于原始套接字(Raw Socket)的编程。同Winsock1相比,最明显的就是支持了Raw Socket套接字类型,通过原始套接字,我们可以更加自如地控制Windows下的多种协议,而且能够对网络底层的传输机制进行控制。

1、创建一个原始套接字,并设置IP头选项。

SOCKET sock;
sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP);
或者:
s = WSASoccket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED);

这里,我们设置了SOCK_RAW标志,表示我们声明的是一个原始套接字类型。创建原始套接字后,IP头就会包含在接收的数据中,如果我们设定 IP_HDRINCL 选项,那么,就需要自己来构造IP头。注意,如果设置IP_HDRINCL 选项,那么必须具有 administrator权限,要不就必须修改注册表:
HKEY_LOCAL_MACHINESystemCurrentControlSetServicesAfdParameter
修改键:DisableRawSecurity(类型为DWORD),把值修改为 1。如果没有,就添加。

BOOL blnFlag=TRUE;
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&blnFlag, sizeof(blnFlag);

对于原始套接字在接收数据报的时候,要注意这么几点:
1、如果接收的数据报中协议类型和定义的原始套接字匹配,那么,接收的所有数据就拷贝到套接字中。
2、如果绑定了本地地址,那么只有接收数据IP头中对应的远端地址匹配,接收的数据就拷贝到套接字中。
3、如果定义的是外部地址,比如使用connect(),那么,只有接收数据IP头中对应的源地址匹配,接收的数据就拷贝到套接字中。


2、构造IP头和TCP头

这里,提供IP头和TCP头的结构:
// Standard TCP flags
#define URG 0x20
#define ACK 0x10
#define PSH 0x08
#define RST 0x04
#define SYN 0x02
#define FIN 0x01
typedef struct _iphdr //定义IP首部
{
unsigned char h_lenver; //4位首部长度+4位IP版本号
unsigned char tos; //8位服务类型TOS
unsigned short total_len; //16位总长度(字节)
unsigned short ident; //16位标识
unsigned short frag_and_flags; //3位标志位
unsigned char ttl; //8位生存时间 TTL
unsigned char proto; //8位协议 (TCP, UDP 或其他)
unsigned short checksum; //16位IP首部校验和
unsigned int sourceIP; //32位源IP地址
unsigned int destIP; //32位目的IP地址
}IP_HEADER;

typedef struct psd_hdr //定义TCP伪首部
{
unsigned long saddr; //源地址
unsigned long daddr; //目的地址
char mbz;
char ptcl; //协议类型
unsigned short tcpl; //TCP长度
}PSD_HEADER;

typedef struct _tcphdr //定义TCP首部
{
USHORT th_sport; //16位源端口
USHORT th_dport; //16位目的端口
unsigned int th_seq; //32位序列号
unsigned int th_ack; //32位确认号
unsigned char th_lenres; //4位首部长度/6位保留字
unsigned char th_flag; //6位标志位
USHORT th_win; //16位窗口大小
USHORT th_sum; //16位校验和
USHORT th_urp; //16位紧急数据偏移量
}TCP_HEADER;

TCP伪首部并不是真正存在的,只是用于计算检验和。校验和函数:

USHORT checksum(USHORT *buffer, int size)
{
unsigned long cksum=0;
while (size > 1)
{
cksum += *buffer++;
size -= sizeof(USHORT);
}
if (size)
{
cksum += *(UCHAR*)buffer;
}
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (USHORT)(~cksum);
}

当需要自己填充IP头部和TCP头部的时候,就同时需要自己计算他们的检验和。

3、发送原始套接字数据报

填充这些头部稍微麻烦点,发送就相对简单多了。只需要使用sendto()就OK。

sendto(sock, (char*)&tcpHeader, sizeof(tcpHeader), 0, (sockaddr*)&addr_in,sizeof(addr_in));

下面是一个示例程序,可以作为SYN扫描的一部分。

#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>

#define SOURCE_PORT 7234
#define MAX_RECEIVEBYTE 255

typedef struct ip_hdr //定义IP首部
{
unsigned char h_verlen; //4位首部长度,4位IP版本号
unsigned char tos; //8位服务类型TOS
unsigned short total_len; //16位总长度(字节)
unsigned short ident; //16位标识
unsigned short frag_and_flags; //3位标志位
unsigned char ttl; //8位生存时间 TTL
unsigned char proto; //8位协议 (TCP, UDP 或其他)
unsigned short checksum; //16位IP首部校验和
unsigned int sourceIP; //32位源IP地址
unsigned int destIP; //32位目的IP地址
}IPHEADER;

typedef struct tsd_hdr //定义TCP伪首部
{
unsigned long saddr; //源地址
unsigned long daddr; //目的地址
char mbz;
char ptcl; //协议类型
unsigned short tcpl; //TCP长度
}PSDHEADER;

typedef struct tcp_hdr //定义TCP首部
{
USHORT th_sport; //16位源端口
USHORT th_dport; //16位目的端口
unsigned int th_seq; //32位序列号
unsigned int th_ack; //32位确认号
unsigned char th_lenres; //4位首部长度/6位保留字
unsigned char th_flag; //6位标志位
USHORT th_win; //16位窗口大小
USHORT th_sum; //16位校验和
USHORT th_urp; //16位紧急数据偏移量
}TCPHEADER;

//CheckSum:计算校验和的子函数
USHORT checksum(USHORT *buffer, int size)
{
unsigned long cksum=0;
while(size >1)
{
cksum+=*buffer++;
size -=sizeof(USHORT);
}
if(size )
{
cksum += *(UCHAR*)buffer;
}

cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (USHORT)(~cksum);
}

void useage()
{
printf("****************************************** ");
printf("TCPPing ");
printf(" Written by Refdom ");
printf(" Email: refdom@263.net ");
printf("Useage: TCPPing.exe Target_ip Target_port ");
printf("******************************************* ");
}

int main(int argc, char* argv[])
{
WSADATA WSAData;
SOCKET sock;
SOCKADDR_IN addr_in;
IPHEADER ipHeader;
TCPHEADER tcpHeader;
PSDHEADER psdHeader;

char szSendBuf[60]={0};
BOOL flag;
int rect,nTimeOver;

useage();

if (argc!= 3)
{ return false; }

if (WSAStartup(MAKEWORD(2,2), &WSAData)!=0)
{
printf("WSAStartup Error! ");
return false;
}

if ((sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET)
{
printf("Socket Setup Error! ");
return false;
}
flag=true;
if (setsockopt(sock,IPPROTO_IP, IP_HDRINCL,(char *)&flag,sizeof(flag))==SOCKET_ERROR)
{
printf("setsockopt IP_HDRINCL error! ");
return false;
}

nTimeOver=1000;
if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeOver, sizeof(nTimeOver))==SOCKET_ERROR)
{
printf("setsockopt SO_SNDTIMEO error! ");
return false;
}
addr_in.sin_family=AF_INET;
addr_in.sin_port=htons(atoi(argv[2]));
addr_in.sin_addr.S_un.S_addr=inet_addr(argv[1]);

//
//
//填充IP首部
ipHeader.h_verlen=(4<<4 | sizeof(ipHeader)/sizeof(unsigned long));
// ipHeader.tos=0;
ipHeader.total_len=htons(sizeof(ipHeader)+sizeof(tcpHeader));
ipHeader.ident=1;
ipHeader.frag_and_flags=0;
ipHeader.ttl=128;
ipHeader.proto=IPPROTO_TCP;
ipHeader.checksum=0;
ipHeader.sourceIP=inet_addr("本地地址");
ipHeader.destIP=inet_addr(argv[1]);

//填充TCP首部
tcpHeader.th_dport=htons(atoi(argv[2]));
tcpHeader.th_sport=htons(SOURCE_PORT); //源端口号
tcpHeader.th_seq=htonl(0x12345678);
tcpHeader.th_ack=0;
tcpHeader.th_lenres=(sizeof(tcpHeader)/4<<4|0);
tcpHeader.th_flag=2; //修改这里来实现不同的标志位探测,2是SYN,1是FIN,16是ACK探测 等等
tcpHeader.th_win=htons(512);
tcpHeader.th_urp=0;
tcpHeader.th_sum=0;

psdHeader.saddr=ipHeader.sourceIP;
psdHeader.daddr=ipHeader.destIP;
psdHeader.mbz=0;
psdHeader.ptcl=IPPROTO_TCP;
psdHeader.tcpl=htons(sizeof(tcpHeader));

//计算校验和
memcpy(szSendBuf, &psdHeader, sizeof(psdHeader));
memcpy(szSendBuf+sizeof(psdHeader), &tcpHeader, sizeof(tcpHeader));
tcpHeader.th_sum=checksum((USHORT *)szSendBuf,sizeof(psdHeader)+sizeof(tcpHeader));

memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));
memcpy(szSendBuf+sizeof(ipHeader), &tcpHeader, sizeof(tcpHeader));
memset(szSendBuf+sizeof(ipHeader)+sizeof(tcpHeader), 0, 4);
ipHeader.checksum=checksum((USHORT *)szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader));

memcpy(szSendBuf, &ipHeader, sizeof(ipHeader));

rect=sendto(sock, szSendBuf, sizeof(ipHeader)+sizeof(tcpHeader),
0, (struct sockaddr*)&addr_in, sizeof(addr_in));
if (rect==SOCKET_ERROR)
{
printf("send error!:%d ",WSAGetLastError());
return false;
}
else
printf("send ok! ");

closesocket(sock);
WSACleanup();

return 0;
}

4、接收数据
和发送原始套接字数据相比,接收就比较麻烦了。因为在WIN我们不能用recv()来接收raw socket上的数据,这是因为,所有的IP包都是先递交给系统核心,然后再传输到用户程序,当发送一个raws socket包的时候(比如syn),核心并不知道,也没有这个数据被发送或者连接建立的记录,因此,当远端主机回应的时候,系统核心就把这些包都全部丢掉,从而到不了应用程序上。所以,就不能简单地使用接收函数来接收这些数据报。

要达到接收数据的目的,就必须采用嗅探,接收所有通过的数据包,然后进行筛选,留下符合我们需要的。可以再定义一个原始套接字,用来完成接收数据的任务,需要设置SIO_RCVALL,表示接收所有的数据。

SOCKET sniffersock;
sniffsock = WSASocket(AF_INET, SOCK_RAW, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED);

DWORD lpvBuffer = 1;
DWORD lpcbBytesReturned = 0 ;
WSAIoctl(sniffersock, SIO_RCVALL, &lpvBuffer, sizeof(lpvBuffer), NULL, 0, & lpcbBytesReturned, NULL, NULL);

创建一个用于接收数据的原始套接字,我们可以用接收函数来接收数据包了。然后在使用一个过滤函数达到筛选的目的,接收我们需要的数据包。
在 http://www.xici.net/board/doc.asp?id=5891453&sub=15 提供了一个完整的发送和接收的程序,可以参考。

------------------------------------------------------------
reference:
1、《MS Windows 2000 TCP-IP Implementation Details》
2、ziss《Raw Sockets in Windows 2000/XP》
3、MSDN Platform SDK:《Windows Sockets 2》
 
□…… C语言初学者的困惑--如何由dos向windows转变
- + 返回页首 + -
  很多人学C语言很长一段时间了,还不知C究竟能干什么,以为学习c语言没什么用,纯粹是为了应付学校的考试.更有人说"学C语言?别做如此愚蠢的行为了!赶快学C++吧!"这种看法是不对的,不应该把c跟c++之间划起绝对的界限,过分看重c++而把c贬得一无是处,这是很片面的.C++功能虽然强大,但它毕竟是c的"超集",在c++里有哪一处找不到c的影子呢?没有c的支持,c++只能是无本之木。

  一般情况下,c++编程方式编写的程序源代码量小,但编译后的代码量较大,运行的速度略低,不过开发时的工作量和工作难度较小;而c编程方式编写的源代码量较大,但可执行的效率高.如果一些对速度要求高,尤其是对硬件操作较多的程序,大多数还是用c编程方式开发的(用C又比用汇编简单,易于实现).另外,学Win32 C程序设计还有助于更深入地了解Windows 的内幕和Win32 API。

  任何的编程语言都是一种工具,学习语言的目是要使用它来编写出实际需要的软件来,而软件作为一个用户程序,运行时要依赖操作系统,大多数人使用什么操作系统,我们就要编写出基于哪一种平台上的程序来.这样,软件才会有更大的市场。

  现在市面上出现的有关c语言方面的书大多是教授DOS下的c,上机实习也是在Turbo C 2.0(简称Tc)环境下转来转去.编程环境的单调总使人感到不爽.这也没办法,dos 下的c是最简单的,初学者当然要从最简单的入门啦.连比较有名的计算机专家谭浩强编的书也都是赞成从dos下的c学起的.再说,一个刚刚入门的人想在windows 这样的多进程,多线程的操作系统下用c编程,那似乎又不太现实.(那要了解在windows下,一个win32程序大体上是怎样执行的.要对系统有比较多的了解才行,一个初学者暂时还不具备那么多的知识)但我们的脚步又不能够只停留在dos里,应该积极地从dos向windows转变.在dos的时代,我们可以对dos下的编程迷恋,但现在都是windows横行霸道的时代了,我们就应用c语言编写windows平台上的程序,因时而变,学以致用.是时代使然!如果现在还是dos雄霸天下的话,那我就不会写这篇狗屁不通的文章来遗笑大方了,不被臭鸡蛋扔死才怪呢!

  "变法"是大势所趋的了,关键是怎么变,不单单是学习c语言的人如此,就连学c++的人都这样,笔者曾经在QQ上碰到一个学了c++将近一年的小伙,居然问我,他想编一个windows窗口,该怎么下手,如果学一门语言用了一年时间,只是学了一点语法知识,却没有编过一道程序,那实在是一种悲哀.下面我谈谈从dos向windows转变的一些个人见解,(这纯属个人观点,仅供参考,如果您已是高手,完全不必要在此浪费时间):

  一.拓宽视野,改变偏见

  别老以为c只是dos特有的东西,一提到c语言就认为c只能在dos下编程.其实,这是被tc束缚了意识,我们在学校里平时就只在dos的tc里面用c编程,很少用到"图形模式",整天面对?quot;乌黑黑"的屏幕,也难怪有些人一看到一个用c语言描绘出来的像windows的窗口便以为是c++的手笔.其实,作为一种语言,可以在任何一种平台上编程,只是接口不同而已,只要找到适合该平台的编程工具即可,c语言当然也能在windows下大放异彩.眼界放宽点,改变偏见,必有精彩发现.





  二.选择优秀的编程工具.

  “有好的工具,做起事来就事半功倍”.在dos下我们常用tc或bc(borland c).在windows下可以用c++builder 或者visual c++ 来编程,最好用visual c++ 毕竟是微软的东西嘛!微软一天不垮台,编程者的饭碗就不会掉的啦 ^_^ .再说,windows操作系统是微软出的,其内幕微软是最清楚不过的了,在应用程序接口上,相信vc也是做得最好的.不过用vc++6来编c程序会恨烦的,大家要有心理准备.同时可以选择多种编程工具,例如汇编,可以加强对windows的了解,是成为高手的好方法。

  三.加强对windows的了解.

  可以说编一个程序,就是用一种语言的语法形式将数据结构和表面的执行过程描述出来.在不同的操作系统下,其程序的执行过程是不同的.我们应该对windows的系统机制最起码有个大体的了解,才有可能编写windows的程序.dos是单进程单线程的系统,进程从头到尾的顺序执行,而windows是多进程、多线程的操作系统,是基于事件的,消息驱动的操作系统.明白这些是在windows下编程必不可少的,多学学它,你会发现windows 和 dos有很多的不同之处。

  四.采取灵活多变的学习方法.

  在不同的时期,学习不同的东西?可是有些人学习像word,excel这类操作性极强的办公软件时,总是先看书,看到尾巴忘了头,到上机时却不知所措.这种学习方式是被动的,看这些软件操作的书,里面说的都是具体的操作,不亲手又怎能接受新知识?

  五.多进行比较.

  dos和windows有许多共同和不同的地方,如果是从dos学过来的话,在学习过程中不妨多进行比较,把不同的地方记下,相同的地方可以跳过,这可以快速地了解系统的不同之处,迅速地学到东西!

  学习程序设计,我主张"实践->理论->再实践"的方式,在编程的初期,不管你会不会写程序,都应先实践,(这里的实践是指编程工具操作方面的实践),学会操作编程工具.也许有些人会说:"废话!没有理论,又怎么实践?"不错,当你坐在一台电脑面前不知所措时,你就会想方设法使自己学会操作它,主动看书,看联机帮助,请教别人,忙得个"不亦乐乎",这不是变"被动"为"主动"了吗? 边学习边操作,以实践来带动理论的学习,接着达到"理论与实践同步",就可闯过第一关,学会了编程工具的基本操作,可以为以后上机实践打下铺垫.

  光学会操作像vc这类的工具还不行,工具是死的,人才是活的,不会编程只能是空操作,你还会说:"废话!没有理论,怎么实践?"的,这时就要学习编程的真功夫了,也就是我说的第二阶段--学"理论"阶段,深入研究前辈们的著作,吸取前人的智慧精华为我所用,扎扎实实打好编程内功,功夫到家了就应该"再实践",将学到的东西运用于实际,编写出我们需要的软件来.学以致用嘛,呵呵~~这种方式总比"先学好语法的条条框框,再上机实践"的效果好得多啦.