1) 什么是电子签名?
电子签名并非是书面签名的数字图像化。它其实是一种电子代码,利用它,收件人便能在网上轻松验证发件人的身份和签名。它还能验证出文件的原文在传输过程中有无变动。
目前,可以通过多种技术手段实现电子签名,在确认了签署者的确切身份后,电子签名承认人们可以用多种不同的方法签署一份电子记录。方法有:基于PKI的公钥密码技术的数字签名;以生物特征统计学为基础的识别标识;手印、声音印记或视网膜扫描的识别;一个让收件人能识别发件人身份的密码代号、密码或个人识别码PIN;基于量子力学的计算机等等。但比较成熟的,使用方便具有可操作性的,在世界先进国家和我国普遍使用的电子签名技术还是基于PKI(PublicKeyInfrastructino)的数字签名技术。
2) 基于PKI的数字签名技术
基于PKI(公钥基础设施)的电子签名被称作“数字签名”。有人称“电子签名”就是“数字签名”是错误的。数字签名只是电子签名的一种特定形式。因为电子签名虽然获得了技术中立性,但也带来使用的不便,法律上又对电子签名作了进一步规定,如上述联合国贸发会的《电子签名示范法》和欧盟的《电子签名共同框架指令》中就规定了“可靠电子签名”和“高级电子签名”。实际上就是规定了数字签名的功能,这种规定使数字签名获得了更好的应用安全性和可操作性。目前,具有实际意义的电子签名只有公钥密码理论。所以,目前国内外普遍使用的、技术成熟的、可实际使用的还是基于PKI的数字签名技术。作为公钥基础设施PKI可提供多种网上安全服务,如认证、数据保密性、数据完整性和不可否认性。其中都用到了数字签名技术。
PKI的核心执行机构是电子认证服务提供者,即通称为认证机构CA(Certificate Authority),PKI签名的核心元素是由CA签发的数字证书。它所提供的PKI服务就是认证、数据完整性、数据保密性和不可否认性。它的作法就是利用证书公钥和与之对应的私钥进行加/解密,并产生对数字电文的签名及验证签名。数字签名是利用公钥密码技术和其他密码算法生成一系列符号及代码组成电子密码进行签名,来代替书写签名和印章;这种电子式的签名还可进行技术验证,其验证的准确度对手工签名和图章的验证无法比拟的。这种签名方法可在很大的可信PKI域人群中进行认证,或在多个可信的PKI域中进行交叉认证,它特别适用于互联网和广域网上的安全认证和传输。
2011年5月12日
【软考】电子签名基础知识ABC
『软考』接入网的分类
接入网的分类方法有很多种,例如可以按传输媒介分、按拓扑结构分、按使用技术分、按接口标准分、按业务带宽分、按业务种类分等等。
接入网的分类方法有很多种,例如可以按传输媒介分、按拓扑结构分、按使用技术分、按接口标准分、按业务带宽分、按业务种类分等等。将这些因素都考虑进去,接入网的花样自然就很多,但常用的主要有下面几大类,它们可单独使用或混合使用:
金属用户线上的XDSL:它又可分为IDSL(ISDN数字用户环路)、HDSL(利用两对线双向对称传输2Mb/s的高速数字用户环路)、SDSL(单线对双向对称传输2Mb/s的数字用户环路,传输距离比HDSL稍短)、VDSL(甚高速数字用户环路)、ADSL(不对称数字用户环路)。上述系统的拓扑结构是点到点。
同轴电缆上的HFC(双向混合光纤同轴电缆接入传输系统),SDV(可交换的数字视频接入系统,也基于混合光纤同轴电缆,但同轴缆上只传下行信号)。
拓扑结构是树型或总线型,下行物理上通常为广播方式。HFC/SDV与其他接入方式相比的特点是下行可以混合传送摸拟与数字信号。
光纤接入系统:可分为有源与无源系统,有源系统有基于PDH和SDH之分,拓扑结构可以是环型、总线型、星型或它们的混合型,也有点对点的应用。
无源即PON(无源光网络),有窄带与宽带之分,目前宽带 PON已经标准化的是基于ATM的 PON,即APON。PON本身下行是点到多点系统,上行为多点到点,上行时需要解决多用户争用问题,目前上行大多用TDMA(时分多址)技术。
无线接入系统:通常指固定无线接入(FWA),根据其技术来自无绳电话(如DECT)、集群电话、蜂窝移动通信、微波通信或卫星通信可分为很多类,对应不同的频段,容量、业务带宽和覆盖范围各异。无线接入主要的工作方式是点到多点,上行解决多用户争用的技术有FDMA(频分多址)、TDMA(时分多址)和CDMA(码分多址),从频谱效率看CDMA最好,TDMA其次。其中CDMA又可有扩谱(DS)、跳频(FH)和同步(S-CDMA)几种。
【软考】如何编写HTTP Servlet程序
| 在编写Servlet 时需要用到两个用于所有 Servlet 的基本软件包:javax.servlet 和 javax.servlet.http。下面主要介绍javax.servlet.http提供的HTTP Servlet应用编程接口。
首先介绍一下Java Servlet的基本方法。
下面介绍编写一个基本HTTP Servlet的步骤。 (1)引入相应的包和类,包括:
(2)实现service方法。 Servlet的主要功能是接受从浏览器发送过来的HTTP请求(request),并返回HTTP响应(response)。这个工作是在service方法中完成的。service方法包括从request对象获得客户端数据和向response对象创建输出。 如果一个Servlet从javax.servlet.http.HttpServlet继承,实现了doPost或doGet方法,那么这个Servlet只能对POST或GET做出响应。如果开发人员想处理所有类型的请求(request),只要简单地实现service方法即可(但假如选择实现service方法,则不必实现doPost或doGet方法,除非在service方法的开始调用super.service())。其中的差别如图14-2所示。 ![]() 图14-2 doGet、doPost、service的区别 HTTP Servlet规范描述了用来处理其他请求(request)类型的方法,所有这些方法都可以归属于service方法。所有的service 方法使用一样的参数。HttpServletRequest提供关于请求(request)的信息,Servlet可以使用 HttpServletResponse 对HTTP客户端做出响应。
(3)编译Servlet。 (4)将此Servlet作为应用的一部分部署。
其中servlet-name是Servlet的名字,servlet-class是在\WEB-INF\classes下存放class文件的相对路径。我们还可以在此文件中初始化参数,形式如下:
param-name是参数的名称,在本例中是greeting;param-value是参数的值,在本例是welcome。我们可以以此形式初始化更多的参数。
这段代码是Servlet名称与url-pattern路径的映射。根据这段代码,HelloWorld2这个Servlet程序的URL路径就是http://SERVER_ADDRESS: (5)从浏览器访问Servlet。一般说来,调用Servlet的URL 取决于包含Servlet的Web应用的名字和Web应用部署描述中的Servlet映射的名字。请求(request)参数也可以是调用Servlet的URL的一部分,一般Servlet 的URL如以下模式: |
【软考】实例:Servlet处理POST请求
下面介绍一个HTTP Servlet处理POST方式的例子,见示例14-3。
【程序源代码】
|
【程序输出结果】
在客户端IE浏览的效果如图14-5所示。

图14-5 客户端浏览效果
服务器端的Servlet就是要将客户端填写并发送的表单数据写入一个文件,并且用一个”thank you”信息响应用户。示例14-4就是Servlet程序。
【程序源代码】
|
部分配置文件如下所示:
|
【程序输出结果】
在相同目录下生成了一个Survey01Result的文本文件,里面记录着客户提交的信息:
|
同时返回给客户端信息,如图14-6所示。

图14-6 返回给客户端的信息
【程序注解】
在init()方法中先初始化了resultsDir变量,这个变量是以后保存文件的路径,这个变量的值在web.xml中。
doPost方法是用getParameterNames和getParameterValues方法从表单中获取数据的,当参数名是submit时,就不对这个参数操作,并将其余客户端的参数名和参数值写入文件中。因为它返回文本给客户端,doPost 调用了 getWriter 方法。在写入响应主体部分之前,它进行了响应头部字段的设置setContentType(“text/html”).
【软考】如何处理HTTP POST/GET请求
Servlet通过下面的方法来提供服务:
- 实现service方法。
- 实现HttpServlet的doMethod方法(doGet、doDelete、doOptions、 doPost、doPut、doTrace)。
对于HTTP Servlets,正确提供响应的过程是首先填写响应(response)的头信息,然后从响应(response)中得到输出流,最后向输出流中写入内容信息。响应(response)头信息必须最先设置。下面将描述如何从请求(request)中获得信息和产生HTTP响应(response)。
一个HttpServletRequest对象提供到达HTTP 头部数据,也允许你获取客户端的数据。怎样获取这些数据取决于HTTP端请求方法。不管用任何HTTP方式,你都可以用 getParameterValues方法返回特定名称的参数值。对于用 HTTP GET 请求的方式,这个getQueryString方法将会返回一个可以用来分析的值。
客户端请求(request)包含了从客户端传递到Servlet的数据。所有的请求(request)都实现了ServletRequest接口。这个接口定义了一些方法访问下面的信息,如表14-1所示。
|
下面的代码段示范了如何使用request中的方法获得客户端信息。
|
HTTP Servlets使用HTTP request对象(HttpServletRequest),它包含了request URL、HTTP头信息、查询字符串,等等。HTTP request URL 包括几个部分:
http://
一般情况下:
|
如表14-2所示。
|
响应(response)包含了在服务器和客户端之间传递的数据。所有的响应(response)都实现了ServletResponse接口。这个接口定义了一些方法提供给开发人员使用,如表14-3所示。
|
HTTP response类(HttpServletResponse)有一些代表HTTP头信息的域:
Servlet首先设置响应(response)头信息,包括响应(response)的内容类别和缓冲区大小,然后在doGet方法中从响应(response)获得PrintWriter ,最后向输出中写入HTML代码,调用close()方法提交这次对客户端的响应(response)。示范代码如下:
|
【软考】网络工程师的素质
网络时代已经来临。我们都知道,社会生活高度电子化,使网络已经成为人们生活不可或缺的一部分。电子商务、电子政务、远程教育已充斥着人们的生活、工作、学习中的每一个环节。而这一切,都需要大量的网络人才来支撑,可以说,网络人才是当今的宠儿。网络工程师已成为现在最热门的职业之一,那么,具备什么样的素质才能称之为真正的工程师呢?
从知识结构的角度看,网络工程师必须有比较全面的理论架构。网络工程与网络维护者是两个完全不同的概念,后者只要求对某个操作系统,或某个基于网络的软件熟悉,并能够处理这方面的问题就可以了。而网络工程师则要求对网络整体有清晰的把握,能够处理随时可能发生的问题。网络是复杂的,可能出现的问题涉及到方方面面,没有较完整的知识结构是不可能胜任这方面的工作的。举个简单的例子,网络由于调整或升级突然出现局域断网的情况,这其中的原因可能是路由模块配置问题,也可能是光纤收发故障,或者又是某个代理服务器停止服务……网络工程师只有掌握这些软硬件知识,才可能在很短的时间内找出问题所在,顺利解决问题。网络工程师分很多种,我们就以一般的局域网设计与管理员来举例,一个合格的网络工程师,应具备如下知识:首先,要有扎实的硬件基础,包括服务器及路由、交换设备等硬件的结构、性能指标等。进行系统设计时,硬件的性能指标都是网络工程师要充分考虑的因素。进行维护就更不用讲了。其次,要掌握最常用的网络操作系统,如Win2000和Linux。现在架构一个局域网可能会用到多种操作系统,多掌握一些毕竟可以更好地处理问题。其三,要掌握路由交换设备的配置方法。可以说,Internet就是由路由器和交换机搭建而成的,合格的网络工程师必须能够单独完成局域网的架构工作,如果没有相关的知识是不敢想象的。其四,还要掌握综合布线和网络集成的相关知识。在做项目计划时,要充分考虑到设备的选型和拓朴的设计,必须对综合布线有所了解,才可能做到网络畅通,硬件匹配,不产生网络瓶颈。对这一点,有的人可能不以为然,举个实际的例子吧。前段时间,有个公司要组建一个局域网,中心骨干设备选择了Cisco的6509千兆交换机,而接入层则为了省钱,选择使用百兆的单模收发器。结果,设备买回后却怎么也调不通。原因很简单,就是因为单模收发器的光纤无法和Cisco的千兆模块相匹配。最后只能全部改用了Cisco3500系列做为接入层交换设备,实际比多投入了近20万,造成了巨大浪费。当然,以上的知识结构只是针对网络管理和维护的工程师而言,如果是专业的数据库管理员,精通SQL语句,熟悉某种数据库则是必须的了。
再者,网络工程师需要在实践中培养一种创新能力。网络需求是千变万化的,必须以不变应万变。同样一个网络设计需求,对于不同层次的网络工程师,其制作的解决方案也不尽相同。可以说,水平越高的越能通过特定的设计最贴切地体现用户的需求。而相反,有的网络工程师将网络设计当作了一种固定模式。笔者认识几位工程师,其中有的就已习惯了照搬方案,对于自己的发展是相当不利的,对于用户而言,也是一种浪费。所以,在工作和学习中多思考,才可能走上更高的台阶。
最后,就是良好的英语水平,毕竟计算机是由美国人发明的,它的母语是英语。对于半路出家的工程师而言,可能英语是个弱项,在起初可能不会对你造成太大的障碍。网络技术发展太快,最新最好的资料往往是英文的。有时,我们对一个设备的配置不熟的话,都要去翻阅它的使用说明书或看帮助文件,那可全是英文的,没有扎实的英语水平,根本是不可想象的。所以要想进一步提升自己,学好英文是基础,也是关键所在。
【软考】网络工程师考试常用的socket程序
Hey! Socket 编程让你沮丧吗?从 man pages 中很难得到有用的信息吗?你想 跟上时代去做一做
Internet 程序,但是为你在调用 connect() 前的 bind() 的结构而愁眉不展?…
好了,我现在已经来了,我将和所有人共享我的知识了。如果你了解 C 语言并想穿过 网络编程的沼泽,那么你来对地方了。
——————————————————————————–
读者
这个文档是写成一个指南,而不是参考书。如果你刚开始 socket 编程并想找一本
入门书,那么你是我的读者。这可不是一本完全的 socket 编程书。
——————————————————————————–
平台和编译器
这篇文章中的大多数代码都在一台 Linux PC 上用 GNU 的 gcc 成功编译过。 而且他们在一台 HPUX 上用
gcc 也成功编译过。但是注意,并不是每个代码 片段都独立测试过。
——————————————————————————–
目录:
什么是套接口?
Internet 套接口的两种类型
网络理论
struct–要么了解他们,要么等异形入侵地球
Convert the Natives!
IP 地址和如何处理他们
socket()–得到文件描述符!
bind()–我们在哪个端口?
connect()–Hello!
listen()–有人给我打电话吗?
accept()–”Thank you for calling port 3490.”
send() 和 recv()–Talk to me, baby!
sendto() 和 recvfrom()–Talk to me, DGRAM-style
close() 和 shutdown()–滚开!
getpeername()–你是谁?
gethostname()–我是谁?
DNS–你说“白宫”,我说 “198.137.240.100″
客户-服务器背景知识
简单的服务器
简单的客户端
数据报 Socket
阻塞
select()–多路同步 I/O,酷!
参考资料
Disclaimer and Call for Help
——————————————————————————–
什么是 socket?
你始终听到人们谈论着 “socket”,而你不知道他的确切含义。那么,现在我告诉你: 他是使用 Unix 文件描述符
(fiel descriptor) 和其他程序通讯的方式。
什么?
Ok–你也许听到一些 Unix 高手 (hacker) 这样说:“呀,Unix 中所有的东西
就是文件!”那个家伙也许正在说到一个事实:Unix 程序在执行任何形式的 I/O 的时候,
程序是在读或者写一个文件描述符。一个文件描述符只是一个和打开的文件相关联的整数。
但是(注意后面的话),这个文件可能是一个网络连接,FIFO,管道,终端,磁盘上的文件 或者什么其他的东西。Unix
中所有的东西是文件!因此,你想和 Internet 上别 的程序通讯的时候,你将要通过文件描述符。最好相信刚才的话。
现在你脑海中或许冒出这样的念头:“那么我从哪里得到网络通讯的文件描述符呢,聪明
人?”无论如何,我要回答这个问题:你利用系统调用 socket()。他返回套接口描 述符 (socket
descriptor),然后你再通过他来调用 send() 和 recv()。
“但是…”,你可能现在叫起来,“如果他是个文件描述符,那么为什么不用一般的调用 read() 和 write()
来通过套接口通讯?”简单的答案是:“你可以使用 一般的函数!”。详细的答案是:“你可以,但是使用 send() 和
recv() 让你更好的控制数据传输。”
有这样一个事实:在我们的世界上,有很多种套接口。有 DARPA Internet 地址 (Internet
套接口),本地节点的路径名 (Unix 套接口),CCITT X.25 地址 (你可以完全忽略 X.25 套接口)。
也许在你的 Unix 机器上还有其他的。我们在这里只讲第一种:Internet 套接口。
——————————————————————————–
Internet 套接口的两种类型
什么意思?有两种 Internet 套接口?是的。不,我在撒谎。其实还有很多,但是我可不想 吓着你。我们这里只讲两种。
Except for this sentence, where I’m going to tell you that
“Raw Sockets” are also very powerful and you should look them
up.
好了,好了。那两种类型是什么呢?一种是 “Stream Sockets”,另外一种是 “Datagram
Sockets”。我们以后谈到他们的时候也会用到 “SOCK_STREAM” 和 “SOCK_DGRAM”。
数据报套接口有时也叫“无连接套接口”(如果你确实要连接的时候用 connect()。)
流式套接口是可靠的双向通讯的数据流。如果你向套接口安顺序输出“1,2”,那么他们
将安顺序“1,2”到达另一边。他们也是无错误的传递的,有自己的错误控制。
有谁在使用流式套接口?你可能听说过 telnet,不是吗?他就使用流式套接口。你需要你所输入的字符按顺序到达,不是
吗?同样,WWW 浏览器使用的 HTTP 协议也使用他们。实际上,当你通过端口80 telnet 到一个 WWW
站点,然后输入 “GET pagename” 的时候,你也可以得到 HTML 的内容。
为什么流式套接口可以达到高质量的数据传输?他使用了“传输控制协议 (The Transmission Control
Protocol)”,也叫 “TCP” (请参考 RFC-793 获得详细资料。)TCP 控制你的数据
按顺序到达并且没有错误。你也许听到 “TCP” 是因为听到过 “TCP/IP”。这里的 IP 是指 “Internet
协议”(请参考 RFC-791.) IP 只是处理 Internet 路由而已。
那么数据报套接口呢?为什么他叫无连接呢?为什么他是不可靠的呢?恩,有这样的事实:如果你发送一个数据报,他可能到达,他可能次序颠倒了。如果他到达,那么在这个包的内部是无错误的。
数据报也使用 IP 作路由,但是他不选择 TCP。他使用“用户数据报协议 (User Datagram
Protocol)”,也叫 “UDP” (请参考 RFC-768.)
为什么他们是无连接的呢?主要原因是因为他并不象流式套接口那样维持一个连接。 你只要建立一个包,在目标信息中构造一个 IP
头,然后发出去。不需要连接。应用程序有: tftp, bootp 等等。
“够了!”你也许会想,“如果数据丢失了这些程序如何正常工作?”我的朋友,每个程序在 UDP 上有自己的协议。例如,tftp
协议每发出一个包,收到者发回一个包来说“我收到了!” (一个“命令正确应答”也叫“ACK”
包)。如果在一定时间内(例如5秒),发送方没有收到应答, 他将重新发送,直到得到 ACK。这一点在实现 SOCK_DGRAM
应用程序的时候非常重要。
——————————————————————————–
网络理论
既然我刚才提到了协议层,那么现在是讨论网络究竟如何工作和演示 SOCK_DGRAM
的工作。当然,你也可以跳过这一段,如果你认为 已经熟悉的话。
朋友们,现在是学习 数据封装 (Data Encapsulation) 的时候了! 这非常非常重要。It’s so
important that you might just learn about it if you take the
networks course here at Chico State ;-).
主要的内容是:一个包,先是被第一个协议(在这里是 TFTP )包装(“封装”), 然后,整个数据(包括 TFTP
头)被另外一个协议(在这里是 UDP )封装,然后下 一个( IP ),一直重复下去,直到硬件(物理)层( Ethernet
)。
当另外一台机器接收到包,硬件先剥去 Ethernet 头,内核剥去 IP 和 UDP 头,TFTP 程序再剥去 TFTP
头,最后得到数据。
现在我们终于讲到臭名远播的 网络分层模型 (Layered Network Model)。
这种网络模型在描述网络系统上相对其他模型有很多优点。例如,你可以写一个套接口
程序而不用关心数据的物理传输(串行口,以太网,连接单元接口 (AUI) 还是其他介质。
因为底层的程序为你处理他们。实际的网络硬件和拓扑对于程序员来说是透明的。
不说其他废话了,我现在列出整个层次模型。如果你要参加网络考试,可一定要记住:
应用层 (Application)
表示层 (Presentation)
会话层 (Session)
传输层 (Transport)
网络层 (Network)
数据链路层 (Data Link)
物理层 (Physical)
物理层是硬件(串口,以太网等等)。应用层是和硬件层相隔最远的–他是用户和网络 交互的地方。
这个模型如此通用,如果你想,你可以把他作为修车指南。把他应用到 Unix,结果是:
应用层 (Application Layer) (telnet, ftp, 等等)
传输层 (Host-to-Host Transport Layer) (TCP, UDP)
Internet 层 (Internet Layer) (IP 和路由)
网络访问层 (Network Access Layer) (网络层,数据链路层和物理层)
现在,你可能看到这些层次如何协调来封装原始的数据了。
看看建立一个简单的数据包有多少工作?哎呀,你将不得不使用 “cat” 来完成 他们!简直是笑话。对于流式套接口你要作的是
send() 发送数据。对于数据报 式套接口你按照你选择的方式封装数据然后用 sendto()。内核将为你建立传输 层和
Internet 层,硬件完成网络访问层。这就是现代科技。
现在结束我们的网络理论速成班。哦,忘记告诉你关于路由的事情了。但是我不准备谈他。 如果你真的想知道,那么参考 IP
RFC。如果你从来不曾了解他,也没有 关系,你还活着不是吗。
——————————————————————————–
structs
终于到达这里了,终于谈到编程了。在这章,我将谈到被套接口用到的各种数据类型。因为 他们中的一些太重要了。
首先是简单的一个:socket descriptor。他是下面的类型:
int
仅仅是一个常见的 int。
从现在起,事情变得不可思议了。请跟我一起忍受苦恼吧。注意这样的事实: 有两种字节排列顺序:重要的字节在前面(有时叫
“octet”),或者不重要的字节在前面。 前一种叫“网络字节顺序 (Network Byte
Order)”。有些机器在内部是按照这个顺序储 存数据,而另外一些则不然。当我说某数据必须按照 NBO
顺序,那么你要调用函数(例 如 htons() )来将他从本机字节顺序 (Host Byte Order) 转换过来。如果我
没有提到 NBO, 那么就让他是本机字节顺序吧。
我的第一个结构(TM)–struct sockaddr. 这个数据结构 为许多类型的套接口储存套接口地址信息:
struct sockaddr {
unsigned short sa_family; /* address family,
AF_xxx */
char sa_data[14]; /* 14 bytes of protocol
address */
};
sa_family 能够是各种各样的事情,但是在这篇文章中是 “AF_INET”。 sa_data
为套接口储存目标地址和端口信息。看上去很笨拙,不是吗。
为了对付 struct sockaddr,程序员创造了一个并列的结构: struct sockaddr_in (“in”
代表 “Internet”.)
struct sockaddr_in {
short int sin_family; /* Address family
*/
unsigned short int sin_port; /* Port number
*/
struct in_addr sin_addr; /* Internet address
*/
unsigned char sin_zero[8]; /* Same size as struct
sockaddr */
};
这个数据结构让可以轻松处理套接口地址的基本元素。注意 sin_zero (他 被加入到这个结构,并且长度和 struct
sockaddr 一样) 应该使用函数 bzero() 或 memset() 来全部置零。 Also, and this
is the important bit, a pointer to a struct sockaddr_in can be
cast to a pointer to a struct sockaddr and vice-versa. 这样的话 即使
socket() 想要的是 struct sockaddr *, 你仍然可以使用 struct
sockaddr_in,and cast it at the last minute! 同时,注意 sin_family 和
struct sockaddr 中的 sa_family 一致并能够设置为 “AF_INET”。最后, sin_port 和
sin_addr 必须是网络字节顺序 (Network Byte Order)!
你也许会反对道:”但是,怎么让整个数据结构 struct in_addr sin_addr 按照网络字节顺序呢?”
要知道这个问题的答案,我们就要仔细的看一 看这个数据结构: struct in_addr, 有这样一个联合
(unions):
/* Internet address (a structure for historical reasons) */
struct in_addr {
unsigned long s_addr;
};
他曾经是个最坏的联合,但是现在那些日子过去了。如果你声明 “ina” 是 数据结构 struct sockaddr_in
的实例,那么 “ina.sin_addr.s_addr” 就储存4字节的 IP 地址(网络字节顺序)。如果你不幸的
系统使用的还是恐怖的联合 struct in_addr ,你还是可以放心4字 节的 IP 地址是和上面我说的一样(这是因为
#define。)
——————————————————————————–
Convert the Natives!
我们现在到达下个章节。我们曾经讲了很多网络到本机字节顺序,现在是采取行动的时刻了!
你能够转换两种类型: short (两个字节)和 long (四个字节)。这个 函数对于变量类型 unsigned
也适用。假设你想将 short 从本机字节顺序 转换为网络字节顺序。用 “h” 表示 “本机 (host)”,接着是
“to”,然后用 “n” 表示 “网络 (network)”,最后用 “s” 表示 “short”: h-to-n-s,
或者 htons() (“Host to Network Short”)。
太简单了…
如果不是太傻的话,你一定想到了组合 “n”,”h”,”s”,和 “l”。但是这里没有 stolh() (“Short to
Long Host”) 函数,但是这里有:
htons()–”Host to Network Short”
htonl()–”Host to Network Long”
ntohs()–”Network to Host Short”
ntohl()–”Network to Host Long”
现在,你可能想你已经知道他们了。你也可能想:”如果我改变 char 的顺序会 怎么样呢? 我的 68000
机器已经使用了网络字节顺序,我没有必要去调用 htonl() 转换 IP 地址。”
你可能是对的,但是当你移植你的程序到别的机器上的时候,你的程序将 失败。可移植性!这里是 Unix
世界!记住:在你将数据放到网络上的时候,确信他们是网络字 节顺序。
最后一点:为什么在数据结构 struct sockaddr_in 中, sin_addr 和 sin_port
需要转换为网络字节顺序,而 sin_family 不需要呢? 答案是:sin_addr 和 sin_port 分别封装在包的
IP 和 UDP 层。因此,他们必须要是网络字节顺序。 但是 sin_family 域只是被内核 (kernel)
使用来决定在数据结构中包含什么 类型的地址,所以他应该是本机字节顺序。也即 sin_family 没有 发
送到网络上,他们可以是本机字节顺序。
——————————————————————————–
IP 地址和如何处理他们
现在我们很幸运,因为我们有很多的函数来方便地操作 IP 地址。没有必要用手工计算 他们,也没有必要用 << 操作符来操作
long。
首先,假设你用 struct sockaddr_in ina,你想将 IP 地址 “132.241.5.10″
储存到其中。你要用的函数是 inet_addr(),转换 numbers-and-dots 格式的 IP 地址到
unsigned long。这个工作可以这样来做:
ina.sin_addr.s_addr = inet_addr(“132.241.5.10″);
注意:inet_addr() 返回的地址已经是按照网络字节顺序的,你没有必要再去调用 htonl()。
上面的代码可不是很健壮 (robust),因为没有错误检查。inet_addr() 在发生错误
的时候返回-1。记得二进制数吗? 在 IP 地址为 255.255.255.255 的时候返回的是
(unsigned)-1!这是个广播地址!记住正确的使用错误检查。
好了,你现在可以转换字符串形式的 IP 地址为 long 了。那么你有一个数据结构 struct in_addr,该如何按照
numbers-and-dots 格式打印呢? 在这个 时候,也许你要用函数 inet_ntoa() (“ntoa” 意思是
“network to ascii”):
printf(“%s”,inet_ntoa(ina.sin_addr));
他将打印 IP 地址。注意的是:函数 inet_ntoa() 的参数是 struct in_addr,而不是
long。同时要注意的是他返回的是一个指向字符的指针。 在 inet_ntoa 内部的指针静态地储存字符数组,因此每次你调用
inet_ntoa() 的时候他将覆盖以前的内容。例如:
char *a1, *a2;
.
.
a1 = inet_ntoa(ina1.sin_addr); /* this is 198.92.129.1 */
a2 = inet_ntoa(ina2.sin_addr); /* this is 132.241.5.10 */
printf(“address 1: %s\n”,a1);
printf(“address 2: %s\n”,a2);
运行结果是:
address 1: 132.241.5.10
address 2: 132.241.5.10
如果你想保存地址,那么用 strcpy() 保存到自己的字符数组中。
这就是这章的内容了。以后,我们将学习转换 “whitehouse.gov” 形式的字符串到正确 的 IP 地址
【软考】交换机的种类
随着网络技术的发展,各种各样的通信设备应运而生,交换机就是其中一员。在一些技术类书籍或文章中,我们经常可以看到很多交换机的名词,它们中很多是由英语直接翻译过来,也有一些是厂商为了某种目的命名的。这些形形色色的交换机名很容易让人混淆,以下我们将介绍一下交换机的不同分类情况,并对其中一些常见的名词作一分析。
交换机包括电话交换机(PBX)、数据交换机(Switch),以下我们所提到的交换机都是指数据交换机,对传统的电话交换机就不作讨论了。
从广义上来看,交换机分为两种:广域网交换机和局域网交换机。广域网交换机主要应用于电信领域,提供通信用的基础平台。而局域网交换机则应用于局域网络,用于连接终端设备,如PC机及网络打印机等。以下内容都是基于局域网交换机来说的。
按照最广泛的普通分类方法,即从规模应用上,局域网交换机可分为企业级交换机、部门级交换机和工作组交换机等。作为骨干交换机时,支持500个信息点以上大型企业应用的交换机为企业级交换机,支持300个信息点以下中型企业的交换机为部门级交换机,而支持100个信息点以内的交换机为工作组级交换机。但这也不是绝对的标准,正是由于没有统一的划分的尺度标准,又出现了桌面型交换机(Desktop Switch)、校园网交换机(Campus Switch)等概念。下面对以上几个概念作一简介:
1. 桌面型交换机,这是最常见的一种交换机,它区别于其他交换机的一个特点是支持的每端口MAC地址很少。广泛的使用于一般办公室、小型机房和业务受理较为集中的业务部门、多媒体制作中心、网站管理中心等部门。在传输速度上,现代桌面型交换机大都提供多个具有10/100Mbps自适应能力的端口。
2.工作组交换机,常用来作为扩充设备,在桌面型交换机不能满足需求时,大多直接考虑工作组型交换机。虽然工作组型交换机只有较少的端口数量,但却支持较多的MAC地址,并具有良好的扩充能力,端口的传输速度基本上为100Mbps。
3. 部门交换机,它通常不比工作组交换机更贵,而且与工作组交换机不同的是它们的端口数量和性能级别有所差异。一个部门交换机通常有8~16个端口,通常在所有端口上支持全双工操作。它们的性能要好于一个工作组交换机的性能,而且有一个等于或超过所有端口带宽的半双工汇集带宽。
4. 校园网交换机,这种交换机应用相对较少,仅应用于大型网络,且一般作为网络的骨干交换机,并具有快速数据交换能力和全双工能力,可提供容错等智能特性,还支持扩充选项及第三层交换中的虚拟局域网(VLAN)等多种功能。
5. 企业交换机,虽然非常类似于校园网交换机,但最大的不同是企业交换机还可以接入一个大底盘。这些底盘产品通常支持许多不同类型的组件,比如快速以太网和以大网中继器、FDDI集中器、令牌环MAU和路由器。企业交换机在建设企业级别的网络时非常有用,尤其是对需要支持一些网络技术和以前的系统。基于底盘设备通常有非常强大的管理特征,因此非常适合于企业网络的环境。不过,基于底盘设备的缺点是它们的成本都非常高。
根据架构特点,人们还将局域网交换机分为机架式、带扩展槽固定配置式、不带扩展槽固定配置式3种产品。
1. 机架式交换机 这是一种插槽式的交换机,这种交换机扩展性较好,可支持不同的网络类型,如以太网、快速以太网、千兆以太网、ATM、令牌环及FDDI等,但价格较贵,高端交换机有不少采用机架式结构。
2. 带扩展槽固定配置式交换机 它是一种有固定端口数并带少量扩展槽的交换机,这种交换机在支持固定端口类型网络的基础上,还可以通过扩展其他网络类型模块来支持其他类型网络。这类交换机的价格居中。
3. 不带扩展槽固定配置式交换机 这类交换机仅支持一种类型的网络(一般是以太网),可应用于小型企业或办公室环境下的局域网,价格最便宜,应用也最广泛。
从传输介质和传输速度上看,局域网交换机可以分为以太网交换机、快速以太网交换机、千兆以太网交换机、FDDI交换机、ATM交换机和令牌环交换机等多种,这些交换机分别适用于以太网、快速以太网、FDDI、ATM和令牌环网等环境。
从ISO/OSI的分层结构上说,交换机可分为二层交换机、三层交换机等。二层交换机指的就是传统的工作在OSI参考模型的第二层–数据链路层上交换机,主要功能包括物理编址、错误校验、帧序列以及流控。 一个纯第二层的解决方案,是最便宜的方案,但它在划分子网和广播限制等方面提供的控制最少。传统的路由器与外部的交换机一起使用也能解决这个问题,但现在路由器的处理速度已跟不上带宽要求。因此三层交换机、Web交换机等应运而生。
三层交换机是一个具有三层交换功能的设备,即带有第三层路由功能的第二层交换机,但它是二者的有机结合,并不是简单地把路由器设备的硬件及软件叠加在局域网交换机上。
Web交换机为数据中心设备(包括Internet服务器、防火墙、高速缓冲服务器和网关等)提供管理、路由和负载均衡传输。不同于传统网络设备的是,传统网络设备注重高速完成单个帧和数据包的交换,而Web交换侧重于跟踪和处理Web会话。除了由传统第二/三层交换机所提供的连接和封包路由外,Web交换机还可提供传统局域网交换机和路由器所缺乏的完备策略,将局部和全球服务器负载均衡、存取控制、服务质量保证(QoS)以及带宽管理等管理能力结合起来。目前,Web交换机已由纯粹的传输层(第四层)设备发展到具有基于内容(第七层)的交换的智能。利用内容或用户分类进行Web请求重定向是Web服务器的一项功能。不过,Internet传输和商业的发展远远超过计算机处理能力的提高。把内容分类卸到Web交换机可平衡整个网站的基础设施。
随着技术的发展,肯定还会有更多的新名词涌现出来,但是只要掌握好原理,有清楚的概念,就不会被它们搞昏头脑。
【软考】ping的工作原理
ping的原理就是首先建立通道,然后发送包,对方接受后返回信息,这个包至少包括以下内容,发送的时候,包的内容包括对方的ip地址和自己的地址,还有序列数,回送的时候包括双方地址,还有时间等,主要是接受方在都是在操作系统内核里做好的,时刻在监听,提供一段c程序的代码,希望对大家有用。
#include <stdio.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netdb.h>
#include <setjmp.h>
#include <errno.h>
#define PACKET_SIZE 4096
#define MAX_WAIT_TIME 5
#define MAX_NO_PACKETS 3
char sendpacket[PACKET_SIZE];
char recvpacket[PACKET_SIZE];
int sockfd,datalen=56;
int nsend=0,nreceived=0;
struct sockaddr_in dest_addr;
pid_t pid;
struct sockaddr_in from;
struct timeval tvrecv;
void statistics(int signo);
unsigned short cal_chksum(unsigned short *addr,int len);
int pack(int pack_no);
void send_packet(void);
void recv_packet(void);
int unpack(char *buf,int len);
void tv_sub(struct timeval *out,struct timeval *in);
void statistics(int signo)
{ printf(“\n——————–PING statistics——————-\n”);
printf(“%d packets transmitted, %d received , %%%d lost\n”,nsend,nreceived,
(nsend-nreceived)/nsend*100);
close(sockfd);
exit(1);
}
/*校验和算法*/
unsigned short cal_chksum(unsigned short *addr,int len)
{ int nleft=len;
int sum=0;
unsigned short *w=addr;
unsigned short answer=0;
/*把ICMP报头二进制数据以2字节为单位累加起来*/
while(nleft>1)
{ sum+=*w++;
nleft-=2;
}
/*若ICMP报头为奇数个字节,会剩下最后一字节。把最后一个字节视为一个2字节数据的高字节,这个2字节数据的低字节为0,继续累加*/
if( nleft==1)
{ *(unsigned char *)(&answer)=*(unsigned char *)w;
sum+=answer;
}
sum=(sum>>16)+(sum&0xffff);
sum+=(sum>>16);
answer=~sum;
return answer;
}
/*设置ICMP报头*/
int pack(int pack_no)
{ int i,packsize;
struct icmp *icmp;
struct timeval *tval;
icmp=(struct icmp*)sendpacket;
icmp->icmp_type=ICMP_ECHO;
icmp->icmp_code=0;
icmp->icmp_cksum=0;
icmp->icmp_seq=pack_no;
icmp->icmp_id=pid;
packsize=8+datalen;
tval= (struct timeval *)icmp->icmp_data;
gettimeofday(tval,NULL); /*记录发送时间*/
icmp->icmp_cksum=cal_chksum( (unsigned short *)icmp,packsize); /*校验算法*/
return packsize;
}
/*发送三个ICMP报文*/
void send_packet()
{ int packetsize;
while( nsend<MAX_NO_PACKETS)
{ nsend++;
packetsize=pack(nsend); /*设置ICMP报头*/
if( sendto(sockfd,sendpacket,packetsize,0,
(struct sockaddr *)&dest_addr,sizeof(dest_addr) )<0 )
{ perror(“sendto error”);
continue;
}
sleep(1); /*每隔一秒发送一个ICMP报文*/
}
}
/*接收所有ICMP报文*/
void recv_packet()
{ int n,fromlen;
extern int errno;
signal(SIGALRM,statistics);
fromlen=sizeof(from);
while( nreceived<nsend)
{ alarm(MAX_WAIT_TIME);
if( (n=recvfrom(sockfd,recvpacket,sizeof(recvpacket),0,
(struct sockaddr *)&from,&fromlen)) <0)
{ if(errno==EINTR)continue;
perror(“recvfrom error”);
continue;
}
gettimeofday(&tvrecv,NULL); /*记录接收时间*/
if(unpack(recvpacket,n)==-1)continue;
nreceived++;
}
}
/*剥去ICMP报头*/
int unpack(char *buf,int len)
{ int i,iphdrlen;
struct ip *ip;
struct icmp *icmp;
struct timeval *tvsend;
double rtt;
ip=(struct ip *)buf;
iphdrlen=ip->ip_hl<<2; /*求ip报头长度,即ip报头的长度标志乘4*/
icmp=(struct icmp *)(buf+iphdrlen); /*越过ip报头,指向ICMP报头*/
len-=iphdrlen; /*ICMP报头及ICMP数据报的总长度*/
if( len<
/*小于ICMP报头长度则不合理*/
{ printf(“ICMP packets\’s length is less than 8\n”);
return -1;
}
/*确保所接收的是我所发的的ICMP的回应*/
if( (icmp->icmp_type==ICMP_ECHOREPLY) && (icmp->icmp_id==pid) )
{ tvsend=(struct timeval *)icmp->icmp_data;
tv_sub(&tvrecv,tvsend); /*接收和发送的时间差*/
rtt=tvrecv.tv_sec*1000+tvrecv.tv_usec/1000; /*以毫秒为单位计算rtt*/
/*显示相关信息*/
printf(“%d byte from %s: icmp_seq=%u ttl=%d rtt=%.3f ms\n”,
len,
inet_ntoa(from.sin_addr),
icmp->icmp_seq,
ip->ip_ttl,
rtt);
}
else return -1;
}
main(int argc,char *argv[])
{ struct hostent *host;
struct protoent *protocol;
unsigned long inaddr=0l;
int waittime=MAX_WAIT_TIME;
int size=50*1024;
if(argc<2)
{ printf(“usage:%s hostname/IP address\n”,argv[0]);
exit(1);
}
if( (protocol=getprotobyname(“icmp”) )==NULL)
{ perror(“getprotobyname”);
exit(1);
}
/*生成使用ICMP的原始套接字,这种套接字只有root才能生成*/
if( (sockfd=socket(AF_INET,SOCK_RAW,protocol->p_proto) )<0)
{ perror(“socket error”);
exit(1);
}
/* 回收root权限,设置当前用户权限*/
setuid(getuid());
/*扩大套接字接收缓冲区到50K这样做主要为了减小接收缓冲区溢出的
的可能性,若无意中ping一个广播地址或多播地址,将会引来大量应答*/
setsockopt(sockfd,SOL_SOCKET,SO_RCVBUF,&size,sizeof(size) );
bzero(&dest_addr,sizeof(dest_addr));
dest_addr.sin_family=AF_INET;
/*判断是主机名还是ip地址*/
if( inaddr=inet_addr(argv[1])==INADDR_NONE)
{ if((host=gethostbyname(argv[1]) )==NULL) /*是主机名*/
{ perror(“gethostbyname error”);
exit(1);
}
memcpy( (char *)&dest_addr.sin_addr,host->h_addr,host->h_length);
}
else /*是ip地址*/
memcpy( (char *)&dest_addr,(char *)&inaddr,host->h_length);
/*获取main的进程id,用于设置ICMP的标志符*/
pid=getpid();
printf(“PING %s(%s): %d bytes data in ICMP packets.\n”,argv[1],
inet_ntoa(dest_addr.sin_addr),datalen);
send_packet(); /*发送所有ICMP报文*/
recv_packet(); /*接收所有ICMP报文*/
statistics(SIGALRM); /*进行统计*/
return 0;
}
/*两个timeval结构相减*/
void tv_sub(struct timeval *out,struct timeval *in)
{ if( (out->tv_usec-=in->tv_usec)<0)
{ –out->tv_sec;
out->tv_usec+=1000000;
}
out->tv_sec-=in->tv_sec;
}
/*————- The End ———–*/
【软考】网络攻击技术和PKI技术概述
网络主动攻击和被动攻击
网络攻击又可分为主动攻击和被动攻击。
◆ 被动攻击
被动攻击就是网络窃听,截取数据包并进行分析,从中窃取重要的敏感信息。被动攻击很难被发现,因此预防很重要,防止被动攻击的主要手段是数据加密传输。为了保护网络资源免受威胁和攻击,在密码学及安全协议的基础上发展了网络安全体系中的五类安全服务,它们是:身份认证、访问控制、数据保密、数据完整性和不可否认。对这五类安全服务,国际标准化组织ISO已经有了明确的定义。
◆ 主动攻击包括窃取、篡改、假冒和破坏。
主动攻击包括窃取、篡改、假冒和破坏。字典式口令猜测,IP地址欺骗和服务拒绝攻击等等都属于主动攻击。一个好的身份认证系统(包括数据加密、数据完整性校验、数字签名和访问控制等安全机制)可以用于防范主动攻击,但要想杜绝主动攻击很困难,因此对付主动攻击的另一措施是及时发现并及时恢复所造成的破坏,现在有很多实用的攻击检测工具。
PKI技术
PKI(Public Key Infrastructure),即公开密钥体系。它是利用公钥理论和技术建立的提供信息安全服务的基础设施,是国际公认的互联网电子商务的安全认证机制。它利用现代密码学中的公钥密码技术在开放的Internet网络环境中提供数据加密以及数字签名服务的统一的技术框架。
公钥是目前应用最广泛的一种加密体制,在此体系中,加密密钥与解密密钥各不相同,发送信息的人利用接收者的公钥发送加密信息,接收者再利用自己专有的私钥进行解密。这种方式既保证了信息的机密性,又能保证信息具有不可抵赖性。
PKI是一种遵循标准并利用公钥技术,为电子商务应用的开展提供一套安全基础平台的技术与规范,它能够透明地提供基于公开密钥的加密和数字签名等安全服务。利用PKI可以方便地建立和维护一个可信的网络计算环境,从而使得人们在这个无法直接相互面对的环境中能够确认彼此的身份和所交换的信息。
为实现以上目的,典型实用的PKI系统应由以下部分组成:PKI客户端、注册机构(RA)、认证机构(CA)和证书库。
◆ PKI客户端
PKI客户端的主要功能是使各种网络应用能够以透明、安全、一致、可信的方式与PKI交互,从而使用户能够方便地使用加密、数字签名等安全服务。
◆ 注册机构(RA)
RA则是用户与认证中心的接口,其主要功能是核实证书申请者的身份,它所获证书的申请者身份的准确性是CA颁发证书的基础。
◆ 认证机构(CA)
作为PKI核心的认证中心是证书颁发机构,由CA签发的证书是网上用户的电子身份标识。
◆ 证书库
证书库用来存放经CA签发的证书和证书注销列表(CRL),为用户和网络应用提供证书及验证证书状态。
