网路通信----笔记
正版 Visual C++网络通信开发入门与编程实践-------- 李媛媛
编辑推荐
超长时间多媒体有声讲解视频
全书以通信协议层的技术为主线
按网络体系结构从应用层到数据链路层逐一讲解
实例完美融合知识点、技巧、行业知识与成功经验
内容提要
本书从介绍通信基础知识和VC++基本编程模型开始,通过众多的小实例来贯穿讲解晦涩的基础知识;然后按照通信协议层展开,将通信协议层和实际应用结合,让读者在学习“基础”后学习中、高级应用,最终提高实际应用水平和独立编程技能;本书最后部分的综合案例,可以让读者对前面学习的内容融会贯通,以便深刻理解与实践应用。
本书的特点是:以通信协议层的技术为主线,在此基础上讲解各技术的应用范围,再通过众多小、中、大型实例来全面而生动地讲解VC++的知识,既能让读者全面地学习VC++技术,又能让读者联系实际,从而摆脱单纯讲解软件功能的枯燥学习模式。本书在讲解VC++的过程中还穿插大量提示和技巧,并对复杂和容易忽略的问题进行单独说明。书中的实例制作深入浅出,步骤详细清晰,可以帮助读者轻松、快速地学习VC++,能够保证对VC++不了解的读者也可以轻松学习。同时对实例进行细致的选择,使本书将知识点、技巧、行业知识和成功经验完美地融合到实例中,也让中级读者感觉物有所值。
本书所配光盘中包含多媒体视频教学和实例源文件。
本书适合VC++初、中级自学用户及VC++设计爱好者,同时也可作为计算机技能中级培训教材。
目录
第1章 Visual C++网络通信基础
1.1 计算机网络的组成及体系结构
1.1.1 网络边缘
1.1.2 网络核心
1.1.3 计算机网络的分层体系结构
1.2 初识Windows Sockets编程规范
1.2.1 Windows Sockets的相关概念
1.2.2 Winsock技术特点
1.2.3 Winsock编程原理
2.2.2 服务方式
UNIX系统的I/O命令集,是从Maltics和早期系统中的命令演变出来的,其模式为打开一读/写一关闭(open-write-read- close)。在一个用户进程进行I/O操作时,它首先调用"打开"获得对指定文件或设备的使用权,并返回称为文件描述符的整型数,以描述用户在打开的文 件或设备上进行I/O操作的进程。然后这个用户进程多次调用"读/写"以传输数据。当所有的传输操作完成后,用户进程关闭调用,通知操作系统已经完成了对 某对象的使用。
TCP/IP协议被集成到UNIX内核中时,相当于在UNIX系统引入了一种新型的I/O操作。UNIX用户进程与网络协议的交互作用比用户进程与传统的 I/O设备相互作用复杂得多。首先,进行网络操作的两个进程在不同机器上,如何建立它们之间的联系?其次,网络协议存在多种,如何建立一种通用机制以支持 多种协议?这些都是网络应用编程界面所要解决的问题。
在UNIX系统中,网络应用编程界面有两类:UNIX BSD的套接字(socket)和UNIX System V的TLI。由于Sun公司采用了支持TCP/IP的UNIX BSD操作系统,使TCP/IP的应用有更大的发展,其网络应用编程界面──套接字(socket)在网络软件中被广泛应用,至今已引进微机操作系统 DOS和Windows系统中,成为开发网络应用软件的强有力工具,本章将要详细讨论这个问题。
2.2 套接字编程基本概念
在开始使用套接字编程之前,首先必须建立以下概念。
2.2.1 网间进程通信
进程通信的概念最初来源于单机系统。由于每个进程都在自己的地址范围内运行,为保证两个相互通信的进程之间既互不干扰又协调一致工作,操作系统为进程通信 提供了相应设施,如UNIX BSD中的管道(pipe)、命名管道(named pipe)和软中断信号(signal),UNIX system V的消息(message)、共享存储区(shared memory)和信号量(semaphore)等,但都仅限于用在本机进程之间通信。网间进程通信要解决的是不同主机进程间的相互通信问题(可把同机进程 通信看作是其中的特例)。为此,首先要解决的是网间进程标识问题。同一主机上,不同进程可用进程号(process ID)唯一标识。但在网络环境下,各主机独立分配的进程号不能唯一标识该进程。例如,主机A赋于某进程号5,在B机中也可以存在5号进程,因此,"5号进 程"这句话就没有意义了。
其次,操作系统支持的网络协议众多,不同协议的工作方式不同,地址格式也不同。因此,网间进程通信还要解决多重协议的识别问题。
为了解决上述问题,TCP/IP协议引入了下列几个概念。
端口
网络中可以被命名和寻址的通信端口,是操作系统可分配的一种资源。
按照OSI七层协议的描述,传输层与网络层在功能上的最大区别是传输层提供进程通信能力。从这个意义上讲,网络通信的最终地址就不仅仅是主机地址了,还包 括可以描述进程的某种标识符。为此,TCP/IP协议提出了协议端口(protocol port,简称端口)的概念,用于标识通信的进程。
端口是一种抽象的软件结构(包括一些数据结构和I/O缓冲区)。应用程序(即进程)通过系统调用与某端口建立连接(binding)后,传输层传给该端口 的数据都被相应进程所接收,相应进程发给传输层的数据都通过该端口输出。在TCP/IP协议的实现中,端口操作类似于一般的I/O操作,进程获取一个端 口,相当于获取本地唯一的I/O文件,可以用一般的读写原语访问之。
类似于文件描述符,每个端口都拥有一个叫端口号(port number)的整数型标识符,用于区别不同端口。由于TCP/IP传输层的两个协议TCP和UDP是完全独立的两个软件模块,因此各自的端口号也相互独 立,如TCP有一个255号端口,UDP也可以有一个255号端口,二者并不冲突。
端口号的分配是一个重要问题。有两种基本分配方式:第一种叫全局分配,这是一种集中控制方式,由一个公认的中央机构根据用户需要进行统一分配,并将结果公 布于众。第二种是本地分配,又称动态连接,即进程需要访问传输层服务时,向本地操作系统提出申请,操作系统返回一个本地唯一的端口号,进程再通过合适的系 统调用将自己与该端口号联系起来(绑扎)。TCP/IP端口号的分配中综合了上述两种方式。TCP/IP将端口号分为两部分,少量的作为保留端口,以全局 方式分配给服务进程。因此,每一个标准服务器都拥有一个全局公认的端口(即周知口,well-known port),即使在不同机器上,其端口号也相同。剩余的为自由端口,以本地方式进行分配。TCP和UDP均规定,小于256的端口号才能作保留端口。
地址
网络通信中通信的两个进程分别在不同的机器上。在互连网络中,两台机器可能位于不同的网络,这些网络通过网络互连设备(网关,网桥,路由器等)连接。因此需要三级寻址:
1. 某一主机可与多个网络相连,必须指定一特定网络地址;
2. 网络上每一台主机应有其唯一的地址;
3. 每一主机上的每一进程应有在该主机上的唯一标识符。
通常主机地址由网络ID和主机ID组成,在TCP/IP协议中用32位整数值表示;TCP和UDP均使用16位端口号标识用户进程。
网络字节顺序
不同的计算机存放多字节值的顺序不同,有的机器在起始地址存放低位字节(低价先存),有的存高位字节(高价先存)。为保证数据的正确性,在网络协议中须指定网络字节顺序。TCP/IP协议使用16位整数和32位整数的高价先存格式,它们均含在协议头文件中。
连接
两个进程间的通信链路称为连接。连接在内部表现为一些缓冲区和一组协议机制,在外部表现出比无连接高的可靠性。
半相关
综上所述,网络中用一个三元组可以在全局唯一标志一个进程:
(协议,本地地址,本地端口号)
这样一个三元组,叫做一个半相关(half-association),它指定连接的每半部分。
全相关
一个完整的网间进程通信需要由两个进程组成,并且只能使用同一种高层协议。也就是说,不可能通信的一端用TCP协议,而另一端用UDP协议。因此一个完整的网间通信需要一个五元组来标识:
(协议,本地地址,本地端口号,远地地址,远地端口号)
这样一个五元组,叫做一个相关(association),即两个协议相同的半相关才能组合成一个合适的相关,或完全指定组成一连接。
在网络分层结构中,各层之间是严格单向依赖的,各层次的分工和协作集中体现在相邻层之间的界面上。"服务"是描述相邻层之间关系的抽象概念,即网络中各层 向紧邻上层提供的一组操作。下层是服务提供者,上层是请求服务的用户。服务的表现形式是原语(primitive),如系统调用或库函数。系统调用是操作 系统内核向网络应用程序或高层协议提供的服务原语。网络中的n层总要向n+1层提供比n-1层更完备的服务,否则n层就没有存在的价值。
在OSI的术语中,网络层及其以下各层又称为通信子网,只提供点到点通信,没有程序或进程的概念。而传输层实现的是"端到端"通信,引进网间进程通信概念,同时也要解决差错控制,流量控制,数据排序(报文排序),连接管理等问题,为此提供不同的服务方式:
面向连接(虚电路)或无连接
面向连接服务是电话系统服务模式的抽象,即每一次完整的数据传输都要经过建立连接,使用连接,终止连接的过程。在数据传输过程中,各数据分组不携带目的地 址,而使用连接号(connect ID)。本质上,连接是一个管道,收发数据不但顺序一致,而且内容相同。TCP协议提供面向连接的虚电路。
无连接服务是邮政系统服务的抽象,每个分组都携带完整的目的地址,各分组在系统中独立传送。无连接服务不能保证分组的先后顺序,不进行分组出错的恢复与重传,不保证传输的可靠性。UDP协议提供无连接的数据报服务。
下面给出这两种服务的类型及应用中的例子:
服务类型
服 务
例 子
面向连接
可靠的报文流
可靠的字节流
不可靠的连接
文件传输(FTP)
远程登录(Telnet)
数字话音
无连接
不可靠的数据报
有确认的数据报
请求-应答
电子邮件(E-mail)
电子邮件中的挂号信
网络数据库查询
顺序
在网络传输中,两个连续报文在端-端通信中可能经过不同路径,这样到达目的地时的顺序可能会与发送时不同。"顺序"是指接收数据顺序与发送数据顺序相同。TCP协议提供这项服务。
差错控制
保证应用程序接收的数据无差错的一种机制。检查差错的方法一般是采用检验"检查和(Checksum)"的方法。而保证传送无差错的方法是双方采用确认应答技术。TCP协议提供这项服务。
流控制
在数据传输过程中控制数据传输速率的一种机制,以保证数据不被丢失。TCP协议提供这项服务。
字节流
字节流方式指的是仅把传输中的报文看作是一个字节序列,不提供数据流的任何边界。TCP协议提供字节流服务。
报文
接收方要保存发送方的报文边界。UDP协议提供报文服务。
全双工/半双工
端-端间数据同时以两个方向/一个方向传送。
缓存/带外数据
在字节流服务中,由于没有报文边界,用户进程在某一时刻可以读或写任意数量的字节。为保证传输正确或采用有流控制的协议时,都要进行缓存。但对某些特殊的需求,如交互式应用程序,又会要求取消这种缓存。
在 数据传送过程中,希望不通过常规传输方式传送给用户以便及时处理的某一类信息,如UNIX系统的中断键(Delete或Control-c)、终端流控制 符(Control-s和Control-q),称为带外数据。逻辑上看,好象用户进程使用了一个独立的通道传输这些数据。该通道与每对连接的流相联系。 由于Berkeley Software Distribution中对带外数据的实现与RFC 1122中规定的Host Agreement不一致,为了将互操作中的问题减到最小,应用程序编写者除非与现有服务互操作时要求带外数据外,最好不使用它。
2.2.3 客户/服务器模式
在TCP/IP 网络应用中,通信的两个进程间相互作用的主要模式是客户/服务器模式(Client/Server model),即客户向服务器发出服务请求,服务器接收到请求后,提供相应的服务。客户/服务器模式的建立基于以下两点:首先,建立网络的起因是网络中软 硬件资源、运算能力和信息不均等,需要共享,从而造就拥有众多资源的主机提供服务,资源较少的客户请求服务这一非对等作用。其次,网间进程通信完全是异步 的,相互通信的进程间既不存在父子关系,又不共享内存缓冲区,因此需要一种机制为希望通信的进程间建立联系,为二者的数据交换提供同步,这就是基于客户/ 服务器模式的TCP/IP。
客户/服务器模式在操作过程中采取的是主动请求方式:
首先服务器方要先启动,并根据请求提供相应服务:
1. 打开一通信通道并告知本地主机,它愿意在某一公认地址上(周知口,如FTP为21)接收客户请求;
2. 等待客户请求到达该端口;
3. 接收到重复服务请求,处理该请求并发送应答信号。接收到并发服务请求,要激活一新进程来处理这个客户请求(如UNIX系统中用fork、exec)。新进程处理此客户请求,并不需要对其它请求作出应答。服务完成后,关闭此新进程与客户的通信链路,并终止。
4. 返回第二步,等待另一客户请求。
5. 关闭服务器
客户方:
1. 打开一通信通道,并连接到服务器所在主机的特定端口;
2. 向服务器发服务请求报文,等待并接收应答;继续提出请求......
3. 请求结束后关闭通信通道并终止。
从上面所描述过程可知:
1. 客户与服务器进程的作用是非对称的,因此编码不同。
2. 服务进程一般是先于客户请求而启动的。只要系统运行,该服务进程一直存在,直到正常或强迫终止。
2.2.4 套接字类型
TCP/IP的socket提供下列三种类型套接字。
流式套接字(SOCK_STREAM)
提供了一个面向连接、可靠的数据传输服务,数据无差错、无重复地发送,且按发送顺序接收。内设流量控制,避免数据流超限;数据被看作是字节流,无长度限制。文件传送协议(FTP)即使用流式套接字。
数据报式套接字(SOCK_DGRAM)
提供了一个无连接服务。数据包以独立包形式被发送,不提供无错保证,数据可能丢失或重复,并且接收顺序混乱。网络文件系统(NFS)使用数据报式套接字。
原始式套接字(SOCK_RAW)
该接口允许对较低层协议,如IP、ICMP直接访问。常用于检验新的协议实现或访问现有服务中配置的新设备。
2.3 基本套接字系统调用
为了更好地说明套接字编程原理,下面给出几个基本套接字系统调用说明。
2.3.1 创建套接字──socket()
应用 程序在使用套接字前,首先必须拥有一个套接字,系统调用socket()向应用程序提供创建套接字的手段,其调用格式如下:
SOCKET PASCAL FAR socket(int af, int type, int protocol);
该 调用要接收三个参数:af、type、protocol。参数af指定通信发生的区域,UNIX系统支持的地址族有:AF_UNIX、AF_INET、 AF_NS等,而DOS、WINDOWS中仅支持AF_INET,它是网际网区域。因此,地址族与协议族相同。参数type 描述要建立的套接字的类型。参数protocol说明该套接字使用的特定协议,如果调用者不希望特别指定使用的协议,则置为0,使用默认的连接模式。根据 这三个参数建立一个套接字,并将相应的资源分配给它,同时返回一个整型套接字号。因此,socket()系统调用实际上指定了相关五元组中的"协议"这一 元。
1.2.4 实例—Willsock实现基于TCP的客户端/服务器通信
C/S模式
客户机/服务器模式的建立基于以下两点:首先,建立网络的起因是网络中软硬件资源、运算能力和信息不均等,需要共享,从而造就拥有众多资源的主机提供服务,资源较少的客户请求服务这一非对等作用。其次,网间进程通信完全是异步的,相互通信的进程间既不存在父子关系,又不共享内存缓冲区,因此需要一种机制为希望通信的进程间建立联系,为二者的数据交换提供同步,这就是基于客户机/服务器模式的TCP/IP。
客户机/服务器模式在操作过程中采取的是主动请求的方式。
基于TCP(面向连接)的socket编程
服务端进程通过bind方法将其套接字告知系统,以使其他的套接字能找到它。它可通过套接字的“侦听(listen)”来“接收(accept)”发过来的信息。客户端的进程同服务端套接字建立连接然后交换信息。需要的信息都可以从该通道向任一端进行发送。
服务器:
创建端点 (socket())
绑定地址(bind())
指定队列(listen())
等待连接 (accept())
传输数据 (read()/write())
客户端:
创建端点 (socket())
链接服务器 (connect())
传输数据(read()/write())
基于UDP(面向无连接)的socket编程
用无连接协议,双方的套接字都需要用bind方法来告知系统。这是因为每方的信息都会单独处理,所以每次服务端发信息过来时,客户端都需要找到它,反之亦然。每次调用bind方法,都绑定了一个新的端口。当然,如果端口已经被使用了,则是不能被绑定的。如果你指定的端口为0,则系统会把当前可用的端口自动给你一个。由于发送信息的额外任务,进程不会使用read/write方法,而是使用recvfrom/sendto方法。这两个方法的参数一个是要写入的套接字,另一个则是远程计算机上服务的地址。
服务端:
创建端点(socket())
绑定地址 (bind())
传输数据(sendto()/recvfrom())
客户端:
创建端点 (socket())
绑定地址(bind()) (connect方法可选择调用)
连接服务端(connect())
传输数据(sendto()/recvfrom())
多线程的设计
《VC中利用多线程技术实现线程之间的通信》这篇文章比较适合线程的了解,Win32 提供了一系列的API函数来完成线程的创建、挂起、恢复、终结以及通信等工作。MFC中使用线程要注意:
1、尽量少的使用全局变量、static变量做共享数据,尽量使用参数传递对象。
2、在MFC中请慎用线程。因为MFC的框架假定你的消息处理都是在主线程中完成的。首先窗口句柄是属于线程的,如果拥有窗口句柄的线程退出了,如果另一个线程处理这个窗口句柄,系统就会出现问题。而MFC为了避免这种情况的发生,使你在子线程中调用消息(窗口)处理函数时,就会不停的出Assert错误,烦都烦死你。典型的例子就时CSocket,因为CSocket是使用了一个隐藏窗口实现了假阻塞,所以不可避免的使用了消息处理函数,如果你在子线程中使用CSocket,你就可能看到assert的弹出了。
3、不要在不同的线程中同时注册COM组件。
常见问题的解决
1、关闭套接字
我们在利用IOCP(完成端口)进行程序设计的时候,经常要关闭一些不满足条件的套接字。假如我们直接采用closesocket方法进行关闭的话,绑定到IO端口的此套接字的未发送的数据就会丢失,这种情况是我们不愿意发生的。下面介绍一种合理关闭此套接字的方法:
首先,利用setsockopt(MSDN)函数设定套接字的选项,我们把此套接字设定为:假如有数据未发送,当数据发送完后再关闭此套接字。
代码如下:
LINGER lingerStruct;
lingerStruct.l_onoff = 1;
lingerStruct.l_linger = 0;
setsockopt(Socket, SOL_SOCKET, SO_LINGER,
(char *)&lingerStruct, sizeof(lingerStruct) );
// Now close the socket handle. This will do an abortive or graceful close, as requested.
CancelIo((HANDLE) Socket);
closesocket(Socket);
clientSocket = INVALID_SOCKET;
当在完成端口的数据被发送出去之后,套接字就会被关闭,这样我们就完成了一个套接字的关闭。
<参考 http://www.examda.com/ncre2/cpp/fudao/20090107/091252332.html>
2、解决 Socket API错误代码:WSAECONNRESET (10054)
出现原因:使用UDP SOCKET时(利用事件触发方式),如果发送端在发送数据时(WSASendTo),接收端没还有创建,那么发送端将会收到一个事件通知,此时调用WSARecv()函数时将会产生调用错误(WSAECONNRESET ),从这以后,这个发送端这个SOCKET无法接受到数据。解决办法:
a.头文件中加入下面代码:
#include <Winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#define IOC_VENDOR 0x18000000
#define _WSAIOW(x,y) (IOC_IN|(x)|(y))
#define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR,12)
b.在创建socket之后加入下面代码:
DWORD dwBytesReturned = 0;
BOOL bNewBehavior = FALSE;
DWORD status;
status = WSAIoctl(m_hSock, SIO_UDP_CONNRESET,
&bNewBehavior,
sizeof (bNewBehavior),
NULL, 0, &dwBytesReturned,
NULL, NULL);
<参考 http://blog.csdn.net/wupangzi/archive/2009/07/27/4384081.aspx及http://hi.baidu.com/jetqu2003/blog/item/397700031435e9703812bbcc.html>
1.3 利用MFC网络编程
1.3.1 CAsyncSocket类的基本组成
1.3.2 CSocket类的基本组成
1.3.3 Winlnet类的基本组成
1.3.4 实例——基于CSocket的网络聊天室
第2章 认识Windows编程模型
2.1 Windows初级编程模型
2.1.1 匈牙利命名法
2.1.2 Visual C++使用入门
2.1.3 最简单的Windows应用程序
2.2 Windows应用程序剖析
2.2.1 真正的Windows应用程序
2.2.2 Windows程序分析
2.2.3 重要的消息事件处理
2.2.4 Windows控件的应用
2.3 Windows高级编程
2.3.1 利用Windows菜单中的位图资源
2.3.2 利用资源制作菜单
2.4 小结
第3章 网络基本应用在VC++中的实现
3.1 获取网卡的MAC地址
3.1.1 原理
3.1.2 实现程序
3.2 获取网络中计算机的IP地址和计算机名
深入DNS域名解析服务原理
DNS分为Client和Server,Client扮演发问的角色,也就是问Server一个Domain Name,而Server必须要回答此Domain Name的真正IP地址。而当地的DNS先会查自己的资料库。如果自己的资料库没有,则会往该DNS上所设的的DNS询问,依此得到答案之后,将收到的答案存起来,并回答客户。
DNS服务器会根据不同的授权区(Zone),记录所属该网域下的各名称资料,这个资料包括网域下的次网域名称及主机名称。
在每一个名称服务器中都有一个快取缓存区(Cache),这个快取缓存区的主要目的是将该名称服务器所查询出来的名称及相对的IP地址记录在快取缓存区中,这样当下一次还有另外一个客户端到次服务器上去查询相同的名称 时,服务器就不用在到别台主机上去寻找,而直接可以从缓存区中找到该笔名称记录资料,传回给客户端,加速客户端对名称查询的速度。例如:
当DNS客户端向指定的DNS服务器查询网际网路上的某一台主机名称 DNS服务器会在该资料库中找寻用户所指定的名称 如果没有,该服务器会先在自己的快取缓存区中查询有无该笔纪录,如果找到该笔名称记录后,会从DNS服务器直接将所对应到的IP地址传回给客户端 ,如果名称服务器在资料记录查不到且快取缓存区中也没有时,服务器首先会才会向别的名称服务器查询所要的名称。例如:
DNS客户端向指定的DNS服务器查询网际网路上某台主机名称,当DNS服务器在该资料记录找不到用户所指定的名称时,会转向该服务器的快取缓存区找寻是否有该资料 ,当快取缓存区也找不到时,会向最接近的名称服务器去要求帮忙找寻该名称的IP地址 ,在另一台服务器上也有相同的动作的查询,当查询到后会回复原本要求查询的服务器,该DNS服务器在接收到另一台DNS服务器查询的结果后,先将所查询到的主机名称及对应IP地址记录到快取缓存区中 ,最后在将所查询到的结果回复给客户端 。
范例
我们举例说明,假设我们要查询网际网路上的一个名称为www.test.com.cn,从此名称我们知道此部主机在中国CN,而且要找的组织名称test.com.cn此网域下的www主机,以下为名称解析过程的每一步骤。
《Step 1》在DNS的客户端(Reslover)键入查询主机的指令,如:
c:\ping www.test.com.cn
pinging www.test.com.cn 【192.72.80.36】with 32bytes of data
reply from 192.72.80.36 bytes time <10ms ttl 253
《Step 2》而被指定的DNS服务器先行查询是否属于该网域下的主机名称,如果查出改主机名称并不属于该网域范围,之后会再查询快取缓存区的纪录资料,查是否有此机名称。
《Step 3》查询后发现缓存区中没有此纪录资料,会取得一台根网域的其中一台服务器,发出说要找www.test.com.cn的Request。
《Step 4》在根网域中,向Root Name Server询问,Root Name Server记录了各Top Domain分别是由哪些DNS Server负责,所以他会响应最接近的Name Server为控制CN网域的DNS伺服主机。
《Step 5》Root Name Server已告诉Local DNS Server哪部Name Server负责.cn这个Domain,然后Local DNS再向负责发出找寻www.test.com.cn的名称Request。
《Step 6》在.cn这个网域中,被指定的DNS服务器在本机上没有找到此名称的的纪录,所以会响应原本发出查询要求的DNS服务器说最近的服务器在哪里?他会回应最近的主机为控制com.cn网域的DNS伺服主机。
《Step 7》原本被查询的DNS服务器主机,收到继续查询的IP位置后,会再向com.cn的网域的DNS Server发出寻找www.test.com.cn名称搜寻的要求。
《Step 8》com.cn的网域中,被指定的DNS Server在本机上没有找到此名称的记录,所以会回复查询要求的DNS Server告诉他最接近的服务器在哪里?他就回应最接近为控制test.com.cn的网域的DNS主机。
《Step 9》原本被查询的DNS Server,在接收到应继续查询的位置,在向test.com.cn网域的DNS Server发出寻找www.test.com.cn的要求,最后会在test.com.cn的网域的DNS Server找到www.test.com.cn此主机的IP。
《Step 10》所以原本发出查询要求的DNS服务器,再接收到查询结果的IP位置后,响应回给原查询名称的DNS客户端。
两种真正DNS的查询模式
有两种询问原理,分为Recursive和Interactive两种。前者是由DNS代理去问,问的方法是用Interactive方式,后者是由本机直接做Interactive式的询问。由上例可以看出,我们一般查询名称的过程中,实际上这两种查询模式都是交互存在着的。
递归式(Recursive):DNS客户端向DNS Server的查询模式,这种方式是将要查询的封包送出去问,就等待正确名称的正确响应,这种方式只处理响应回来的封包是否是正确响应或是说是找不到该名称的错误讯息。
交谈式(Interactive):DNS Server间的查询模式,由Client端或是DNS Server上所发出去问,这种方式送封包出去问,所响应回来的资料不一定是最后正确的名称位置,但也不是如上所说的响应回来是错误讯息,他响应回来告诉你最接近的IP位置,然后再到此最接近的IP上去寻找所要解析的名称,反复动作直到找到正确位置。
3.2.1 原理
3.2.2 实现程序
3.3 超链接程序的原理与实现
3.3.1 原理
3.3.2 实现程序
超级链接程序原理与实现MFC网络编程 2010-12-21 21:02:49 阅读 评论 字号:大中小 订阅 .
(一)原理:要实现超级链接程序,首先创建一个CHyperLink类,而该类是从静态文本框类Static继承而来的,因此具备了CStatic的所有属性,同时在该类的基础上,扩展一些功能,比如设定颜色、设定鼠标形状等,然后通过对操作函数的调用链接到相应的URL
(二)类声明部分的代码:
class CHyperLink : public CStatic
{
// Construction
public:
CHyperLink();
// Attributes
public:
// Operations
public:
void SetURL(CString strURL);//设定URL
CString GetURL()const;//获得URL
void SetColours(COLORREF crLinkColour,COLORREF crVisitedColour,COLORREF crHoverColour=-1);//设定颜色
COLORREF GetLinkColour()const;//获得连接颜色
COLORREF GetVisitedColour() const;//获得被访问后的颜色
COLORREF GetHoverColour()const;//获得鼠标移动上以后的颜色
void SetVisited(BOOL bVisited=TRUE);//设定是否被访问过
BOOL GetVisited()const;//获得是否被访问过
void SetLinkCursor(HCURSOR hCursor);//设定鼠标形状
HCURSOR GetLinkCursor()const;//获得鼠标形状
void SetUnderline(BOOL bUnderline=TRUE);//设定是否有下划线
BOOL GetUnderline()const;//获得是否有下划线
void SetAutoSize(BOOL bAutoSize=TRUE);//设定是否是自动改变大小
BOOL GetAutoSize() const;
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CHyperLink)
public:
virtual BOOL PreTranslateMessage(MSG* pMsg);
protected:
virtual void PreSubclassWindow();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CHyperLink();
protected:
HINSTANCE GotoURL(LPCTSTR url,int showcmd);//连接到URL
void ReportError(int nError);//打印错误
LONG GetRegKey(HKEY key,LPCTSTR subkey,LPTSTR retdata);//获得注册表信息
void PositionWindow();//调整位置
void SetDefaultCursor();//设定默认的鼠标形状
protected:
COLORREF m_crLinkColour,m_crVisitedColour; //超级链接颜色
COLORREF m_crHoverColour;//鼠标停留颜色
BOOL m_bOverControl;//是否鼠标移到控件上
BOOL m_bVisited;//是否被访问
BOOL m_bUnderline;//是否有下画线
BOOL m_bAdjustToFit;//是否自动调整控件大小
CString m_strURL;//URL
CFont m_Font;//设定字体
HCURSOR m_hLinkCursor;//光标
CToolTipCtrl m_ToolTip;//提示文字
// Generated message map functions
//{{AFX_MSG(CHyperLink)
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
afx_msg void OnClicked();
afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
(三)类实现部分的代码:
BOOL CHyperLink::PreTranslateMessage(MSG* pMsg) //重载该函数,可以处理键盘和鼠标消息
{
// TODO: Add your specialized code here and/or call the base class
m_ToolTip.RelayEvent(pMsg);
return CStatic::PreTranslateMessage(pMsg);
}
void CHyperLink::PreSubclassWindow() //定制控件
{
// 获得鼠标单击事件
DWORD dwStyle = GetStyle();
::SetWindowLong(GetSafeHwnd(), GWL_STYLE, dwStyle | SS_NOTIFY);
// 如果URL为空,设定为窗体名称
if (m_strURL.IsEmpty())
GetWindowText(m_strURL);
// 同时检查窗体标题是否为空,如果为空则设定为URL
CString strWndText;
GetWindowText(strWndText);
if (strWndText.IsEmpty()) {
ASSERT(!m_strURL.IsEmpty());
SetWindowText(m_strURL);
}
// 创建字体
LOGFONT lf;
GetFont()->GetLogFont(&lf);
lf.lfUnderline = m_bUnderline;
m_Font.CreateFontIndirect(&lf);
SetFont(&m_Font);
PositionWindow(); // 调整窗体大小
SetDefaultCursor(); // 设定默认鼠标形状
//创建提示信息
CRect rect;
GetClientRect(rect);
m_ToolTip.Create(this);
m_ToolTip.AddTool(this, m_strURL, rect, TOOLTIP_ID);
CStatic::PreSubclassWindow();
}
HBRUSH CHyperLink::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CStatic::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: Change any attributes of the DC here
// TODO: Return a different brush if the default is not desired
return hbr;
}
void CHyperLink::OnMouseMove(UINT nFlags, CPoint point) //鼠标移动事件
{
// TODO: Add your message handler code here and/or call default
CStatic::OnMouseMove(nFlags, point);
if(m_bOverControl) //判断是否鼠标在控件上方
{
CRect rect;
GetClientRect(rect);
if(!rect.PtInRect(point))
{
m_bOverControl=FALSE;
ReleaseCapture();
RedrawWindow();
return;
}
}
else
{
m_bOverControl=TRUE;
RedrawWindow();
SetCapture();
}
}
BOOL CHyperLink::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: Add your message handler code here and/or call default
if (m_hLinkCursor)
{
::SetCursor(m_hLinkCursor);
return TRUE;
}
return FALSE;
}
void CHyperLink::OnClicked()
{
int result = (int)GotoURL(m_strURL, SW_SHOW);
m_bVisited = (result > HINSTANCE_ERROR);
if (!m_bVisited) {
MessageBeep(MB_ICONEXCLAMATION); // Unable to follow link
ReportError(result);
} else
SetVisited(); // Repaint to show visited colour
}
void CHyperLink::PositionWindow()//调整窗口位置事件
{
if(!::IsWindow(GetSafeHwnd()) || m_bAdjustToFit)
return ;
CRect rect;//得到当前窗口的位置
GetWindowRect(rect);
CWnd* pParent=GetParent();
if(pParent)
pParent->ScreenToClient(rect);
CString strWndText; //得到窗口文本的大小
GetWindowText(strWndText);
CDC* pDC=GetDC();
CFont* pOldFont=pDC->SelectObject(&m_Font);
CSize Extent=pDC->GetTextExtent(strWndText);
pDC->SelectObject(pOldFont);
ReleaseDC(pDC);
DWORD dwStyle=GetStyle();//通过窗口的风格获得文本的环境
if(dwStyle & SS_CENTERIMAGE)
rect.DeflateRect(0,(rect.Height()-Extent.cy)/2);
else
rect.bottom=rect.top+Extent.cy;
if(dwStyle & SS_CENTER)
rect.DeflateRect((rect.Width()-Extent.cx)/2,0);
else if(dwStyle & SS_RIGHT)
rect.left=rect.right-Extent.cx;
else
rect.right=rect.left+Extent.cx;
SetWindowPos(NULL,rect.left,rect.top,rect.Width(),rect.Height(),SWP_NOZORDER);
}
//链接到目标地址
HINSTANCE CHyperLink::GotoURL(LPCTSTR url, int showcmd)
{
TCHAR key[MAX_PATH + MAX_PATH];
// 调用函数ShellExecute()
HINSTANCE result = ShellExecute(NULL, _T("open"), url, NULL,NULL, showcmd);
// 如果错误,则检查注册表获得.htm文件的注册键值
if ((UINT)result <= HINSTANCE_ERROR) {
if (GetRegKey(HKEY_CLASSES_ROOT, _T(".htm"), key) == ERROR_SUCCESS) {
lstrcat(key, _T("\\shell\\open\\command"));
if (GetRegKey(HKEY_CLASSES_ROOT,key,key) == ERROR_SUCCESS) {
TCHAR *pos;
pos = _tcsstr(key, _T("\"%1\""));
if (pos == NULL) { // 没有发现
pos = strstr(key, _T("%1")); // 检查%1
if (pos == NULL) // 没有参数
pos = key+lstrlen(key)-1;
else
*pos = '\0'; // 删除参数
}
else
*pos = '\0'; // 删除参数
lstrcat(pos, _T(" "));
lstrcat(pos, url);
result = (HINSTANCE) WinExec(key,showcmd);
}
}
}
return result;
}
HBRUSH CHyperLink::CtlColor(CDC* pDC, UINT nCtlColor)
{
ASSERT(nCtlColor == CTLCOLOR_STATIC);
if (m_bOverControl)
pDC->SetTextColor(m_crHoverColour);
else if (m_bVisited)
pDC->SetTextColor(m_crVisitedColour);
else
pDC->SetTextColor(m_crLinkColour);
// transparent text.
pDC->SetBkMode(TRANSPARENT);
return (HBRUSH)GetStockObject(NULL_BRUSH);
}
BOOL CHyperLink::GetAutoSize() const
{
return m_bAdjustToFit;
}
COLORREF CHyperLink::GetHoverColour() const//获得鼠标移动上以后的颜色
{
return m_crHoverColour;
}
COLORREF CHyperLink::GetLinkColour() const//获得连接颜色
{
return m_crLinkColour;
}
HCURSOR CHyperLink::GetLinkCursor() const//获得鼠标形状
{
return m_hLinkCursor;
}
LONG CHyperLink::GetRegKey(HKEY key, LPCTSTR subkey, LPTSTR retdata)//获得注册表信息
{
HKEY hkey;
LONG retval = RegOpenKeyEx(key, subkey, 0, KEY_QUERY_VALUE, &hkey);
if (retval == ERROR_SUCCESS) {
long datasize = MAX_PATH;
TCHAR data[MAX_PATH];
RegQueryValue(hkey, NULL, data, &datasize);
lstrcpy(retdata,data);
RegCloseKey(hkey);
}
return retval;
}
BOOL CHyperLink::GetUnderline() const//获得是否有下划线
{
return m_bUnderline;
}
CString CHyperLink::GetURL() const//获得URL
{
return m_strURL;
}
BOOL CHyperLink::GetVisited() const//获得是否被访问过
{
return m_bVisited;
}
COLORREF CHyperLink::GetVisitedColour() const//获得被访问后的颜色
{
return m_crVisitedColour;
}
void CHyperLink::ReportError(int nError)//打印错误
{
CString str;
switch (nError) {
case 0: str = "The operating system is out\nof memory or resources."; break;
case SE_ERR_PNF: str = "The specified path was not found."; break;
case SE_ERR_FNF: str = "The specified file was not found."; break;
case ERROR_BAD_FORMAT: str = "The .EXE file is invalid\n(non-Win32 .EXE or error in .EXE image)."; break;
case SE_ERR_ACCESSDENIED: str = "The operating system denied\naccess to the specified file."; break;
case SE_ERR_ASSOCINCOMPLETE: str = "The filename association is\nincomplete or invalid."; break;
case SE_ERR_DDEBUSY: str = "The DDE transaction could not\nbe completed because other DDE transactions\nwere being processed."; break;
case SE_ERR_DDEFAIL: str = "The DDE transaction failed."; break;
case SE_ERR_DDETIMEOUT: str = "The DDE transaction could not\nbe completed because the request timed out."; break;
case SE_ERR_DLLNOTFOUND: str = "The specified dynamic-link library was not found."; break;
case SE_ERR_NOASSOC: str = "There is no application associated\nwith the given filename extension."; break;
case SE_ERR_OOM: str = "There was not enough memory to complete the operation."; break;
case SE_ERR_SHARE: str = "A sharing violation occurred. ";
default: str.Format("Unknown Error (%d) occurred.", nError); break;
}
str = "Unable to open hyperlink:\n\n" + str;
AfxMessageBox(str, MB_ICONEXCLAMATION | MB_OK);
}
void CHyperLink::SetAutoSize(BOOL bAutoSize /* = TRUE */)//设定是否自动改变大小
{
m_bAdjustToFit = bAutoSize;
if (::IsWindow(GetSafeHwnd()))
PositionWindow();
}
//设定颜色
void CHyperLink::SetColours(COLORREF crLinkColour, COLORREF crVisitedColour,
COLORREF crHoverColour /* = -1 */)
{
m_crLinkColour = crLinkColour;
m_crVisitedColour = crVisitedColour;
if (crHoverColour == -1)
m_crHoverColour = ::GetSysColor(COLOR_HIGHLIGHT);
else
m_crHoverColour = crHoverColour;
if (::IsWindow(m_hWnd))
Invalidate();
}
void CHyperLink::SetDefaultCursor()//设定默认的鼠标形状
{
if (m_hLinkCursor == NULL) // No cursor handle - load our own
{
// Get the windows directory
CString strWndDir;
GetWindowsDirectory(strWndDir.GetBuffer(MAX_PATH), MAX_PATH);
strWndDir.ReleaseBuffer();
strWndDir += _T("\\winhlp32.exe");
// This retrieves cursor #106 from winhlp32.exe, which is a hand pointer
HMODULE hModule = LoadLibrary(strWndDir);
if (hModule) {
HCURSOR hHandCursor = ::LoadCursor(hModule, MAKEINTRESOURCE(106));
if (hHandCursor)
m_hLinkCursor = CopyCursor(hHandCursor);
}
FreeLibrary(hModule);
}
}
void CHyperLink::SetLinkCursor(HCURSOR hCursor)//设定鼠标形状
{
m_hLinkCursor = hCursor;
if (m_hLinkCursor == NULL)
SetDefaultCursor();
}
//设置下划线
void CHyperLink::SetUnderline(BOOL bUnderline /* = TRUE */)
{
m_bUnderline = bUnderline;
if (::IsWindow(GetSafeHwnd()))
{
LOGFONT lf;
GetFont()->GetLogFont(&lf);
lf.lfUnderline = m_bUnderline;
m_Font.DeleteObject();
m_Font.CreateFontIndirect(&lf);
SetFont(&m_Font);
Invalidate();
}
}
//设定URL
void CHyperLink::SetURL(CString strURL)
{
m_strURL = strURL;
if (::IsWindow(GetSafeHwnd())) {
PositionWindow();
m_ToolTip.UpdateTipText(strURL, this, TOOLTIP_ID);
}
}
void CHyperLink::SetVisited(BOOL bVisited /* = TRUE */) //设定是否被访问过
{
m_bVisited = bVisited;
if (::IsWindow(GetSafeHwnd()))
Invalidate();
}
3.4 获取域名和网卡类型的原理和实现
3.4.1 原理
3.4.2 实现程序
3.5 小结
第4章 串口通信及其实例
4.1 串行通信原理
4.1.1 串行通信基本概念
4.1.2 单工、半双工和全双工定义
4.1.3 串行通信协议
4.1.4 串行通信方式
4.2 MSComm控件
4.2.1 VC++中的MSComm控件
4.2.2 实例——-MSCscorIlIn多串口通信
4.3 Windows APl串口通信编程
4.3.1 Windows串口通信API函数
4.3.2 VC++中的CserialPort类
4.3.3 实例——串口的多线程通信
4.4小结
第5章 应用层协议及编程实例
5.1 应用层协议体系结构
5.1.1 应用层协议原理
5.1.2 网络应用程序的体系结构
5.2 HTTP协议
5.2.1 HTTP协议
http协议的主要特点
HTTP协议的主要特点可概括如下:
1.支持客户/服务器模式。
2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type(Content-Type是HTTP包中用来表示内容类型的标识)加以标记。
4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
1.连接(Connection):一个传输层的实际环流,它是建立在两个相互通讯的应用程序之间。 2.消息(Message):HTTP通讯的基本单位,包括一个结构化的八元组序列并通过连接传输。 3.请求(Request):一个从客户端到服务器的请求信息包括应用于资源的方法、资源的标
HTTP协议的几个重要概念
1.连接(Connection):一个传输层的实际环流,它是建立在两个相互通讯的应用程序之间。
2.消息(Message):HTTP通讯的基本单位,包括一个结构化的八元组序列并通过连接传输。
3.请求(Request):一个从客户端到服务器的请求信息包括应用于资源的方法、资源的标识符和协议的版本号
4.响应(Response):一个从服务器返回的信息包括HTTP协议的版本号、请求的状态(例如“成功”或“没找到”)和文档的MIME类型。
5.资源(Resource):由URI标识的网络数据对象或服务。
6.实体(Entity):数据资源或来自服务资源的回映的一种特殊表示方法,它可能被包围在一个请求或响应信息中。一个实体包括实体头信息和实体的本身内容。
7.客户机(Client):一个为发送请求目的而建立连接的应用程序。
8.用户代理(Useragent):初始化一个请求的客户机。它们是浏览器、编辑器或其它用户工具。
9.服务器(Server):一个接受连接并对请求返回信息的应用程序。
10.源服务器(Originserver):是一个给定资源可以在其上驻留或被创建的服务器。
11.代理(Proxy):一个中间程序,它可以充当一个服务器,也可以充当一个客户机,为其它客户机建立请求。请求是通过可能的翻译在内部或经过传递到其它的服务器中。一个代理在发送请求信息之前,必须解释并且如果可能重写它。
代理经常作为通过防火墙的客户机端的门户,代理还可以作为一个帮助应用来通过协议处理没有被用户代理完成的请求。
12.网关(Gateway):一个作为其它服务器中间媒介的服务器。与代理不同的是,网关接受请求就好象对被请求的资源来说它就是源服务器;发出请求的客户机并没有意识到它在同网关打交道。
网关经常作为通过防火墙的服务器端的门户,网关还可以作为一个协议翻译器以便存取那些存储在非HTTP系统中的资源。
13.通道(Tunnel):是作为两个连接中继的中介程序。一旦激活,通道便被认为不属于HTTP通讯,尽管通道可能是被一个HTTP请求初始化的。当被中继的连接两端关闭时,通道便消失。当一个门户(Portal)必须存在或中介(Intermediary)不能解释中继的通讯时通道被经常使用。
14.缓存(Cache):反应信息的局域存储。
HTTP协议基础
HTTP(HyperTextTransferProtocol)是超文本传输协议的缩写,它用于传送WWW方式的数据,关于HTTP协议的详细内容请参考RFC2616。HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求,请求头包含请求的方法、URI、协议版本、以及包含请求修饰符、客户信息和内容的类似于MIME的消息结构。服务器以一个状态行作为响应,相应的内容包括消息协议的版本,成功或者错误编码加上包含服务器信息、实体元信息以及可能的实体内容。
通常HTTP消息包括客户机向服务器的请求消息和服务器向客户机的响应消息。这两种类型的消息由一个起始行,一个或者多个头域,一个只是头域结束的空行和可选的消息体组成。HTTP的头域包括通用头,请求头,响应头和实体头四个部分。每个头域由一个域名,冒号(:)和域值三部分组成。域名是大小写无关的,域值前可以添加任何数量的空格符,头域可以被扩展为多行,在每行开始处,使用至少一个空格或制表符。
通用头域
通用头域包含请求和响应消息都支持的头域,通用头域包含Cache-Control、Connection、Date、Pragma、Transfer-Encoding、Upgrade、Via。对通用头域的扩展要求通讯双方都支持此扩展,如果存在不支持的通用头域,一般将会作为实体头域处理。下面简单介绍几个在UPnP消息中使用的通用头域。
Cache-Control头域
Cache-Control指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置Cache-Control并不会修改另一个消息处理过程中的缓存处理过程。请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached,响应消息中的指令包括public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age。各个消息中的指令含义如下:
Public指示响应可被任何缓存区缓存。
Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。
no-cache指示请求或响应消息不能缓存
no-store用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
max-age指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。
min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应。
max-stale指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。
Date头域
Date头域表示消息发送的时间,时间的描述格式由rfc822定义。例如,Date:Mon,31Dec200104:25:57GMT。Date描述的时间表示世界标准时,换算成本地时间,需要知道用户所在的时区。
Pragma头域
Pragma头域用来包含实现特定的指令,最常用的是Pragma:no-cache。在HTTP/1.1协议中,它的含义和Cache-Control:no-cache相同。
请求消息
请求消息的第一行为下面的格式:
MethodSPRequest-URISPHTTP-VersionCRLFMethod表示对于Request-URI完成的方法,这个字段是大小写敏感的,包括OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE。方法GET和HEAD应该被所有的通用WEB服务器支持,其他所有方法的实现是可选的。GET方法取回由Request-URI标识的信息。HEAD方法也是取回由Request-URI标识的信息,只是可以在响应时,不返回消息体。POST方法可以请求服务器接收包含在请求中的实体信息,可以用于提交表单,向新闻组、BBS、邮件群组和数据库发送消息。
SP表示空格。Request-URI遵循URI格式,在此字段为星号(*)时,说明请求并不用于某个特定的资源地址,而是用于服务器本身。HTTP-Version表示支持的HTTP版本,例如为HTTP/1.1。CRLF表示换行回车符。请求头域允许客户端向服务器传递关于请求或者关于客户机的附加信息。请求头域可能包含下列字段Accept、Accept-Charset、Accept-Encoding、Accept-Language、Authorization、From、Host、If-Modified-Since、If-Match、If-None-Match、If-Range、If-Range、If-Unmodified-Since、Max-Forwards、Proxy-Authorization、Range、Referer、User-Agent。对请求头域的扩展要求通讯双方都支持,如果存在不支持的请求头域,一般将会作为实体头域处理。
典型的请求消息:
GEThttp://class/download.microtool.de:80/somedata.exe
Host:download.microtool.de
Accept:*/*
Pragma:no-cache
Cache-Control:no-cache
Referer:http://class/download.microtool.de/
User-Agent:Mozilla/4.04[en](Win95;I;Nav)
Range:bytes=554554-
上例第一行表示HTTP客户端(可能是浏览器、下载程序)通过GET方法获得指定URL下的文件。棕色的部分表示请求头域的信息,绿色的部分表示通用头部分。
Host头域
Host头域指定请求资源的Intenet主机和端口号,必须表示请求url的原始服务器或网关的位置。HTTP/1.1请求必须包含主机头域,否则系统会以400状态码返回。
Referer头域
Referer头域允许客户端指定请求uri的源资源地址,这可以允许服务器生成回退链表,可用来登陆、优化cache等。他也允许废除的或错误的连接由于维护的目的被追踪。如果请求的uri没有自己的uri地址,Referer不能被发送。如果指定的是部分uri地址,则此地址应该是一个相对地址。
Range头域
Range头域可以请求实体的一个或者多个子范围。例如,
表示头500个字节:bytes=0-499
表示第二个500字节:bytes=500-999
表示最后500个字节:bytes=-500
表示500字节以后的范围:bytes=500-
第一个和最后一个字节:bytes=0-0,-1
同时指定几个范围:bytes=500-600,601-999
但是服务器可以忽略此请求头,如果无条件GET包含Range请求头,响应会以状态码206(PartialContent)返回而不是以200(OK)。
User-Agent头域
User-Agent头域的内容包含发出请求的用户信息。
响应消息
响应消息的第一行为下面的格式:
HTTP-VersionSPStatus-CodeSPReason-PhraseCRLF
HTTP-Version表示支持的HTTP版本,例如为HTTP/1.1。Status-Code是一个三个数字的结果代码。Reason-Phrase给Status-Code提供一个简单的文本描述。Status-Code主要用于机器自动识别,Reason-Phrase主要用于帮助用户理解。Status-Code的第一个数字定义响应的类别,后两个数字没有分类的作用。第一个数字可能取5个不同的值:
1xx:信息响应类,表示接收到请求并且继续处理
2xx:处理成功响应类,表示动作被成功接收、理解和接受
3xx:重定向响应类,为了完成指定的动作,必须接受进一步处理
4xx:客户端错误,客户请求包含语法错误或者是不能正确执行
5xx:服务端错误,服务器不能正确执行一个正确的请求
响应头域允许服务器传递不能放在状态行的附加信息,这些域主要描述服务器的信息和Request-URI进一步的信息。响应头域包含Age、Location、Proxy-Authenticate、Public、Retry-After、Server、Vary、Warning、WWW-Authenticate。对响应头域的扩展要求通讯双方都支持,如果存在不支持的响应头域,一般将会作为实体头域处理。
典型的响应消息:
HTTP/1.0200OK
Date:Mon,31Dec200104:25:57GMT
Server:Apache/1.3.14(Unix)
Content-type:text/html
Last-modified:Tue,17Apr200106:46:28GMT
Etag:"a030f020ac7c01:1e9f"
Content-length:39725426
Content-range:bytes554554-40279979/40279980
上例第一行表示HTTP服务端响应一个GET方法。棕色的部分表示响应头域的信息,绿色的部分表示通用头部分,红色的部分表示实体头域的信息。
Location响应头
Location响应头用于重定向接收者到一个新URI地址。
Server响应头
Server响应头包含处理请求的原始服务器的软件信息。此域能包含多个产品标识和注释,产品标识一般按照重要性排序。
实体
请求消息和响应消息都可以包含实体信息,实体信息一般由实体头域和实体组成。实体头域包含关于实体的原信息,实体头包括Allow、Content-Base、Content-Encoding、Content-Language、Content-Length、Content-Location、Content-MD5、Content-Range、Content-Type、Etag、Expires、Last-Modified、extension-header。extension-header允许客户端定义新的实体头,但是这些域可能无法未接受方识别。实体可以是一个经过编码的字节流,它的编码方式由Content-Encoding或Content-Type定义,它的长度由Content-Length或Content-Range定义。
Content-Type实体头
Content-Type实体头用于向接收方指示实体的介质类型,指定HEAD方法送到接收方的实体介质类型,或GET方法发送的请求介质类型Content-Range实体头
Content-Range实体头用于指定整个实体中的一部分的插入位置,他也指示了整个实体的长度。在服务器向客户返回一个部分响应,它必须描述响应覆盖的范围和整个实体长度。一般格式:
Content-Range:bytes-unitSPfirst-byte-pos-last-byte-pos/entity-legth
例如,传送头500个字节次字段的形式:Content-Range:bytes0-499/1234如果一个http消息包含此节(例如,对范围请求的响应或对一系列范围的重叠请求),Content-Range表示传送的范围,Content-Length表示实际传送的字节数。
Last-modified实体头
Last-modified实体头指定服务器上保存内容的最后修订时间。
一、HTTP协议是什么
我们在浏览器的地址栏里输入的网站地址叫做URL(UniformResourceLocator,统一资源定位符)。就像每家每户都有一个门牌地址一样,每个网页也都有一个Internet地址。当你在浏览器的地址框中输入一个URL或是单击一个超级链接时,URL就确定了要浏览的地址。浏览器通过超文本传输协议(HTTP),将Web服务器上站点的网页代码提取出来,并翻译成漂亮的网页。因此,在我们认识HTTP之前,有必要先弄清楚URL的组成,例如:http://www.microsoft.com/china/index.htm。它的含义如下:
1.http://:代表超文本传输协议,通知microsoft.com服务器显示Web页,通常不用输入;
2.www:代表一个Web(万维网)服务器;
3.Microsoft.com/:这是装有网页的服务器的域名,或站点服务器的名称;
4.China/:为该服务器上的子目录,就好像我们的文件夹;
5.Index.htm:index.htm是文件夹中的一个HTML文件(网页)。
我们知道,Internet的基本协议是TCP/IP协议,然而在TCP/IP模型最上层的是应用层(Applicationlayer),它包含所有高层的协议。高层协议有:文件传输协议FTP、电子邮件传输协议SMTP、域名系统服务DNS、网络新闻传输协议NNTP和HTTP协议等。
HTTP协议(HypertextTransferProtocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。这就是你为什么在浏览器中看到的网页地址都是以“http://”开头的原因。
自WWW诞生以来,一个多姿多彩的资讯和虚拟的世界便出现在我们眼前,可是我们怎么能够更加容易地找到我们需要的资讯呢?当决定使用超文本作为WWW文档的标准格式后,于是在1990年,科学家们立即制定了能够快速查找这些超文本文档的协议,即HTTP协议。经过几年的使用与发展,得到不断的完善和扩展,目前在WWW中使用的是HTTP/1.0的第六版。
二、HTTP是怎样工作的
既然我们明白了URL的构成,那么HTTP是怎么工作呢?我们接下来就要讨论这个问题。
由于HTTP协议是基于请求/响应范式的(相当于客户机/服务器)。一个客户机与服务器建立连接后,发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
许多HTTP通讯是由一个用户代理初始化的并且包括一个申请在源服务器上资源的请求。最简单的情况可能是在用户代理和服务器之间通过一个单独的连接来完成。在Internet上,HTTP通讯通常发生在TCP/IP连接之上。缺省端口是TCP80,但其它的端口也是可用的。但这并不预示着HTTP协议在Internet或其它网络的其它协议之上才能完成。HTTP只预示着一个可靠的传输。
这个过程就好像我们打电话订货一样,我们可以打电话给商家,告诉他我们需要什么规格的商品,然后商家再告诉我们什么商品有货,什么商品缺货。这些,我们是通过电话线用电话联系(HTTP是通过TCP/IP),当然我们也可以通过传真,只要商家那边也有传真。
以上简要介绍了HTTP协议的宏观运作方式,下面介绍一下HTTP协议的内部操作过程。
在WWW中,“客户”与“服务器”是一个相对的概念,只存在于一个特定的连接期间,即在某个连接中的客户在另一个连接中可能作为服务器。基于HTTP协议的客户/服务器模式的信息交换过程,它分四个过程:建立连接、发送请求信息、发送响应信息、关闭连接。这就好像上面的例子,我们电话订货的全过程。
其实简单说就是任何服务器除了包括HTML文件以外,还有一个HTTP驻留程序,用于响应用户请求。你的浏览器是HTTP客户,向服务器发送请求,当浏览器中输入了一个开始文件或点击了一个超级链接时,浏览器就向服务器发送了HTTP请求,此请求被送往由IP地址指定的URL。驻留程序接收到请求,在进行必要的操作后回送所要求的文件。在这一过程中,在网络上发送和接收的数据已经被分成一个或多个数据包(packet),每个数据包包括:要传送的数据;控制信息,即告诉网络怎样处理数据包。TCP/IP决定了每个数据包的格式。如果事先不告诉你,你可能不会知道信息被分成用于传输和再重新组合起来的许多小块。
也就是说商家除了拥有商品之外,它也有一个职员在接听你的电话,当你打电话的时候,你的声音转换成各种复杂的数据,通过电话线传输到对方的电话机,对方的电话机又把各种复杂的数据转换成声音,使得对方商家的职员能够明白你的请求。这个过程你不需要明白声音是怎么转换成复杂的数据的。
应用分析 - HTTP网页访问应用分析 一、HTTP协议简介 1.什么是HTTP协议 HTTP,全称Hyper Text Transfer Protocol,中文名为超文本传输协议。 HTTP是一种用于从Web服务器端传送超文本标记语言(HTML-Hyper Text Markup Language)文件到客户端浏览器的传送协议,它是Internet上最常见的协议之一。我们通常访问的网页,就是通过HTTP协议进行传送的。 2.HTTP协议的工作原理 HTTP用名字标识某一资源时(即在浏览器中输入网址),遵循统一资源名(URN-Uniform Resource Name)的规则,当前网络中最常用的URN是统一资源定位符(URL-Uniform Resource Locator),当客户端在浏览器中输入一个URL或单击一个URL超链接时,就确定了要访问的地址。 以http://www.colasoft.com.cn/resource/index.html为例介绍URL的组成: 1) http://:表示使用超文本传输协议,通知Web服务器显示Web页,客户端可不输入; 2) www:代表1个Web服务器; 3) colasoft.com.cn/:Web服务器的域名,或站点服务器的名称; 4) resource/:Web服务器上的子目录,类似机器中的文件夹; 5) index.html:Web服务器上resource子目录中的一个网页文件,即Web服务器传送给客户端浏览器的文件。 HTTP使用TCP协议的80端口进行可靠数据传输,一个HTTP会话由客户端开始发起,包括以下步骤: 1) 客户端在浏览器中标识希望获取信息的URL; 2) 发起HTTP连接请求,启动客户端(UA)和一个初始WWW服务器或代理服务器之间的一个HTTP会话; 3) WWW服务器或代理服务器根据客户端的URL请求将内容传送给客户端。 3.HTTP协议的工作方式 宏观工作方式: 1) 客户端(UA)直接连接到Web服务器的通讯路径如图1所示,客户端与Web服务器之间的通讯不需要任何的中介服务器,这是最简单的情况。 (图1 客户端与Web服务器直接连接) 2) 客户端(UA)通过中介服务器连接到Web服务器的通讯路径如图2所示,客户端与Web服务器之间的通讯通过中介服务器进行转发,中介服务器可能有1个,也可能有多个。 (图2 客户端通过中介服务器与Web服务器连接) 3) 客户端(UA)到中介服务器的通讯路径如图3所示,客户端将请求发送给中介服务器1,中介服务器1将其发送中介服务器2,中介服务器2再发给Web服务器,最后客户端收到的内容由中介服务器1发送给它,而不是Web服务器。 (图3 客户端与中介服务器通讯过程) 内部操作过程: 如图4所示,它分为四个步骤:建立连接、发出请求信息、发出响应信息、关闭连接。 (图4 HTTP协议内部操作过程) 4.HTTP协议的报文格式服务器对HTTP的处理方式 客户端发送的HTTP报文,我们称为请求链;中介服务器或Web服务器发送的HTTP报文,称为响应链。两种报文都遵循以下格式: l 一般开始行,即请求报文的请求行和应答报文的状态行; l 总头; l 报文头; l 一个空行; l 报文体。
HTTP协议三--断点续传
二、分析HTTP通讯1.分析HTTP访问的具体流程 我们使用科来网络分析系统5.0捕获并分析一个HTTP通讯过程,客户端主机名为“wangym”,客户端浏览器是IE6.0,请求的域名是“www.colasoft.com.cn”。 在客户端上打开科来网络分析系统5.0。为避免数据干扰,可以设定一个过滤器,只捕获本机的数据通讯。设定好后开始数据捕获,同时在本机的浏览器中输入www.colasoft.com.cn,待网页全部打开后,停止捕获。 注意:此文里提到的HTTP访问均指标准80端口的通信,对于非80端口的HTTP访问,用户可在“工程->高级分析模块->HTTP分析模块->常规设置->端口”处进行更改,系统默认为80,当HTTP服务有多个端口时,多个端口之间用分号分隔,如80;8080。 1) HTTP请求 图5所示的是科来网络分析系统5.0对上面访问www.colasoft.com.cn的操作的HTTP请求报文跟踪。 (图5 HTTP GET请求操作) 从图5中的数据包列表可知,上述操作中HTTP请求的原始信息如下: 1) 第1个数据包是DNS查询数据包,本机通过DNS查询获得www.colasoft.com.cn对应的IP地址。 2) 第2个数据包是DNS回应数据包,DNS服务器查询到域名www.colasoft.com.cn对应的IP是64.246.27.237,并将查询结果传送给客户端。 3) 3、4、5数据包是TCP连接的三次握手数据包,连接的双方是本机与域名www.colasoft.com.cn对应的IP地址64.246.27.237。 4) 第6个数据包是客户端发起的HTTP GET请求,向Web服务器处请求获得内容,第7帧的解码包含了GET请求的各参数信息。 上述HTTP访问的HTTP请求方法是GET,而GET仅仅是HTTP众多方法中的一种,HTTP通过不同的方法实现不同的功能,下表列出了HTTP常见的请求方法。
(表1 HTTP常见请求方法) 每个HTTP请求都包含两个部分: 1) HTTP请求行,大多情况下为GET或POST; 2) HTTP请求中的可选消息头,这些消息头会由于使用的HTTP客户端浏览器或客户端浏览器配置选项的不同而不同。 具体分析图5中第6个数据包的HTTP请求解码,可以得到如下信息: 1) HTTP请求:请求的方法是GET,“/”表示请求Web服务器的根目录,“HTTP/1.1”表示的是URI(Uniform Resource Identifier,统一资源标识符)及其版本; 2) Accept:指定客户端能够接收的内容类型,内容类型中的先后次序表示客户端接收的先后次序。这里可以看到客户端能够接收的类型有gif、bitmap、jpeg等等。 3) Accept-Language:指定优先选择的语言是中文; 4) Accept-Encoding:指定内容编码类型为gzip或deflate; 5) User-Agent:包含HTTP客户端运行的浏览器类型; 6) Host:包含的主机信息为www.colasoft.com.cn。 7) Connection:指定的连接类型为Keep-Alive。 注意:在传送一个网页时,Web服务器会同时打开多个TCP连接,如每一张图片都单独使用一个TCP连接进行传送。 超文本传输协议HTTP(二) 用于支持WWW浏览的网络协议为HTTP,这是一种最基本的客户机/服务器的访问协议。浏览器向服务器发送请求,而服务器回应相应的网页。HTTP协议从1990年开始出现,发展到当前的HTTP1.1标准,已经有了相当多的扩展,然而其最基本的实现是非常简单的,服务器需要进行的额外处理相当少,这也是为什么Web服务器软件如此众多的原因之一。 应用分析 - HTTP网页访问应用分析(3)
|
什么是长连接、短连接?
2009-07-30 11:38
什么是长连接,什么是短连接? |
HTTP1.1状态代码及其含义
2009-08-24 16:59
100 Continue 初始的请求已经接受,客户应当继续发送请求的其余部分。(HTTP 1.1新) 101 Switching Protocols 服务器将遵从客户的请求转换到另外一种协议(HTTP 1.1新) 200 OK 一切正常,对GET和POST请求的应答文档跟在后面。 201 Created 服务器已经创建了文档,Location头给出了它的URL。 202 Accepted 已经接受请求,但处理尚未完成。 203 Non-Authoritative Information 文档已经正常地返回,但一些应答头可能不正确,因为使用的是文档的拷贝(HTTP 1.1新)。 204 No Content 没有新文档,浏览器应该继续显示原来的文档。如果用户定期地刷新页面,而Servlet可以确定用户文档足够新,这个状态代码是很有用的。 205 Reset Content 没有新的内容,但浏览器应该重置它所显示的内容。用来强制浏览器清除表单输入内容(HTTP 1.1新)。 302 Found 类似于301,但新的URL应该被视为临时性的替代,而不是永久性的。注意,在HTTP1.0中对应的状态信息是“Moved Temporatily”。 注意这个状态代码有时候可以和301替换使用。例如,如果浏览器错误地请求http://host/~user(缺少了后面的斜杠),有的服务器返回301,有的则返回302。 严格地说,我们只能假定只有当原来的请求是GET时浏览器才会自动重定向。请参见307。 304 Not Modified 客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。 305 Use Proxy 客户请求的文档应该通过Location头所指明的代理服务器提取(HTTP 1.1新)。 307 Temporary Redirect 和302(Found)相同。许多浏览器会错误地响应302应答进行重定向,即使原来的请求是POST,即使它实际上只能在POST请求的应答是303时才能重定向。由于这个原因,HTTP 1.1新增了307,以便更加清除地区分几个状态代码:当出现303应答时,浏览器可以跟随重定向的GET和POST请求;如果是307应答,则浏览器只能跟随对GET请求的重定向。(HTTP 1.1新) 400 Bad Request 请求出现语法错误。 401 Unauthorized 客户试图未经授权访问受密码保护的页面。应答中会包含一个WWW-Authenticate头,浏览器据此显示用户名字/密码对话框,然后在填写合适的Authorization头后再次发出请求。 403 Forbidden 资源不可用。服务器理解客户的请求,但拒绝处理它。通常由于服务器上文件或目录的权限设置导致。 404 Not Found 无法找到指定位置的资源。这也是一个常用的应答。 405 Method Not Allowed 请求方法(GET、POST、HEAD、Delete、PUT、TRACE等)对指定的资源不适用。(HTTP 1.1新) 406 Not Acceptable 指定的资源已经找到,但它的MIME类型和客户在Accpet头中所指定的不兼容(HTTP 1.1新)。 407 Proxy Authentication Required 类似于401,表示客户必须先经过代理服务器的授权。(HTTP 1.1新) 408 Request Timeout 在服务器许可的等待时间内,客户一直没有发出任何请求。客户可以在以后重复同一请求。(HTTP 1.1新) 409 Conflict 通常和PUT请求有关。由于请求和资源的当前状态相冲突,因此请求不能成功。(HTTP 1.1新) 410 Gone 所请求的文档已经不再可用,而且服务器不知道应该重定向到哪一个地址。它和404的不同在于,返回407表示文档永久地离开了指定的位置,而404表示由于未知的原因文档不可用。(HTTP 1.1新) 411 Length Required 服务器不能处理请求,除非客户发送一个Content-Length头。(HTTP 1.1新) 412 Precondition Failed 请求头中指定的一些前提条件失败(HTTP 1.1新)。 413 Request Entity Too Large 目标文档的大小超过服务器当前愿意处理的大小。如果服务器认为自己能够稍后再处理该请求,则应该提供一个Retry-After头(HTTP 1.1新)。 414 Request URI Too Long URI太长(HTTP 1.1新)。 416 Requested Range Not Satisfiable 服务器不能满足客户在请求中指定的Range头。(HTTP 1.1新) 500 Internal Server Error 服务器遇到了意料不到的情况,不能完成客户的请求。 501 Not Implemented 服务器不支持实现请求所需要的功能。例如,客户发出了一个服务器不支持的PUT请求。 502 Bad Gateway 服务器作为网关或者代理时,为了完成请求访问下一个服务器,但该服务器返回了非法的应答。 503 Service Unavailable 服务器由于维护或者负载过重未能应答。例如,Servlet可能在数据库连接池已满的情况下返回503。服务器返回503时可以提供一个Retry-After头。 504 Gateway Timeout 由作为代理或网关的服务器使用,表示不能及时地从远程服务器获得应答。(HTTP 1.1新) 505 HTTP Version Not Supported 服务器不支持请求中所指明的HTTP版本。(HTTP 1.1新) HTTP状态列表 响应码由三位十进制数字组成,它们出现在由HTTP服务器发送的响应的第一行。 |
HTTP协议的运作方式
HTTP协议是基于请求/响应范式的。一个客户机与服务器建立连接后,发送一个请求给服务器,请求方式的格式为,统一资源标识符、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。服务器接到请求后,给予相应的响应信息,其格式为一个状态行包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
许多HTTP通讯是由一个用户代理初始化的并且包括一个申请在源服务器上资源的请求。最简单的情况可能是在用户代理(UA)和源服务器(O)之间通过一个单独的连接来完成(见图2-1)。
图2-1
当一个或多个中介出现在请求/响应链中时,情况就变得复杂一些。中介由三种:代理(Proxy)、网关(Gateway)和通道(Tunnel)。一个代理根据URI的绝对格式来接受请求,重写全部或部分消息,通过URI的标识把已格式化过的请求发送到服务器。网关是一个接收代理,作为一些其它服务器的上层,并且如果必须的话,可以把请求翻译给下层的服务器协议。一个通道作为不改变消息的两个连接之间的中继点。当通讯需要通过一个中介(例如:防火墙等)或者是中介不能识别消息的内容时,通道经常被使用。图2-2>
上面的图2-2表明了在用户代理(UA)和源服务器(O)之间有三个中介(A,B和C)。一个通过整个链的请求或响应消息必须经过四个连接段。这个区别是重要的,因为一些HTTP通讯选择可能应用于最近的连接、没有通道的邻居,应用于链的终点或应用于沿链的所有连接。尽管图2-2是线性的,每个参与者都可能从事多重的、并发的通讯。例如,B可能从许多客户机接收请求而不通过A,并且/或者不通过C把请求送到A,在同时它还可能处理A的请求。
任何针对不作为通道的汇聚可能为处理请求启用一个内部缓存。缓存的效果是请求/响应链被缩短,条件是沿链的参与者之一具有一个缓存的响应作用于那个请求。下图说明结果链,其条件是针对一个未被UA或A加缓存的请求,B有一个经过C来自O的一个前期响应的缓存拷贝。
图2-3
在Internet上,HTTP通讯通常发生在TCP/IP连接之上。缺省端口是TCP80,但其它的端口也是可用的。但这并不预示着HTTP协议在Internet或其它网络的其它协议之上才能完成。HTTP只预示着一个可靠的传输。
以上简要介绍了HTTP协议的宏观运作方式,下面介绍一下HTTP协议的内部操作过程。
首先,简单介绍基于HTTP协议的客户/服务器模式的信息交换过程,如图2-4所示,它分四个过程,建立连接、发送请求信息、发送响应信息、关闭连接。
图2-4
在WWW中,“客户”与“服务器”是一个相对的概念,只存在于一个特定的连接期间,即在某个连接中的客户在另一个连接中可能作为服务器。WWW服务器运行时,一直在TCP80端口(WWW的缺省端口)监听,等待连接的出现。
下面,讨论HTTP协议下客户/服务器模式中信息交换的实现。 1.建立连接 连接的建立是通过申请套接字(Socket)实现的。客户打开一个套接字并把它约束在一个端口上,如果成功,就相当于建立了一个虚拟文件。以后就可以在该虚拟文件上写数据并通过网络向外传送。
2.发送请求
打开一个连接后,客户机把请求消息送到服务器的停留端口上,完成提出请求动作。
HTTP/1.0 请求消息的格式为:
请求消息=请求行(通用信息|请求头|实体头)CRLF[实体内容]
请求 行=方法 请求URL HTTP版本号 CRLF
方 法=GET|HEAD|POST|扩展方法
U R L=协议名称+宿主名+目录与文件名
请求行中的方法描述指定资源中应该执行的动作,常用的方法有GET、HEAD和POST。不同的请求对象对应GET的结果是不同的,对应关系如下:
对象 GET的结果
文件 文件的内容
程序 该程序的执行结果
数据库查询 查询结果
HEAD——要求服务器查找某对象的元信息,而不是对象本身。
POST——从客户机向服务器传送数据,在要求服务器和CGI做进一步处理时会用到POST方法。POST主要用于发送HTML文本中FORM的内容,让CGI程序处理。
一个请求的例子为:
GEThttp://networking.zju.edu.cn/zju/index.htmHTTP/1.0
头信息又称为元信息,即信息的信息,利用元信息可以实现有条件的请求或应答。
请求头——告诉服务器怎样解释本次请求,主要包括用户可以接受的数据类型、压缩方法和语言等。
实体头——实体信息类型、长度、压缩方法、最后一次修改时间、数据有效期等。
实体——请求或应答对象本身。
3.发送响应
服务器在处理完客户的请求之后,要向客户机发送响应消息。
HTTP/1.0的响应消息格式如下:
响应消息=状态行(通用信息头|响应头|实体头) CRLF 〔实体内容〕
状态行=HTTP版本号 状态码 原因叙述
状态码表示响应类型
1×× 保留
2×× 表示请求成功地接收
3×× 为完成请求客户需进一步细化请求
4×× 客户错误
5×× 服务器错误
响应头的信息包括:服务程序名,通知客户请求的URL需要认证,请求的资源何时能使用。
4.关闭连接
客户和服务器双方都可以通过关闭套接字来结束TCP/IP对话
HTTP和WWW的配置注意事项
一、HTTP的安全因素 |
利用HTTP协议的特性进行拒绝服务攻击的一些构思
在介绍这个方法之前,让我们复习一下HTTP是怎样工作的:
由于HTTP协议是基于请求/响应范式的(相当于客户机/服务器)。一个客户机与服务器建立连接后,发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
留意这行文字:“服务器接到请求后,给予相应的响应信息,其格式为一个状态行”,这是HTTP协议的一个重要特性,我们可以做个实验:
用TELNET或任何一个能建立HTTP连接的程序连接到某服务器的80端口,手工输入:
GET/index.htmHTTP/1.0(必须确保这个工具能自动产生两个换行符,否则服务器会认为你没有输入完全!)
如果index.htm存在,你会看到类似以下的报文:
HTTP/1.1200OK
Server:Microsoft-IIS/5.0
Content-Location:http://www.******.com/index.htm
Date:Sat,20Jul200223:32:03GMT
Content-Type:text/html
Accept-Ranges:bytes
Last-Modified:Wed,03Jul200209:50:05GMT
ETag:"8e2ba27722c21:850"
Content-Length:3292
<html>
<head>
<title>青涩宝贝主题站--SGfans的世界!!!</title>
<metahttp-equiv="Content-Type"content="text/html;charset=gb2312">
<linkrel="stylesheet"href="all.css"type="text/css">
.......
这是正常的访问方法,但是如果我们胡乱输入请求呢?看:
HTTP/1.1400BadRequest
Server:Microsoft-IIS/5.0
Date:Sat,20Jul200223:37:59GMT
Content-Type:text/html
Content-Length:87
<html><head><title>Error</title></head><body>Theparameterisincorrect.</body></html>
呵呵,HTTP400-错误请求,其实就是HTTP语法错误,服务器老老实实给我们返回了。
可以得出结论:无论你输入了什么,服务器根据HTTP协议,总会返回信息
通常用得最多的DOS方法主要有SYN、Smurf、Land、TearDrop等,其中SYN的资料如下(抄来的资料~~呵呵)假设一个用户向服务器发送了SYN报文后突然死机或掉线,那么服务器在发出SYN+ACK应答报文后是无法收到客户端的ACK报文的(第三次握手无法完成),这种情况下服务器端一般会重试(再次发送SYN+ACK给客户端)并等待一段时间后丢弃这个未完成的连接,这段时间的长度我们称为SYNTimeout,一般来说这个时间是分钟的数量级(大约为30秒-2分钟);一个用户出现异常导致服务器的一个线程等待1分钟并不是什么很大的问题,但如果有一个恶意的攻击者大量模拟这种情况,服务器端将为了维护一个非常大的半连接列表而消耗非常多的资源----数以万计的半连接,即使是简单的保存并遍历也会消耗非常多的CPU时间和内存,何况还要不断对这个列表中的IP进行SYN+ACK的重试。实际上如果服务器的TCP/IP栈不够强大,最后的结果往往是堆栈溢出崩溃---即使服务器端的系统足够强大,服务器端也将忙于处理攻击者伪造的TCP连接请求而无暇理睬客户的正常请求(毕竟客户端的正常请求比率非常之小),此时从正常客户的角度看来,服务器失去响应,这种情况我们称作:服务器端受到了SYNFlood攻击(SYN洪水攻击)。
而Smurf、TearDrop等是利用ICMP报文来Flood和IP碎片攻击的。
但是以上的DOS方法的目的无非都是让服务器大量消耗资源和超时连接,那么除了超时连接,能不能用“正常连接”的方法来产生拒绝服务攻击呢?
再来看看19端口的定义:
字符产生器协议(CharacterGeneratorProtocol)
字符产生器服务器一个有用的调试工具。无论接收到的是什么,它都返回特定的数据。
基于TCP的字符产生器服务
此服务可以是一个基于TCP的服务,TCP端口19是用于此服务的。一旦连接建立,服务器会传送一个字符流。接收到的信息会被抛弃。字符流会在用户请求下中止。用户可能会非正常中止一个连接,因此此服务必须准备处理这种情况。传输的速度会由TCP流控制机制负责,用户不必关心数据太快,而用户来不及处理。
19端口在早期已经有人用来做Chargen攻击了,即Chargen_Denial_of_Service,但是!他们用的方法是在两台Chargen服务器之间产生UDP连接,让服务器处理过多信息而DOWN掉,那么,干掉一台WEB服务器的条件就必须有2个:1.有Chargen服务2.有HTTP服务
实际上,现在是无法找到这么多同时开放两个这两个服务的服务器的。
看看开头的HTTP协议特性,和Chargen比较一下,你发现了什么?哈哈~~~没错!一个是无论接收到什么报文都会回应,一个是一旦连接建立就会发送报文,看看示意图:
发送请求------------------------------------->
客户端----------------------------------------------------------服务器
<-------------------------------------------回应
如果把客户端改为Chargen,就是以下情况:
字符流--------------------------------------->
Chargen----------------------------------------------------------服务器
<-----------------------------------400BadRequest
也就是说,这两者会产生利害冲突,可以这样比喻:两个人吵架,你骂一句,他还一句,这就是循环过程,除非有一方停止或第三者干涉,否则这将是个Do...Loop循环!
搬到HTTP和Chargen来说,就是因为这两者的特性正好天生一对,那好,就从这里下手:
攻击者伪造源IP给N台Chargen发送连接请求(Connect),如有必要还可以发送(Send)个“Fuckyou”报文过去,Chargen接收到连接后就会返回每秒72字节的字符流(实际上根据网络实际情况,这个速度更快)给服务器,HTTP协议处理这个报文时当然会识别为400BadRequest而返回一条错误说明给它,接下来的情况嘛………………自己发挥想像力,别问我。
我用自己的机器(640kbpsADSL)+VBWinsock程序做测试,只用了3秒钟,程序就因为内存溢出而崩溃了主要是TextBox的问题,它接受文本的最大范围为64KB),就是说,3秒钟内Chargen就发送了大于64KB的字符流!如果用大于10台的Chargen一起发起攻击,其速度足以大量消耗服务器资源和带
5.2.2 实例——基于vC++的HTTP蓉户端程序
应用层位于TCP/IP协议栈的最上层,它是网络应用程序及其应用层协议保存的地方。应用层向使用网络的用户提供特定的、常用的应用程序,如使用最广泛的远程登录协议Telnet、文件传输协议FTP、超文本传输协议HTTP、域名系统DNS、简单网络管理协议SNMP、P2p文件共享系统和简单邮件传输协议SMTP等.网络应用程序3种主要体系结构:客户机/服务器体系结构,P2P体系结构、客户机/服务器和P2P混合的体系结构.
有些应用层协议是基于TCP协议的,如FTP和HTTP,有些应用层协议是基于UDP协议的,如SMTP等。应用层协议定义了运行在不同端系统上的应用程序进程是如何相互传递报文的,特别是应用层协议定义了:
(1)交换的报文类型,如请求报文和相应报文。
(2)各种报文类型的语法,如报文的各个字段及其详细描述.
(3)字段的语义,即包含在字段中的信息的含义
(4)进程何时、如何发送报文及对报文进行响应.
HTTP协议即超文本传输协议(HyperText Transfer Protocol),它是一个面向无连接的简单快速C/S结构的协议,HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。
HTTP协议是基于请求/响应范式的。一个客户机与服务器建立连接后,发送一个请求给服务器,请求方式的格式为统一资源标识符、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。服务器接到请求后,给予相应的响应消息,其格式为一个状态行包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息,实体信息和可能的内容。
HTTP协议的内部操作过程分为4个过程,建立连接、发送请求信息、发送响应消息、关闭连接,在WWW中,"客户"与"服务器"是一个相对的概念,只存在于一个特定的连接期间,即在某个连接中的客户在另一个连接中可能作为服务器。WWW服务器运行时,一般在TCP80端口(WWW的默认端口)监听,等待连接的出现,下面,讨论HTTP协议下客户/ 服务器模式中信息交换的实现.
(1)建立连接:连接的建立是通过申请套接字(Socket)实现的。客户打开一个套接字并把它绑定在一个端口上,这样就可以建立客户机与服务器的TCP连接
(2)发送请求:客户机与服务器建立连接后,客户机把请求信息送服务器的监听端口上,消息中含有资源在服务器上的位置,完成提出请求动作
(3)发送响应:服务器在处理完客户的请求之后,要向客户机发送响应消息,消息中含有返回状态码,表示请求是否完成;包含相应消息标题和请求的对象实体,如一个HTTP文件或者一个图片
(4)关闭连接:一旦响应消息发出,服务器将关闭TCP/IP 连接,然后结束HTTP会话,客户和服务器双方都可以通过关闭套接字来结束TCP/IP对话
客户端HTTP请求的方法:GET,HEAD,POST,PUT,DELETE,OPTIONS,TRAC
该实例直接调用类库中的CHtmlView类,CHtmlView类在文档/视图结构的上下文中提供WebBrowser控件的功能。WebBrowser控件是客户可浏览网址以及本地文件系统和网络文件夹的窗口。WebBrowser控件支持超级链接、统一资源定位符(URL)导航器比维护一张历史表.,所以在创建程序的时候MFCAppWizard,并将CHtmlView 指定为视图类.
下面是用到的函数
//刷新当前的页面
void CMywebView::OnRefresh()
{
// TODO: Add your command handler code here
Refresh();
}
//前进到下一个网页
void CMywebView::OnForward()
{
// TODO: Add your command handler code here
GoForward();
}
//停止网页的下载
void CMywebView::OnStop()
{
// TODO: Add your command handler code here
Stop();
}
//进行搜索
void CMywebView::OnSearch()
{
// TODO: Add your command handler code here
OnSearch();
}
//后退到前一个网页
void CMywebView::OnBack()
{
// TODO: Add your command handler code here
GoBack();
}
//回到主页
void CMywebView::OnHamepage()
{
// TODO: Add your command handler code here
GoHome();
}
void CMainFrame::OnGO()//该函数实现按回车键时,自动跳动指定的网页
{
CString addr;
//获得用户在地址栏输入的地址
m_wndDlgBar.GetDlgItem(IDC_ADDRESS)->GetWindowText(addr);
//浏览指定的网页
((CMywebView*)GetActiveView())->Navigate(addr);
}
5.3 Email协议及电子邮件
http://binyanye.blog.163.com/blog/static/1753360812010112514120844/
Email协议及电子邮件
SMTP是简单邮件传输协议,是Internet的正式标准,最初在1982年由RFC821规定,目前它的最高版本是RFC2821.目标是向用户提供高效、可靠的邮件传输。SMTP采用C/S模式,专用电子邮件的发送,规定了发信人把电子邮件发送到收信人的电子邮箱的全过程,SMTP客户机与SMTP服务器两者在通信过程中如何交换信息。
SMTP主要工作在两种情况下:一是电子邮件从客户机传输到服务器;二是从某一个服务器传输到令一个服务器。
POP3协议是邮局协议版本3的缩写,从邮件传输过程可知,发送给某用户的邮件通过SMTP的传输,最终被保存于用户所在的电子邮件服务器上的邮箱里。一般情况下用户无法在邮件服务器上直接阅读邮件,用户需要把存储于邮件服务器上的邮件取到本地主机后再阅读。POP3就是一个从邮件服务器的邮箱中取邮件到本地主机的协议。
工作时,服务器在提供POP3服务的TCP端口110上侦听客户的请求,当客户主机需要从服务器上取邮件时,它向服务器发出建立一条TCP连接的请求。在连接成功后,客户与服务器之间使用POP3协议会话的过程分为3个阶段(1)认证阶段,每一个用户只有提供了正确的用户名和口令后,才有权访问自己的邮箱,在这个阶段里,可以使用USER、PASS和QUIT这3个POP3命令(2)邮件操作阶段:检索、下载或者删除邮件等操作(3)更新阶段:当客户发送了QUIT命令后,系统就进入更新阶段,POP3服务器释放在操作阶段中取得的资源,并将逻辑删除的邮件进行物理删除,然后发送消息,关闭客户与服务器之间的TCP连接,邮件处理的会话过程结束
实例:Email接收程序--POP3邮件接收端:
关键代码:
()
bool WSocket::Create(int af, int type, int protocol)//创建套接字
{
m_sock=socket(af,type,protocol);
if(m_sock==INVALID_SOCKET)
{
return false;
}
return true;
}
bool WSocket::Connect(const char *ip, unsigned short port)//与服务器连接
{
struct sockaddr_in svraddr;
svraddr.sin_family=AF_INET;
svraddr.sin_addr.s_addr=inet_addr(ip);
svraddr.sin_port=htons(port);
int ret=connect(m_sock,(struct sockaddr*)&svraddr,sizeof(svraddr));
if(ret==SOCKET_ERROR)
{
return false;
}
return true;
}
int WSocket::Send(const char *buf, int len, int flags)//套接字发送数据
{
int bytes;
int count=0;
while(count<len)
{
bytes=send(m_sock,buf+count,len-count,flags);
if(bytes==-1||bytes==0)
return -1;
count+=bytes;
}
return count;
}
int WSocket::Recv(char *buf, int len, int flags)//套接字接收数据
{
return (recv(m_sock,buf,len,flags));
}
int WSocket::Close()//关闭套接字
{
#ifdef WIN32
return (closesocket(m_sock));
#else
return (close(m_sock));
#endif
}
int WSocket::Init()//套接字初始化
{
#ifdef WIN32
WSADATA wsaData;
WORD version=MAKEWORD(2,0);
int ret=WSAStartup(version,&wsaData);//加载套接字
if(ret)
{
cerr<<"Initilize winsock error!"<<endl;
return -1;
}
#endif
return 0;
}
int WSocket::Clean()//清除套接字
{
#ifdef WIN32
return (WSACleanup());
#endif
return 0;
}
bool WSocket::DnsParse(const char* domain,char* ip)//服务器域名解析
{
struct hostent* p;
if((p=gethostbyname(domain))==NULL)
return false;
//如果是域名则转换成IP地址
sprintf(ip,
"%u.%u.%u.%u",
(unsigned char)p->h_addr_list[0][0],
(unsigned char)p->h_addr_list[0][1],
(unsigned char)p->h_addr_list[0][2],
(unsigned char)p->h_addr_list[0][3]);
return true;
}
()
//POP3接收服务器消息函数
int CPop3::Pop3Recv(char* buf, int len, int flags)
{
int rs;
int offset = 0;
do
{
if ( offset > len - 2 )
return offset;
rs = m_sock.Recv(buf + offset, len - offset, flags);
if ( rs < 0 ) /* error occur */
return -1;
offset += rs;
buf[offset] = '\0';
} while ( strstr(buf, "\r\n.\r\n") == (char*)NULL );
return offset;
}
//初始化POP3,
bool CPop3::Init(const char* username, const char* userpwd, const char* svraddr, unsigned short port)
{
//给用户名、密码和服务器地址赋值
strcpy(m_username, username);
strcpy(m_password, userpwd);
strcpy(m_svraddr, svraddr);
m_port = port;
return true;
}
//与邮件服务器建立连接
bool CPop3::Connect()
{
// 创建套接字
m_sock.Create(AF_INET, SOCK_STREAM, 0);
// 解析域名
char ipaddr[16];
if ( WSocket::DnsParse(m_svraddr, ipaddr) != true )
{
return false;
}
// 发送连接
if ( m_sock.Connect(ipaddr, m_port) != true )
{
return false;
}
// 接收服务器消息
char buf[128];
int rs = m_sock.Recv(buf, sizeof(buf), 0);
if ( rs <= 0 || strncmp(buf, "+OK", 3) != 0 )
{
return false;
}
#ifdef _DEBUG
buf[rs] = '\0';
printf("Recv POP3 Resp: %s", buf);
#endif
return true;
}
//向邮件服务器发送用户名和密码登录邮件服务器
bool CPop3::Login()
{
//发送USER命令,向服务器发送用户名
char sendbuf[128];
char recvbuf[128];
sprintf(sendbuf, "USER %s\r\n", m_username);
m_sock.Send(sendbuf, strlen(sendbuf), 0);
int rs = m_sock.Recv(recvbuf, sizeof(recvbuf), 0);
if ( rs <= 0 || strncmp(recvbuf, "+OK", 3) != 0 )
{
return false;
}
#ifdef _DEBUG
recvbuf[rs] = '\0';
printf("Recv USER Resp: %s", recvbuf);
#endif
//发送PASS命令,向服务器发送密码
sprintf(sendbuf, "PASS %s\r\n", m_password);
m_sock.Send(sendbuf, strlen(sendbuf), 0);
rs = m_sock.Recv(recvbuf, sizeof(recvbuf), 0);
if ( rs <= 0 || strncmp(recvbuf, "+OK", 3) != 0 )
{
return false;
}
#ifdef _DEBUG
recvbuf[rs] = '\0';
printf("Recv PASS Resp: %s", recvbuf);
#endif
return true;
}
//列出邮件主要信息
bool CPop3::List(int& sum)
{
//发送LIST命令,获得邮件信息
char sendbuf[128];
char recvbuf[256];
sprintf(sendbuf, "LIST \r\n");
m_sock.Send(sendbuf, strlen(sendbuf), 0);
int rs = Pop3Recv(recvbuf, sizeof(recvbuf), 0);
if ( rs <= 0 || strncmp(recvbuf, "+OK", 3) != 0 )
{
return false;
}
recvbuf[rs] = '\0';
#ifdef _DEBUG
printf("Recv LIST Resp: %s", recvbuf);
#endif
sum = GetMailSum(recvbuf);
return true;
}
//获取邮件并保存邮件
bool CPop3::Retrieve(int num)
{
int rs;
FILE* fp;
int flag = 0;
unsigned int len;
char filename[32];
char sendbuf[128];
char recvbuf[10240];
//发送RETR命令,获取邮件内容
sprintf(sendbuf, "RETR %d\r\n", num);
m_sock.Send(sendbuf, strlen(sendbuf), 0);
do {
rs = Pop3Recv(recvbuf, sizeof(recvbuf), 0);
if ( rs < 0 ) {
return false;
}
recvbuf[rs] = '\0';
// 获得邮件主题,并生成保存邮件的文件名
if ( flag == 0 )
{
GetSubject((char *)(LPCTSTR)Subject,recvbuf);
GetSubject(filename,recvbuf);
strcat(filename, ".eml");
flag = 1;
if ( (fp = fopen(filename, "wb")) == NULL )
return false;
}
#ifdef _DEBUG
printf("Recv RETR Resp: %s", recvbuf);
#endif
//获得邮件大小
len = strlen(recvbuf);
//保存邮件
if ( fwrite(recvbuf, 1, len, fp) != len ) {
fclose(fp);
return false;
}
fflush(fp);
} while ( strstr(recvbuf, "\r\n.\r\n") == (char*)NULL );
fclose(fp);
return true;
}
//与邮件服务器断开
bool CPop3::Quit()
{
char sendbuf[128];
char recvbuf[128];
//发送QUIT命令,断开与邮件服务器的连接
sprintf(sendbuf, "QUIT\r\n");
m_sock.Send(sendbuf, strlen(sendbuf), 0);
int rs = m_sock.Recv(recvbuf, sizeof(recvbuf), 0);
if ( rs <= 0 || strncmp(recvbuf, "+OK", 3) != 0 )
{
return false;
}
#ifdef _DEBUG
recvbuf[rs] = '\0';
printf("Recv QUIT Resp: %s", recvbuf);
#endif
//关闭套接字
m_sock.Close();
return true;
}
//获得邮件主题
bool CPop3::GetSubject(char* subject, const char* buf)
{
char* p = strstr(buf, "Subject: ");
if ( p == NULL )
return false;
p = p + 9;
for (int i = 0; i < 32; i++) {
if ( p[i] == '\r' || p[i] == '\n' ) {
subject[i] = '\0';
break;
}
subject[i] = p[i];
}
return true;
}
//获得邮箱邮件数量
int CPop3::GetMailSum(const char* buf)
{
int sum = 0;
char* p = strstr(buf, "\r\n");
if ( p == NULL )
return sum;
p = strstr(p + 2, "\r\n");
if ( p == NULL )
return sum;
while ( (p = strstr(p + 2, "\r\n")) != NULL )
{
sum++;
}
return sum;
}
5.3.1 SMTP协议
1 SMTP(Simple Mail Transfer Protocal)称为简单邮件传输协议,目标是向用户提供高效、可靠的邮件传输。 |
SMTP的一个重要特点是它能够在传送中接力传送邮件,即邮件可以通过不同网络上的主机接力式传送。 |
工作在两种情况下: |
一是电子邮件从客户机传输到服务器; 二是从某一个服务器传输到另一个服务器。 SMTP是个请求/响应协议,它监听25号端口,用于接收用户的邮件请求,并与远端邮件服务器建立SMTP连接。 |
SMTP工作机制 |
SMTP通常有两种工作模式:发送SMTP和接收SMTP。 |
具体工作方式为: 发送SMTP在接到用户的邮件请求后,判断此邮件是否为本地邮件, 若是直接投送到用户的邮箱,否则向DNS查询远端邮件服务器的MX纪录,并建立与远端接收SMTP之间的一个双向传送通道,此后SMTP命令由发送SMTP发出,由接收SMTP接收,而应答则反方面传送。 一旦传送通道建立,SMTP发送者发送MAIL命令指明邮件发送者。 如果SMTP接收者可以接收邮件则返回OK应答。 SMTP发送者再发出RCPT命令确认邮件是否接收到。 如果SMTP接收者接收,则返回OK应答; 如果不能接收到,则发出拒绝接收应答(但不中止整个邮件操作),双方将如此重复多次。 当接收者收到全部邮件后会接收到特别的序列,如果接收者成功处理了邮件,则返回OK应答。 |
2.POP协议简介 |
POP的全称是 Post Office Protocol ,即邮局协议,用于电子邮件的接收,它使用TCP的110端口,现在常用的是第三版,所以简称为 POP3。 |
POP3采用Client/Server工作模式。 |
当客户机需要服务时,客户端的软件(Outlook Express或FoxMail)将与POP3服务器建立TCP连接,此后要经过POP3协议的三种工作状态, 1、首先是认证过程,确认客户机提供的用户名和密码, 在认证通过后便转入处理状态,在此状态下用户可收取自己的邮件或做邮件 2、的删除,在完成响应的操作后客户机便发出quit命令, 3、此后便进入更新状态,将做删除标记的邮件从服务器端删除掉。到此为止整个POP过程完成。 |
3.IMAP协议简介 IMAP是Internet Message Access Protocol的缩写,顾名思义,主要提供的是通过Internet获取信息的一种协议。 |
IMAP像POP那样提供了方便的邮件下载服务,让用户能进行离线阅读,但IMAP能完成的却远远不只这些。IMAP提供的摘要浏览功能可以让你在阅读完所有的邮件到达时间、主题、发件人、大小等信息后才作出是否下载的决定。 |
邮件协议SMTP POP3 IMAP介绍及常用邮件服务器地址 | |||
|
SMTP 命令简介
什么是 SMTP
SMTP (Simple Mail Transfer Protocol) : 电子邮件从客户机传输到服务器或从某一个服务器传输到另一个服务器使用的传输协议。 SMTP 是请求/响应协议,命令和响应都是基于 ASCII 文本,并以 CR 和 LF 符结束。响应包括一个表示返回状态的三位数字代码。SMTP 在 TCP 协议 25 端口监听连接请求。
什么是 ESMTP
ESMTP (Extended SMTP),顾名思义,扩展 SMTP 就是对标准 SMTP 协议进行的扩展。它与 SMTP 服务的区别仅仅是,使用 SMTP 发信不需要验证用户帐户,而用 ESMTP 发信时, 服务器会要求用户提供用户名和密码以便验证身份。验证之后的邮件发送过程与 SMTP 方式没有两样。
SMTP 命令
SMTP 命令包括:
HELO 向服务器标识用户身份。发送者能欺骗,说谎,但一般情况下服务器都能检测到。
EHLO 向服务器标识用户身份。发送者能欺骗,说谎,但一般情况下服务器都能检测到。
MAIL FROM 命令中指定的地址是发件人地址
RCPT TO 标识单个的邮件接收人;可有多个 RCPT TO;常在 MAIL 命令后面。
DATA 在单个或多个 RCPT 命令后,表示所有的邮件接收人已标识,并初始化数据传输,以 CRLF.CRLF 结束
VRFY 用于验证指定的用户/邮箱是否存在;由于安全方面的原因,服务器常禁止此命令
EXPN 验证给定的邮箱列表是否存在,扩充邮箱列表,也常被禁用
HELP 查询服务器支持什么命令
NOOP 无操作,服务器应响应 OK
RSET 重置会话,当前传输被取消
QUIT 结束会话
连接 Winmail Server 使用 SMTP 命令发送邮件
例如:安装 Winmail 的邮件服务器IP是192.168.0.1 (蓝色字体内容由客户端输入,红色字体内容是服务返回的)
telnet 192.168.0.1 25 --------------------------------------- 使用 telnet 命令连接服务器 25 端口
Trying 192.168.0.1... --------------------------------------- 正在连接服务器 25 端口
Connected to 192.168.0.1. ----------------------------------- 连接服务器 25 端口成功
220 Winmail Mail Server ESMTP ready ------------------------- 显示服务器的标识名称 (Winmail 管理工具->高级设置->系统参数->基本参数中可更改)
helo cnu.com ------------------------------------------------ 向服务器标识用户身份,发信不要认证,跳过下面几步直接发送 mail from 命令
250 Winmail Mail Server
ehlo cnu.com ------------------------------------------------ ESMTP 命令,发信需要认证。
250-Winmail Mail Server
250-PIPELINING
250-AUTH=LOGIN PLAIN
250-AUTH LOGIN PLAIN
250-SIZE 20480000
250 8BITMIME
auth login ------------------------------------------------- 进行用户身份认证
334 VXNlcm5hbWU6
Y29zdGFAYW1heGl0Lm5ldA== ----------------------------------- BASE64 加密后的用户名
334 UGFzc3dvcmQ6
MTk4MjIxNA== ----------------------------------------------- BASE64 加密后的密码
235 auth successfully -------------------------------------- 身份认证成功
(535 auth failure ------------------------------------------ 身份认证失败)
发到本系统中域名下的账户可跳过身份认证。
mail from: <test1@domain.com> ------------------------------ mail from 地址 test1@domain.com
250 ok ----------------------------------------------------- 命令执行成功
rcpt to: <test2@domain.com> -------------------------------- 递送给地址 test2@domain.com
250 ok ----------------------------------------------------- 命令执行成功
data ------------------------------------------------------- 数据传输初始化
354 go ahead ----------------------------------------------- 开始传输数据
From: test1@domain.com
To: test2@domain.com
Date: Mon, 25 Oct 2004 14:24:27 +0800
Subject: test mail
Hi, test2
This is a test mail, you don't reply it.
------------------------------------------------------------ 数据内容,包括BASE64加密后的邮件内容, 以 CRLF.CRLF 结束数据传输
250 ok message accepted for delivery ----------------------- 命令执行成功
quit ------------------------------------------------------- 结束会话
221 Winmail Mail Server
Connection closed by foreign host .------------------------- 断开连接
电子邮件是Internet上最广泛的应用之一,尽管网络上有多种邮件收发服务,但最常用的还是SMTP,SMTP就是简单邮件传输协议(Simple Mail Transfer Protocol)。传统的SMTP使用简单的协议传输7位ASCII文本字符,它还有一种扩展形式,称为ESMTP,允许扩展协商,它包括8位的传输。这样,它不仅能够传输二进制的数据,还可以传输非ASCII字符集。一会儿,我们将用SMTP命令模拟发送邮件,但现在让我们先去了解一下SMTP协议的参数吧!
参数 |
作用 |
HELO |
使用标准的SMTP,向服务器标识用户身份。发送者能进行欺骗,但一般情况下服务器都能检测到 |
EHLO |
使用ESMTP,向服务器标识用户身份。发送者能进行欺骗,但一般情况下服务器都能检测到。 |
STARTTLS |
启用TLS |
MAIL FROM |
命令中指定的地址是发件人地址 |
RCPT TO |
标识单个的邮件接收人;可有多个 RCPT TO;常在 MAIL 命令后面 |
DATA |
在单个或多个 RCPT 命令后,表示所有的邮件接收人已标识,并初始化数据传输,以CRLF.CRLF 结束 |
VRFY |
用于验证指定的用户/邮箱是否存在;由于安全方面的原因,服务器常禁止此命令 |
EXPN |
验证给定的邮箱列表是否存在,扩充邮箱列表,也常被禁用 |
HELP |
查询服务器支持什么命令 |
NOOP |
无操作,服务器响应 250 OK |
RSET |
重置会话,当前传输被取消,服务器响应 250 OK |
QUIT |
结束会话 |
以上参数为常用参数,明白它们的作用,现在我们来做一个实例吧!让我们利用SMTP命令,先向邮件服务器发送一封电子邮件。Internet上有些邮件服务器都支持这种方法去模拟身份发邮件呀,大家可以试一试。
1.首先我们TELNET上邮件服务器
2.然后输入以下命令
3. 验证邮件是否收到
5.3.2 POP3模型及会话过程
大家一听这个POP,读起来有点像是中文中的泡泡,其实这是一个英文术语的缩写。POP的全称是 Post Office Protocol,即邮局协议,用于电子邮件的接收,它使用TCP的110端口。现在常用的是第三版 ,所以简称为 POP3。POP3仍采用Client/Server工作模式,Client被称为客户端,一般我们日常使用电脑都是作为客户端,而Server(服务器)则是网管人员进行管理的。举个形象的例子,Server(服务器)是许多小信箱的集合,就像我们所居住楼房的信箱结构,而客户端就好比是一个人拿着钥匙去信箱开锁取信一样的道理。
POP在网络模型中的层次
大家都知道网络是分层的,而这个分层就好比是一个企业里的组织结构一样。在日常使用电脑过程中,人操作着电脑,人就好比是指挥电脑对因特网操作的首席执行官。当我们打开Foxmail这个邮件软件收取邮件时,Foxmail这个软件就会调用TCP/IP参考模型中的应用层协议—POP协议。
应用层协议建立在网络层协议之上,是专门为用户提供应用服务的,一般是可见的。如利用FTP(文件传输协议)传输一个文件请求一个和目标计算机的连接,在传输文件的过程中,用户和远程计算机交换的一部分是能看到的。而这时POP协议则会指挥下层的协议为它传送数据服务器,最后Foxmail通过一系列协议对话后成功将电子邮件保存到了Foxmail的收件箱里。TCP/IP参考模型是Internet的基础。和OSI的7层协议比较,TCP/IP参考模型中没有会话层和表示层。通常说的TCP/IP是一组协议的总称,TCP/IP实际上是一个协议族(或协议包),包括100多个相互关联的协议,其中 IP(Internet Protocol,网际协议)是网络层最主要的协议;TCP(Transmission Control Protocol,传输控制协议)和UDP(User Datagram Protocol,用户数据报协议)是传输层中最主要的协议。一般认为IP、TCP、UDP是最根本的三种协议,是其它协议的基础。
相信读者了解TCP/IP框架之后,一定会对各层产生一定的兴趣,不过我们对于这个模型的理解也是一步步来的。在这里,我们首先只要知道相应的软件会调用应用层的相应协议,比如Foxmail会调用POP协议,而IE浏览器则会调用DNS协议先将网址解析成IP地址。在实际收取邮件的过程中,POP这个应用层的协议会指挥TCP协议,利用IP协议将一封大邮件拆分成若干个数据包在Internet上传送。
为了便于读者理解这个过程,笔者举个例子来说明一下,比如你要和一个人远距离通话,因为距离实在太远了,你只好将你所表达的一大段分成一个个字大声喊,而对方把每个听到的字写在纸上,当写下来后就大喊一声告诉你它收到了,这样就克服了距离远听不清的弱点,这种一问一答的反馈机制就好比是TCP协议, POP服务器一般使用的是TCP的110号端口。
POP工作原理简介
下面就让我们一起来看看电子邮件软件收取电子邮件的过程,一般我们在电子邮件软件的账号属性上设置一个POP服务器的URL(比如 pop.163.com),以及邮箱的账号和密码。这个在收信过程中都是用得到的。当我们按下电子邮件软件中的收取键后,电子邮件软件首先会调用DNS协议对POP服务器进行解析IP地址,当IP地址被解析出来后,邮件程序便开始使用TCP协议连接邮件服务器的110端口,因为POP服务器是比较忙的,所以在这个过程中我们相对要等比较长的时间。当邮件程序成功地连上POP服务器后,其先会使用USER命令将邮箱的账号传给POP服务器,然后再使用 PASS命令将邮箱的账号传给服务器,当完成这一认证过程后,邮件程序使用STAT命令请求服务器返回邮箱的统计资料,比如邮件总数和邮件大小等,然后 LIST便会列出服务器里邮件数量。然后邮件程序就会使用RETR命令接收邮件,接收一封后便使用DELE命令将邮件服务器中的邮件置为删除状态。当使用 QUIT时,邮件服务器便会将置为删除标志的邮件给删了。通俗地讲,邮件程序从服务器接收邮件,其实就是一个对话过程,POP协议就是用于电子邮件的一门语言。
POP3协议命令原始码及工作原理
5.3.3 实例——Email接收程序
5.4 FTP文件传输协议
FTP文件传输协议
FTP(File Transfer Protocol)即文件传输协议,主要是用来在网络上进行文件传输的。要在两台主机直接直接传输文件,除了通过共享方式传输外,还有一类使用非常广泛的方式,即采用FTP方式。
FTP的工作模式同其他的C/S模式的网络通信协议有很大的区别。通常在进行HTTP通信,只需要一个端口进行通信,即客户端只需要连接一个端口进行数据传输。但是FTP通信除了一个默认的端口21以外,还需要其他端口,通常是两个端口同时进行数据传输的。一是默认的端口,而另一个是按照一定原则由服务器或者客户端产生的非标准端口。其中默认端口主要进行控制连接,顾名思义,控制连接主要是进行命令协议的及服务器端的响应码的传输,另一个非标准端口主要是进行数据的传递,比如上传文件、下载文件、打印目录信息等。非标准端口的产生要根据用户选择的连接模式而定,如果客户选择的是PORT模式,则需要客户端提供服务器一个IP地址和一个非标准端口;如果用户采用被动模式,则服务器端要提供给客户端一个IP地址和一个非标准端口。在进行文件传输的时候,通常每传送完一个文件,又会重新建立连接模式并重新产生一个临时端口。
在用户协议解释器和服务器协议解释器之间的控制连接上传输的是FTP命令和应答信息。用户协议解释器负责发送命令和解释收到的应答,由服务器协议解释器执行命令并把执行情况以应答的形式发送给客户。
所有FTP命令和应答都在控制连接上以NVT ASCII码的形式传输,并且每一个命令都以<CR>和<LF>结尾,即是一个命令或应答占一行。
(1)FTP命令
访问控制命令:用户名:USER,口令:PASS,账号:ACCT,改变工作目录:CWD,回到上一层目录:CDUP,结构加载:SMNT,重新初始化:REIN,退出登录:QUIT
传输参数命令:数据端口:PORT,被动:PASV,表示类型:TYPE,文件结构:STRU,传输模式:MODE
FTP服务命令:RETR:用于从服务器获取指定路径内的文件复本,服务器上的文件内容和状态不受影响.
STOP:向服务器传送文件,如果文件存在,则覆盖源文件,否则创建文件
APPE:功能和STOP相似,但是如果文件在指定路径内已存在,则把数据附加到原文件尾部,如果不存在则新建文件。
ALLP:用于在主机上位新传送的文件分配足够的空间。参数是十进际的逻辑字节数。
REFR:该命令用于重命名指定的文件,它后面必须跟“rename to"来指定新的文件名。
RNTO:该命令用于指定新的文件名。
ABOR:关闭控制连接,但不关闭数据连接.
DEL:该命令用于删除指定路径下的文件,用户进程负责对删除的提示。
RMD:该命令用于删除指定目录。
MKD:该命令用于在指定的路径下创建新目录。
PWD:该命令用于返回当前工作目录。
LIST::该命令式服务器传送列表到客户。
SITE:用于获得服务器系统信息,信息因系统不同而不同。
NLIST:该命令式服务器传送目录表名到用户。
HELP:该命令与平常系统中得到的帮助相似。
NOOP:该命令不产生任何实际动作,它仅使服务器返回OK
(2)FTP应答
FTP命令的应答是服务器对FTP命令执行情况的响应,它主要有两方面的功能:一是服务器对数据传输的请求和过程进行同步,这是TCP协议所要求的,TCP要求对接收到的数据都要进行确认;二是让用户了解服务器的状态,用户可以根据收到的状态信息对服务器是否正常执行了有关操作进行判断。
第6章 传输层协议及编程实例
第7章 网络层协议和数据链路层
第8章 Internet通信原理及编程实例
第9章 基于Windows API的虚拟终端实现
第10章 多线程网络文件传输的设计与实现
VC中利用多线程技术实现线程之间的通信
作者: 刘涛 | ||||||||||||||||||
当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力。用进程和线程的观点来研究软件是当今普遍采用的方法,进程和线程的概念的出现,对提高软件的并行性有着重要的意义。现在的大型应用软件无一不是多线程多任务处理,单线程的软件是不可想象的。因此掌握多线程多任务设计方法对每个程序员都是必需要掌握的。本实例针对多线程技术在应用中经常遇到的问题,如线程间的通信、同步等,分别进行探讨,并利用多线程技术进行线程之间的通信,实现了数字的简单排序。 当主线程终止时,进程也随之终止。根据实际需要,应用程序可以分解成许多独立执行的线程,每个线程并行的运行在同一进程中。 第二步是根据需要重载该派生类的一些成员函数如:ExitInstance()、InitInstance()、OnIdle()、PreTranslateMessage()等函数。最后调用AfxBeginThread()函数的一个版本: CWinThread* AfxBeginThread( CRuntimeClass* pThreadClass, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL ) 启动该用户界面线程, 其中第一个参数为指向定义的用户界面线程类指针变量, 第二个参数为线程的优先级, 第三个参数为线程所对应的堆栈大小, 第四个参数为线程创建时的附加标志,缺省为正常状态,如为CREATE_SUSPENDED则线程启动后为挂起状态。 int GetThreadPriority(); 线程可以在自身内部调用AfxEndThread()来终止自身的运行; 可以在线程的外部调用BOOL TerminateThread( HANDLE hThread, DWORD dwExitCode )来强行终止一个线程的运行,然后调用CloseHandle()函数释放线程所占用的堆栈; 第三种方法是改变全局变量,使线程的执行函数返回,则该线程终止。 下面以第三种方法为例,给出部分代码: //////////////////////////////////////////////////////////////// 3、线程之间的通信 #define WM_USERMSG WMUSER+100; 在需要的时候,在一个线程中调用::PostMessage((HWND)param,WM_USERMSG,0,0)或CwinThread::PostThradMessage()来向另外一个线程发送这个消息, 上述函数的四个参数分别是消息将要发送到的目的窗口的句柄、要发送的消息标志符、消息的参数WPARAM和LPARAM。 下面的代码是对上节代码的修改,修改后的结果是在线程结束时显示一个对话框,提示线程结束: UINT ThreadFunction(LPVOID pParam) ////////WM_USERMSG消息的响应函数为OnThreadended(WPARAM wParam, | ||||||||||||||||||
VC中利用多线程技术实现线程之间的通信(2) | ||||||||||||||||||
4、线程之间的同步 临界区对应着一个CcriticalSection对象,当线程需要访问保护数据时,调用临界区对象的Lock()成员函数;当对保护数据的操作完成之后,调用临界区对象的Unlock()成员函数释放对临界区对象的拥有权,以使另一个线程可以夺取临界区对象并访问受保护的数据。 同时启动两个线程,它们对应的函数分别为WriteThread()和ReadThread(),用以对公共数组array[]操作,下面的代码说明了如何使用临界区对象: #include "afxmt.h" 上述代码运行的结果应该是Destarray数组中的元素分别为1-9,而不是杂乱无章的数,如果不使用同步,则不是这个结果,有兴趣的读者可以实验一下。 互斥与Cmutex类的对象相对应,使用互斥对象时,必须创建一个CSingleLock或CMultiLock对象,用于实际的访问控制,因为这里的例子只处理单个互斥,所以我们可以使用CSingleLock对象,该对象的Lock()函数用于占有互斥,Unlock()用于释放互斥。实现代码如下: #include "afxmt.h" (三)信号量 要实现计数处理,先创建一个CsingleLock或CmltiLock对象,然后用该对象的Lock()函数减少这个信号量的计数值,Unlock()反之。 下面的代码分别启动三个线程,执行时同时显示二个消息框,然后10秒后第三个消息框才得以显示。///////////////////////////////////////////////////////////////////////// 二、 编程步骤 | ||||||||||||||||||
VC中利用多线程技术实现线程之间的通信(3) | ||||||||||||||||||
三、 程序代码 ////////////////////////////////////////////////////////////////////////////// //调用RetEvent清除信号。若为 FALSE则在WaitForSingleObject DWORD WaitForSingleObject( data2 = new long[iDataLen]; data3 = new long[iDataLen]; data4 = new long[iDataLen]; data5 = new long[iDataLen]; | ||||||||||||||||||
用Visual C++语言在局域网实现IP多播 | ||||||||||||||||||
在局域网中,管理员常常需要将某条信息发送给一组用户。如果使用一对一的发送方法,虽然是可行的,但是过于麻烦,也常会出现漏发、错发。为了更有效的解决这种组通信问题,出现了一种多播技术(也常称为组播通信),它是基于IP层的通信技术。为了帮助读者理解,下面将简要的介绍一下多播的概念。
3、 多播路由器 | ||||||||||||||||||
用Visual C++语言在局域网实现IP多播(2) | ||||||||||||||||||
三、程序代码 //////////////////////////////Receiver.c程序代码: |
第11章 防火墙的设计与实现
网络安全基础:防火墙的概念及实现原理
一. 防火墙的概念
近年来,随着普通计算机用户群的日益增长,“防火墙”一词已经不再是服务器领域的专署,大部分家庭用户都知道为自己爱机安装各种“防火墙”软件了。但是,并不是所有用户都对“防火墙”有所了解的,一部分用户甚至认为,“防火墙”是一种软件的名称……
到底什么才是防火墙?它工作在什么位置,起着什么作用?查阅历史书籍可知,古代构筑和使用木制结构房屋的时候为防止火灾的发生和蔓延,人们将坚固的石块堆砌在房屋周围作为屏障,这种防护构筑物就被称为“防火墙”(FireWall)。时光飞梭,随着计算机和网络的发展,各种攻击入侵手段也相继出现了,为了保护计算机的安全,人们开发出一种能阻止计算机之间直接通信的技术,并沿用了古代类似这个功能的名字——“防火墙”技术来源于此。用专业术语来说,防火墙是一种位于两个或多个网络间,实施网络之间访问控制的组件集合。对于普通用户来说,所谓“防火墙”,指的就是一种被放置在自己的计算机与外界网络之间的防御系统,从网络发往计算机的所有数据都要经过它的判断处理后,才会决定能不能把这些数据交给计算机,一旦发现有害数据,防火墙就会拦截下来,实现了对计算机的保护功能。
防火墙技术从诞生开始,就在一刻不停的发展着,各种不同结构不同功能的防火墙,构筑成网络上的一道道防御大堤。
二. 防火墙的分类
世界上没有一种事物是唯一的,防火墙也一样,为了更有效率的对付网络上各种不同攻击手段,防火墙也派分出几种防御架构。根据物理特性,防火墙分为两大类,硬件防火墙和软件防火墙。软件防火墙是一种安装在负责内外网络转换的网关服务器或者独立的个人计算机上的特殊程序,它是以逻辑形式存在的,防火墙程序跟随系统启动,通过运行在Ring0级别的特殊驱动模块把防御机制插入系统关于网络的处理部分和网络接口设备驱动之间,形成一种逻辑上的防御体系。
在没有软件防火墙之前,系统和网络接口设备之间的通道是直接的,网络接口设备通过网络驱动程序接口(Network Driver Interface Specification,NDIS)把网络上传来的各种报文都忠实的交给系统处理,例如一台计算机接收到请求列出机器上所有共享资源的数据报文,NDIS直接把这个报文提交给系统,系统在处理后就会返回相应数据,在某些情况下就会造成信息泄漏。而使用软件防火墙后,尽管NDIS接收到仍然的是原封不动的数据报文,但是在提交到系统的通道上多了一层防御机制,所有数据报文都要经过这层机制根据一定的规则判断处理,只有它认为安全的数据才能到达系统,其他数据则被丢弃。因为有规则提到“列出共享资源的行为是危险的”,因此在防火墙的判断下,这个报文会被丢弃,这样一来,系统接收不到报文,则认为什么事情也没发生过,也就不会把信息泄漏出去了。
软件防火墙工作于系统接口与NDIS之间,用于检查过滤由NDIS发送过来的数据,在无需改动硬件的前提下便能实现一定强度的安全保障,但是由于软件防火墙自身属于运行于系统上的程序,不可避免的需要占用一部分CPU资源维持工作,而且由于数据判断处理需要一定的时间,在一些数据流量大的网络里,软件防火墙会使整个系统工作效率和数据吞吐速度下降,甚至有些软件防火墙会存在漏洞,导致有害数据可以绕过它的防御体系,给数据安全带来损失,因此,许多企业并不会考虑用软件防火墙方案作为公司网络的防御措施,而是使用看得见摸得着的硬件防火墙。
硬件防火墙是一种以物理形式存在的专用设备,通常架设于两个网络的驳接处,直接从网络设备上检查过滤有害的数据报文,位于防火墙设备后端的网络或者服务器接收到的是经过防火墙处理的相对安全的数据,不必另外分出CPU资源去进行基于软件架构的NDIS数据检测,可以大大提高工作效率。
硬件防火墙一般是通过网线连接于外部网络接口与内部服务器或企业网络之间的设备,这里又另外派分出两种结构,一种是普通硬件级别防火墙,它拥有标准计算机的硬件平台和一些功能经过简化处理的UNIX系列操作系统和防火墙软件,这种防火墙措施相当于专门拿出一台计算机安装了软件防火墙,除了不需要处理其他事务以外,它毕竟还是一般的操作系统,因此有可能会存在漏洞和不稳定因素,安全性并不能做到最好;另一种是所谓的“芯片”级硬件防火墙,它采用专门设计的硬件平台,在上面搭建的软件也是专门开发的,并非流行的操作系统,因而可以达到较好的安全性能保障。但无论是哪种硬件防火墙,管理员都可以通过计算机连接上去设置工作参数。由于硬件防火墙的主要作用是把传入的数据报文进行过滤处理后转发到位于防火墙后面的网络中,因此它自身的硬件规格也是分档次的,尽管硬件防火墙已经足以实现比较高的信息处理效率,但是在一些对数据吞吐量要求很高的网络里,档次低的防火墙仍然会形成瓶颈,所以对于一些大企业而言,芯片级的硬件防火墙才是他们的首选。
有人也许会这么想,既然PC架构的防火墙也不过如此,那么购买这种防火墙还不如自己找技术人员专门腾出一台计算机来做防火墙方案了。虽然这样做也是可以的,但是工作效率并不能和真正的PC架构防火墙相比,因为PC架构防火墙采用的是专门修改简化过的系统和相应防火墙程序,比一般计算机系统和软件防火墙更高度紧密集合,而且由于它的工作性质决定了它要具备非常高的稳定性、实用性和非常高的系统吞吐性能,这些要求并不是安装了多网卡的计算机就能简单替代的,因此PC架构防火墙虽然是与计算机差不多的配置,价格却相差很大。
现实中我们往往会发现,并非所有企业都架设了芯片级硬件防火墙,而是用PC架构防火墙甚至前面提到的计算机替代方案支撑着,为什么?这大概就是硬件防火墙最显著的缺点了:它太贵了!购进一台PC架构防火墙的成本至少都要几千元,高档次的芯片级防火墙方案更是在十万元以上,这些价格并非是小企业所能承受的,而且对于一般家庭用户而言,自己的数据和系统安全也无需专门用到一个硬件设备去保护,何况为一台防火墙投入的资金足以让用户购买更高档的电脑了,因而广大用户只要安装一种好用的软件防火墙就够了。
为防火墙分类的方法很多,除了从形式上把它分为软件防火墙和硬件防火墙以外,还可以从技术上分为“包过滤型”、“应用代理型”和“状态监视”三类;从结构上又分为单一主机防火墙、路由集成式防火墙和分布式防火墙三种;按工作位置分为边界防火墙、个人防火墙和混合防火墙;按防火墙性能分为百兆级防火墙和千兆级防火墙两类……虽然看似种类繁多,但这只是因为业界分类方法不同罢了,例如一台硬件防火墙就可能由于结构、数据吞吐量和工作位置而规划为“百兆级状态监视型边界防火墙”,因此这里主要介绍的是技术方面的分类,即“包过滤型”、“应用代理型”和“状态监视型”防火墙技术。
那么,那些所谓的“边界防火墙”、“单一主机防火墙”又是什么概念呢?所谓“边界”,就是指两个网络之间的接口处,工作于此的防火墙就被称为“边界防火墙”;与之相对的有“个人防火墙”,它们通常是基于软件的防火墙,只处理一台计算机的数据而不是整个网络的数据,现在一般家庭用户使用的软件防火墙就是这个分类了。而“单一主机防火墙”呢,就是我们最常见的一台台硬件防火墙了;一些厂商为了节约成本,直接把防火墙功能嵌进路由设备里,就形成了路由集成式防火墙……
三. 防火墙技术
传统意义上的防火墙技术分为三大类,“包过滤”(Packet Filtering)、“应用代理”(Application Proxy)和“状态监视”(Stateful Inspection),无论一个防火墙的实现过程多么复杂,归根结底都是在这三种技术的基础上进行功能扩展的。
1.包过滤技术
包过滤是最早使用的一种防火墙技术,它的第一代模型是“静态包过滤”(Static Packet Filtering),使用包过滤技术的防火墙通常工作在OSI模型中的网络层(Network Layer)上,后来发展更新的“动态包过滤”(Dynamic Packet Filtering)增加了传输层(Transport Layer),简而言之,包过滤技术工作的地方就是各种基于TCP/IP协议的数据报文进出的通道,它把这两层作为数据监控的对象,对每个数据包的头部、协议、地址、端口、类型等信息进行分析,并与预先设定好的防火墙过滤规则(Filtering Rule)进行核对,一旦发现某个包的某个或多个部分与过滤规则匹配并且条件为“阻止”的时候,这个包就会被丢弃。适当的设置过滤规则可以让防火墙工作得更安全有效,但是这种技术只能根据预设的过滤规则进行判断,一旦出现一个没有在设计人员意料之中的有害数据包请求,整个防火墙的保护就相当于摆设了。也许你会想,让用户自行添加不行吗?但是别忘了,我们要为是普通计算机用户考虑,并不是所有人都了解网络协议的,如果防火墙工具出现了过滤遗漏问题,他们只能等着被入侵了。一些公司采用定期从网络升级过滤规则的方法,这个创意固然可以方便一部分家庭用户,但是对相对比较专业的用户而言,却不见得就是好事,因为他们可能会有根据自己的机器环境设定和改动的规则,如果这个规则刚好和升级到的规则发生冲突,用户就该郁闷了,而且如果两条规则冲突了,防火墙该听谁的,会不会当场“死给你看”(崩溃)?也许就因为考虑到这些因素,至今我没见过有多少个产品会提供过滤规则更新功能的,这并不能和杀毒软件的病毒特征库升级原理相提并论。为了解决这种鱼与熊掌的问题,人们对包过滤技术进行了改进,这种改进后的技术称为“动态包过滤”(市场上存在一种“基于状态的包过滤防火墙”技术,即Stateful-based Packet Filtering,他们其实是同一类型),与它的前辈相比,动态包过滤功能在保持着原有静态包过滤技术和过滤规则的基础上,会对已经成功与计算机连接的报文传输进行跟踪,并且判断该连接发送的数据包是否会对系统构成威胁,一旦触发其判断机制,防火墙就会自动产生新的临时过滤规则或者把已经存在的过滤规则进行修改,从而阻止该有害数据的继续传输,但是由于动态包过滤需要消耗额外的资源和时间来提取数据包内容进行判断处理,所以与静态包过滤相比,它会降低运行效率,但是静态包过滤已经几乎退出市场了,我们能选择的,大部分也只有动态包过滤防火墙了。
基于包过滤技术的防火墙,其缺点是很显著的:它得以进行正常工作的一切依据都在于过滤规则的实施,但是偏又不能满足建立精细规则的要求(规则数量和防火墙性能成反比),而且它只能工作于网络层和传输层,并不能判断高级协议里的数据是否有害,但是由于它廉价,容易实现,所以它依然服役在各种领域,在技术人员频繁的设置下为我们工作着。
2.应用代理技术
由于包过滤技术无法提供完善的数据保护措施,而且一些特殊的报文攻击仅仅使用过滤的方法并不能消除危害(如SYN攻击、ICMP洪水等),因此人们需要一种更全面的防火墙保护技术,在这样的需求背景下,采用“应用代理”(Application Proxy)技术的防火墙诞生了。我们的读者还记得“代理”的概念吗?代理服务器作为一个为用户保密或者突破访问限制的数据转发通道,在网络上应用广泛。我们都知道,一个完整的代理设备包含一个服务端和客户端,服务端接收来自用户的请求,调用自身的客户端模拟一个基于用户请求的连接到目标服务器,再把目标服务器返回的数据转发给用户,完成一次代理工作过程。那么,如果在一台代理设备的服务端和客户端之间连接一个过滤措施呢?这样的思想便造就了“应用代理”防火墙,这种防火墙实际上就是一台小型的带有数据检测过滤功能的透明代理服务器(Transparent Proxy),但是它并不是单纯的在一个代理设备中嵌入包过滤技术,而是一种被称为“应用协议分析”(Application Protocol Analysis)的新技术。
“应用协议分析”技术工作在OSI模型的最高层——应用层上,在这一层里能接触到的所有数据都是最终形式,也就是说,防火墙“看到”的数据和我们看到的是一样的,而不是一个个带着地址端口协议等原始内容的数据包,因而它可以实现更高级的数据检测过程。整个代理防火墙把自身映射为一条透明线路,在用户方面和外界线路看来,它们之间的连接并没有任何阻碍,但是这个连接的数据收发实际上是经过了代理防火墙转向的,当外界数据进入代理防火墙的客户端时,“应用协议分析”模块便根据应用层协议处理这个数据,通过预置的处理规则(没错,又是规则,防火墙离不开规则)查询这个数据是否带有危害,由于这一层面对的已经不再是组合有限的报文协议,甚至可以识别类似于“GET /sql.asp?id=1 and 1”的数据内容,所以防火墙不仅能根据数据层提供的信息判断数据,更能像管理员分析服务器日志那样“看”内容辨危害。而且由于工作在应用层,防火墙还可以实现双向限制,在过滤外部网络有害数据的同时也监控着内部网络的信息,管理员可以配置防火墙实现一个身份验证和连接时限的功能,进一步防止内部网络信息泄漏的隐患。最后,由于代理防火墙采取是代理机制进行工作,内外部网络之间的通信都需先经过代理服务器审核,通过后再由代理服务器连接,根本没有给分隔在内外部网络两边的计算机直接会话的机会,可以避免入侵者使用“数据驱动”攻击方式(一种能通过包过滤技术防火墙规则的数据报文,但是当它进入计算机处理后,却变成能够修改系统设置和用户数据的恶意代码)渗透内部网络,可以说,“应用代理”是比包过滤技术更完善的防火墙技术。
但是,似乎任何东西都不可能逃避“墨菲定律”的规则,代理型防火墙的结构特征偏偏正是它的最大缺点,由于它是基于代理技术的,通过防火墙的每个连接都必须建立在为之创建的代理程序进程上,而代理进程自身是要消耗一定时间的,更何况代理进程里还有一套复杂的协议分析机制在同时工作,于是数据在通过代理防火墙时就不可避免的发生数据迟滞现象,换个形象的说法,每个数据连接在经过代理防火墙时都会先被请进保安室喝杯茶搜搜身再继续赶路,而保安的工作速度并不能很快。代理防火墙是以牺牲速度为代价换取了比包过滤防火墙更高的安全性能,在网络吞吐量不是很大的情况下,也许用户不会察觉到什么,然而到了数据交换频繁的时刻,代理防火墙就成了整个网络的瓶颈,而且一旦防火墙的硬件配置支撑不住高强度的数据流量而发生罢工,整个网络可能就会因此瘫痪了。所以,代理防火墙的普及范围还远远不及包过滤型防火墙,而在软件防火墙方面更是几乎没见过类似产品了——单机并不具备代理技术所需的条件,所以就目前整个庞大的软件防火墙市场来说,代理防火墙很难有立足之地。
3.状态监视技术
这是继“包过滤”技术和“应用代理”技术后发展的防火墙技术,它是CheckPoint技术公司在基于“包过滤”原理的“动态包过滤”技术发展而来的,与之类似的有其他厂商联合发展的“深度包检测”(Deep Packet Inspection)技术。这种防火墙技术通过一种被称为“状态监视”的模块,在不影响网络安全正常工作的前提下采用抽取相关数据的方法对网络通信的各个层次实行监测,并根据各种过滤规则作出安全决策。
“状态监视”(Stateful Inspection)技术在保留了对每个数据包的头部、协议、地址、端口、类型等信息进行分析的基础上,进一步发展了“会话过滤”(Session Filtering)功能,在每个连接建立时,防火墙会为这个连接构造一个会话状态,里面包含了这个连接数据包的所有信息,以后这个连接都基于这个状态信息进行,这种检测的高明之处是能对每个数据包的内容进行监视,一旦建立了一个会话状态,则此后的数据传输都要以此会话状态作为依据,例如一个连接的数据包源端口是8000,那么在以后的数据传输过程里防火墙都会审核这个包的源端口还是不是8000,否则这个数据包就被拦截,而且会话状态的保留是有时间限制的,在超时的范围内如果没有再进行数据传输,这个会话状态就会被丢弃。状态监视可以对包内容进行分析,从而摆脱了传统防火墙仅局限于几个包头部信息的检测弱点,而且这种防火墙不必开放过多端口,进一步杜绝了可能因为开放端口过多而带来的安全隐患。
由于状态监视技术相当于结合了包过滤技术和应用代理技术,因此是最先进的,但是由于实现技术复杂,在实际应用中还不能做到真正的完全有效的数据安全检测,而且在一般的计算机硬件系统上很难设计出基于此技术的完善防御措施(市面上大部分软件防火墙使用的其实只是包过滤技术加上一点其他新特性而已)。
四. 技术展望
防火墙作为维护网络安全的关键设备,在目前采用的网络安全的防范体系中,占据着举足轻重的位置。伴随计算机技术的发展和网络应用的普及,越来越多的企业与个体都遭遇到不同程度的安全难题,因此市场对防火墙的设备需求和技术要求都在不断提升,而且越来越严峻的网络安全问题也要求防火墙技术有更快的提高,否则将会在面对新一轮入侵手法时束手无策。
多功能、高安全性的防火墙可以让用户网络更加无忧,但前提是要确保网络的运行效率,因此在防火墙发展过程中,必须始终将高性能放在主要位置,目前各大厂商正在朝这个方向努力,而且丰富的产品功能也是用户选择防火墙的依据之一,一款完善的防火墙产品,应该包含有访问控制、网络地址转换、代理、认证、日志审计等基础功能,并拥有自己特色的安全相关技术,如规则简化方案等,明天的防火墙技术将会如何发展,让我们拭目以待。
解析防火墙负载均衡技术与功能实现原理
在谈及负载均衡应用的时候,说的最多的就是流量控制,网站负载,以及服务器负载等等。那么,现在要给大家介绍的是防火墙负载均衡的应用。还是让我们从基础了解,防火墙大家都知道,它是安全上网的一道屏障,有了它在很多不安因子都被挡在门外。那么,我们现在来看看如何进行防火墙的负载均衡。
防火墙负载均衡技术
概述
网络安全性是许多ICP和ISP长期担心的问题,网络安全已经成为了人们关注的焦点?网络安全技术将防火墙作为一种防止对网络资源进行非授权访问的常用方法?
尽管目前防火墙产品可以有效地防止网络入侵?但是,它本身也给ICP和ISP网络带来了问题?尤其是,目前防火墙技术限制了网络的性能和可伸缩性,并且由于防火墙经常成为单故障点,因而它降低了整体网络的可用性?
由于防火墙处于数据路径上,因此,它们可能会限制网络的性能和可伸缩性?在内部网络和外部网络之间的所有网络流量都必须经过防火墙?可惜的是,最适于防火墙的处理结构不适于检查高容量的数据包?由于防火墙必须处理每一个数据包,因而造成了通信速度的下降?扩展防火墙的性能十分困难,因为它一般要直接升级到功能更强大的硬件平台?
也是由于防火墙安放在数据路径上,因此,它们形成了降低网络资源可用性的单故障点?尽管多数防火墙可以使用市面上已有的高可用性软件以热备份的配置部署,但是,迄今为止,没有一种解决方案可以安全?可靠?高效支持多台防火墙同时工作?
新型Web交换机的防火墙负载均衡技术解决了上述问题?先进的Web交换机允许防火墙并行运行,使用户无需将防火墙升级就可以最大限度地发挥防火墙的工作效力,扩展防火的性能,同时使防火墙不再成为一种单故障点?
实现原理
与传统包交换机不同,Web交换机支持第四层以上的交换功能并具有维护不同TCP会话状态的能力?这类设备为实现防火墙的负载均衡提供了完美的平台?在实施防火墙负载均衡技术时,至少需要两台Web交换机:一台安装在防火墙的外部,另一台安装在内部?
改变所有输入数据流流向的过滤器被配置在连接外部网和内部网的Web交换机端口上?
为保持高可用性,Web交换机对防火墙的健康进行监控,只将数据包发向健康的防火墙?Web交换机通过正常地向每个防火墙另一端对应的交换机发送ping数据包来监控防火墙的健康情况?如果某个Web交换机接口不能回应ping命令,累计达到用户定义的次数,这个Web交换机端口(以及暗指的相关防火墙)就被置成"服务器故障"状态?同时,对应Web交换机停止向这个接口发送数据流,而将数据流分配到其余的健康的Web交换机接口和防火墙上?
当一个Web交换机接口处于"服务器故障"状态时,其对应的Web交换机继续以用户配置的速率向它发送ping命令?在发回第一个成功的ping回应后,该接口(以及防火墙)恢复到服务状态?
前几节描述的防火墙健康监控技术是Web交换机保证应用程序高可用性的一种方式?在采用防火墙负载均衡技术的同时使用热备份Web交换机,可以使应用获得更高水平的可用性?在使用防火墙负载均衡技术的情况下,可以采用Web交换机对(一台处于工作状态,另一台处于热备份状态?)来构造整个系统无单故障点的网络拓扑结构?这意味着Web交换机不是单故障点,使用它不会造成网络另一些点上的单故障点?
防火墙负载均衡功能实现
在案例中,使用了四台交换机,两台位于防火墙的外部,两台位于防火墙的内部?
在实施热备份配置时,每对Web交换机中的一台被指定为激活交换机,另一台被指定为备份交换机?在激活Web交换机与备份Web交换机之间配置一条直通链路,即所谓的故障转移链路?通常故障转移链路在激活的和备份Web交换机之间只传递Web交换机状态信息,数据流只有在激活Web交换机端口现出故障的情况下才经过故障转移链路传输?
如果激活Web交换机检测到链路故障的话,它就将此信息通过故障转移链路通知备份Web交换机?如果备份Web交换机上的相应端口是健康的话,该端口就被激活?
一、防火墙基本原理
首先,我们需要了解一些基本的防火墙实现原理。防火墙目前主要分包过滤,和状态检测的包过滤,应用层代理防火
墙。但是他们的基本实现都是类似的。
│ │---路由器-----网卡│防火墙│网卡│----------内部网络│ │
防火墙一般有两个以上的网络卡,一个连到外部(router),另一个是连到内部网络。当打开主机网络转发功能时,两个网卡间的网络通讯能直接通过。当有防火墙时,他好比插在网卡之间,对所有的网络通讯进行控制。
说到访问控制,这是防火墙的核心了:),防火墙主要通过一个访问控制表来判断的,他的形式一般是一连串的如下规则:
1 accept from+ 源地址,端口 to+ 目的地址,端口+ 采取的动作
2 deny ...........(deny就是拒绝。。)
3 nat ............(nat是地址转换。后面说)
防火墙在网络层(包括以下的炼路层)接受到网络数据包后,就从上面的规则连表一条一条地匹配,如果符合就执行预先安排的动作了!如丢弃包。。。。
但是,不同的防火墙,在判断攻击行为时,有实现上的差别。下面结合实现原理说说可能的攻击。
二、攻击包过滤防火墙
包过滤防火墙是最简单的一种了,它在网络层截获网络数据包,根据防火墙的规则表,来检测攻击行为。他根据数据包的源IP地址;目的IP地址;TCP/UDP源端口;TCP/UDP目的端口来过滤!!很容易受到如下攻击:
1 ip 欺骗攻击:
这种攻击,主要是修改数据包的源,目的地址和端口,模仿一些合法的数据包来骗过防火墙的检测。如:外部攻击者,将他的数据报源地址改为内部网络地址,防火墙看到是合法地址就放行了:)。可是,如果防火墙能结合接口,地址来匹
配,这种攻击就不能成功了:(
2 d.o.s拒绝服务攻击
简单的包过滤防火墙不能跟踪 tcp的状态,很容易受到拒绝服务攻击,一旦防火墙受到d.o.s攻击,他可能会忙于处理,而忘记了他自己的过滤功能。:)你就可以饶过了,不过这样攻击还很少的。!
3 分片攻击
这种攻击的原理是:在IP的分片包中,所有的分片包用一个分片偏移字段标志分片包的顺序,但是,只有第一个分片包含有TCP端口号的信息。当IP分片包通过分组过滤防火墙时,防火墙只根据第一个分片包的Tcp信息判断是否允许通过,而其他后续的分片不作防火墙检测,直接让它们通过。
这样,攻击者就可以通过先发送第一个合法的IP分片,骗过防火墙的检测,接着封装了恶意数据的后续分片包就可以直接穿透防火墙,直接到达内部网络主机,从而威胁网络和主机的安全。
4 木马攻击
对于包过滤防火墙最有效的攻击就是木马了,一但你在内部网络安装了木马,防火墙基本上是无能为力的。
原因是:包过滤防火墙一般只过滤低端口(1-1024),而高端口他不可能过滤的(因为,一些服务要用到高端口,因此防火墙不能关闭高端口的),所以很多的木马都在高端口打开等待,如冰河,subseven等。。。
但是木马攻击的前提是必须先上传,运行木马,对于简单的包过滤防火墙来说,是容易做的。这里不写这个了。大概就是利用内部网络主机开放的服务漏洞。
早期的防火墙都是这种简单的包过滤型的,到现在已很少了,不过也有。现在的包过滤采用的是状态检测技术,下面谈谈状态检测的包过滤防火墙。
三、攻击状态检测的包过滤
状态检测技术最早是checkpoint提出的,在国内的许多防火墙都声称实现了状态检测技术。
可是:)很多是没有实现的。到底什么是状态检测?
一句话,状态检测就是从tcp连接的建立到终止都跟踪检测的技术。
原先的包过滤,是拿一个一个单独的数据包来匹配规则的。可是我们知道,同一个tcp连接,他的数据包是前后关联的,先是syn包,-》数据包=》fin包。数据包的前后序列号是相关的。
如果割裂这些关系,单独的过滤数据包,很容易被精心够造的攻击数据包欺骗!!!如nmap的攻击扫描,就有利用syn包,fin包,reset包来探测防火墙后面的网络。!
相反,一个完全的状态检测防火墙,他在发起连接就判断,如果符合规则,就在内存登记了这个连接的状态信息(地址,port,选项。。),后续的属于同一个连接的数据包,就不需要在检测了。直接通过。而一些精心够造的攻击数据包由于没有在内存登记相应的状态信息,都被丢弃了。这样这些攻击数据包,就不能饶过防火墙了。
说状态检测必须提到动态规则技术。在状态检测里,采用动态规则技术,原先高端口的问题就可以解决了。实现原理是:平时,防火墙可以过滤内部网络的所有端口(1-65535),外部攻击者难于发现入侵的切入点,可是为了不影响正常的服务,防火墙一但检测到服务必须开放高端口时,如(ftp协议,irc等),防火墙在内存就可以动态地天加一条规则打开相关的高端口。等服务完成后,这条规则就又被防火墙删除。这样,既保障了安全,又不影响正常服务,速度也快。!
一般来说,完全实现了状态检测技术防火墙,智能性都比较高,一些扫描攻击还能自动的反应,因此,攻击者要很小
心才不会被发现。
但是,也有不少的攻击手段对付这种防火墙的。
1 协议隧道攻击
协议隧道的攻击思想类似与VPN的实现原理,攻击者将一些恶意的攻击数据包隐藏在一些协议分组的头部,从而穿透防火墙系统对内部网络进行攻击。
例如,许多简单地允许ICMP回射请求、ICMP回射应答和UDP分组通过的防火墙就容易受到ICMP和UDP协议隧道的攻击。
Loki和lokid(攻击的客户端和服务端)是实施这种攻击的有效的工具。在实际攻击中,攻击者首先必须设法在内部网络的一个系统上安装上lokid服务端,而后攻击者就可以通过loki客户端将希望远程执行的攻击命令(对应IP分组)嵌入在ICMP或
UDP包头部,再发送给内部网络服务端lokid,由它执行其中的命令,并以同样的方式返回结果。由于许多防火墙允许ICMP和UDP分组自由出入,因此攻击者的恶意数据就能附带在正常的分组,绕过防火墙的认证,顺利地到达攻击目标主机下面的命令是用于启动lokid服务器程序:
lokid-p CI Cvl
loki客户程序则如下启动:
loki Cd172.29.11.191(攻击目标主机)-p CI Cv1 Ct3
这样,lokid和loki就联合提供了一个穿透防火墙系统访问目标系统的一个后门。
2 利用FTP-pasv绕过防火墙认证的攻击
FTP-pasv攻击是针对防火墙实施入侵的重要手段之一。目前很多防火墙不能过滤这种攻击手段。如CheckPoint的Firewall-1,在监视FTP服务器发送给客户端的包的过程中,它在每个包中寻找"227"这个字符串。如果发现这种包,将从中提取目标地址和端口,并对目标地址加以验证,通过后,将允许建立到该地址的TCP连接。
攻击者通过这个特性,可以设连接受防火墙保护的服务器和服务。
3 反弹木马攻击
反弹木马是对付这种防火墙的最有效的方法。攻击者在内部网络的反弹木马定时地连接外部攻击者控制的主机,由于连接是从内部发起的,防火墙(任何的防火墙)都认为是一个合法的连接,因此基本上防火墙的盲区就是这里了。防火墙不能区分木马的连接和合法的连接。
但是这种攻击的局限是:必须首先安装这个木马!!!所有的木马的第一步都是关键!
四、攻击代理
代理是运行在应用层的防火墙,他实质是启动两个连接,一个是客户到代理,另一个是代理到目的服务器。
实现上比较简单,和前面的一样也是根据规则过滤。由于运行在应用层速度比较慢/1
攻击代理的方法很多。
这里就以wingate为例,简单说说了。(太累了)
WinGate是目前应用非常广泛的一种Windows95/NT代理防火墙软件,内部用户可以通过一台安装有WinGate的主机访问外部网络,但是它也存在着几个安全脆弱点。
黑客经常利用这些安全漏洞获得WinGate的非授权Web、Socks和Telnet的访问,从而伪装成WinGate主机的身份对下一
个攻击目标发动攻击。因此,这种攻击非常难于被跟踪和记录。
导致WinGate安全漏洞的原因大多数是管理员没有根据网络的实际情况对WinGate代理防火墙软件进行合理的设置,只是简单地从缺省设置安装完毕后就让软件运行,这就给攻击者可乘之机。
1 非授权Web访问
某些WinGate版本(如运行在NT系统下的2.1d版本)在误配置情况下,允许外部主机完全匿名地访问因特网。因此,外部攻击者就可以利用WinGate主机来对Web服务器发动各种Web攻击( 如CGI的漏洞攻击等),同时由于Web攻击的所有报文都是
从80号Tcp端口穿过的,因此,很难追踪到攻击者的来源。
检测
检测WinGate主机是否有这种安全漏洞的方法如下:
1) 以一个不会被过滤掉的连接(譬如说拨号连接)连接到因特网上。
2) 把浏览器的代理服务器地址指向待测试的WinGate主机。
如果浏览器能访问到因特网,则WinGate主机存在着非授权Web访问漏洞。
2 非授权Socks访问
在WinGate的缺省配置中,Socks代理(1080号Tcp端口)同样是存在安全漏洞。与打开的Web代理(80号Tcp端口)一样,外部攻击者可以利用Socks代理访问因特网。
防范
要防止攻击WinGate的这个安全脆弱点,管理员可以限制特定服务的捆绑。在多宿主(multi homed)系统上,执行以下步骤以限定如何提供代理服务。
1选择Socks或WWWProxyServer属性。
2选择Bindings标签。
3按下ConnectionsWillBeAcceptedOnTheFollowingInte***ceOnly按钮,并指定本WinGate服务器的内部接口。
非授权Telnet访问
它是WinGate最具威胁的安全漏洞。通过连接到一个误配置的inGate服务器的Telnet服务,攻击者可以使用别人的主机隐藏自己的踪迹,随意地发动攻击。
检测
检测WinGate主机是否有这种安全漏洞的方法如下:
1.使用telnet尝试连接到一台WinGate服务器。
[root@happy/tmp]#telnet172.29.11.191
Trying172.29.11.191….
Connectedto172.29.11.191.
Escapecharacteris‘^]’.
Wingate>10.50.21.5
2.如果接受到如上的响应文本,那就输入待连接到的网站。
3.如果看到了该新系统的登录提示符,那么该服务器是脆弱的。
Connectedtohost10.50.21.5…Connected
SunOS5.6
Login:
对策
防止这种安全脆弱点的方法和防止非授权Socks访问的方法类似。在WinGate中简单地限制特定服务的捆绑就可以解决这个问题。一般来说,在多宿主(multihomed)系统管理员可以通过执行以下步骤来完成:
1.选择TelnetSever属性。
2.选择Bindings标签。
3.按下ConnectionsWillBeAcceptedOnTheFollowingInte***ceOnly按钮,并指定本WinGate服务器的内部接口。
五、后话
有防火墙的攻击不单是上面的一点,我有什么写的不对的,大家指正。
一直以来,黑客都在研究攻击防火墙的技术和手段,攻击的手法和技术越来越智能化和多样化。但是就黑客攻击防火墙的过程上看,大概可以分为三类攻击。
第一类攻击防火墙的方法是探测在目标网络上安装的是何种防火墙系统并且找出此防火墙系统允许哪些服务。我们叫它为对防火墙的探测攻击。
第二类攻击防火墙的方法是采取地址欺骗、TCP序号攻击等手法绕过防火墙的认证机制,从而 对防火墙和内部网络破坏。
第三类攻击防火墙的方法是寻找、利用防火墙系统实现和设计上的安全漏洞,从而有针对性地发动攻击。这种攻击难度比较大,可是破坏性很大。
病毒分类及病毒命名规则详解 收藏
很多时候大家已经用杀毒软件查出了自己的机子中了例如Rootkit.Vanti.zg、Trojan.Win32.SendIP.15等等这些一串英文还带数字的病毒名,这时有些人就懵了,那么长一串的名字,我怎么知道是什么病毒啊?
其实只要我们掌握一些病毒的命名规则,我们就能通过杀毒软件的报告中出现的病毒名来判断该病毒的一些公有的特性了。
世界上那么多的病毒,反病毒公司为了方便管理,他们会按照病毒的特性,将病毒进行分类命名。虽然每个反病毒公司的命名规则都不太一样,但大体都是采用一个统一的命名方法来命名的。
一般格式为:<病毒前缀>.<病毒名>.<病毒后缀> 。
病毒前缀是指一个病毒的种类,他是用来区别病毒的种族分类的。不同的种类的病毒,其前缀也是不同的。比如我们常见的木马病毒的前缀Trojan ,蠕虫病毒的前缀是Worm等等还有其他的。
病毒名是指一个病毒的家族特征,是用来区别和标识病毒家族的,如以前著名的CIH病毒的家族名都是统一的“ CIH ”。
病毒后缀是指一个病毒的变种特征,是用来区别具体某个家族病毒的某个变种的。一般都采用英文中的26个字母来表示,如Worm.Sasser.b就是指振荡波蠕虫病毒的变种B,因此一般称为“振荡波B变种”或者“振荡波变种B”。如果该病毒变种非常多(也表明该病毒生命力顽强^_^),可以采用数字与字母混合表示变种标识。
综上所述,一个病毒的前缀对我们快速的判断该病毒属于哪种类型的病毒是有非常大的帮助的。通过判断病毒的类型,就可以对这个病毒有个大概的评估(当然这需要积累一些常见病毒类型的相关知识,这不在本文讨论范围)。而通过病毒名我们可以利用查找资料等方式进一步了解该病毒的详细特征。病毒后缀能让我们知道现在在你机子里呆着的病毒是哪个变种。
下面附带一些常见的病毒前缀的解释(针对我们用得最多的Windows操作系统):
1、系统病毒
系统病毒的前缀为:Win32、PE、Win95、W32、W95等。这些病毒的一般公有的特性是可以感染windows操作系统的*.exe和 *.dll文件,并通过这些文件进行传播。如CIH病毒。
2、蠕虫病毒
蠕虫病毒的前缀是:Worm。这种病毒的公有特性是通过网络或者系统漏洞进行传播,很大部分的蠕虫病毒都有向外发送带毒邮件,阻塞网络的特性。比如冲击波(阻塞网络),小邮差(发带毒邮件)等。
3、木马病毒、黑客病毒
木马病毒其前缀是:Trojan,黑客病毒前缀名一般为Hack 。木马病毒的公有特性是通过网络或者系统漏洞进入用户的系统并隐藏,然后向外界泄露用户的信息,而黑客病毒则有一个可视的界面,能对用户的电脑进行远程控制。木马、黑客病毒往往是成对出现的,即木马病毒负责侵入用户的电脑,而黑客病毒则会通过该木马病毒来进行控制。现在这两种类型都越来越趋向于整合了。这里补充一点,病毒名中有PSW或者什么PWD之类的一般都表示这个病毒有盗取密码的功能(这些字母一般都为“密码”的英文“password”的缩写)。
4、脚本病毒
脚本病毒的前缀是:Script。脚本病毒的公有特性是使用脚本语言编写,通过网页进行的传播的病毒,如红色代码。脚本病毒还会有如下前缀:VBS、JS(表明是何种脚本编写的。
5、宏病毒
其实宏病毒是也是脚本病毒的一种,由于它的特殊性,因此在这里单独算成一类。宏病毒的前缀是:Macro,第二前缀是:Word、Word97、Excel、Excel97(也许还有别的)其中之一。凡是只感染WORD97及以前版本WORD文档的病毒采用Word97做为第二前缀,格式是:Macro.Word97;凡是只感染WORD97以后版本WORD文档的病毒采用Word做为第二前缀,格式是:Macro.Word;凡是只感染EXCEL97及以前版本EXCEL文档的病毒采用Excel97做为第二前缀,格式是:Macro.Excel97;凡是只感染EXCEL97以后版本EXCEL文档的病毒采用Excel做为第二前缀,格式是:Macro.Excel,依此类推。该类病毒的公有特性是能感染OFFICE系列文档,然后通过OFFICE通用模板进行传播。
6、后门病毒
后门病毒的前缀是:Backdoor。该类病毒的公有特性是通过网络传播,给系统开后门,给用户电脑带来安全隐患。
7、病毒种植程序病毒
这类病毒的公有特性是运行时会从体内释放出一个或几个新的病毒到系统目录下,由释放出来的新病毒产生破坏。
8.破坏性程序病毒
破坏性程序病毒的前缀是:Harm。这类病毒的公有特性是本身具有好看的图标来诱惑用户点击,当用户点击这类病毒时,病毒便会直接对用户计算机产生破坏。
9.玩笑病毒
玩笑病毒的前缀是:Joke。也称恶作剧病毒。这类病毒的公有特性是本身具有好看的图标来诱惑用户点击,当用户点击这类病毒时,病毒会做出各种破坏操作来吓唬用户,其实病毒并没有对用户电脑进行任何破坏。
10.捆绑机病毒
捆绑机病毒的前缀是:Binder。这类病毒的公有特性是病毒作者会使用特定的捆绑程序将病毒与一些应用程序如QQ、IE捆绑起来,表面上看是一个正常的文件,当用户运行这些捆绑病毒时,会表面上运行这些应用程序,然后隐藏运行捆绑在一起的病毒,从而给用户造成危害。
以上为比较常见的病毒前缀,有时候我们还会看到一些其他的,但比较少见,这里简单提一下:
DoS:会针对某台主机或者服务器进行DoS攻击;
Exploit:会自动通过溢出对方或者自己的系统漏洞来传播自身,或者他本身就是一个用于Hacking的溢出工具;
HackTool:黑客工具,也许本身并不破坏你的机子,但是会被别人加以利用来用你做替身去破坏别人。
你可以在查出某个病毒以后通过以上所说的方法来初步判断所中病毒的基本情况,达到知己知彼的效果。
第12章 Foxmail邮件转发器设计与实现
件系统经常会遇到以下问题:
1. 垃圾邮件,经常收到各类垃圾邮件,尤其是色情,股票等严重敏感的垃圾邮件。
2. 重要邮件经常无法发送至国外等地方。
3. 邮件系统不稳定,别人发过来的邮件经常丢失或退回。
4. 邮件系统暴露在Internet,经常受到外部攻击。
5. 带宽情况糟糕,尤其是国外地区的链路。
6. 邮件系统日志查询困难,无暇定期分析日志。
串联解决方案
华堂反垃圾邮件防火墙的邮件处理系统支持透明网桥的串联接入模式,在这种接入模式下,修改了用户的影环境,但几乎可以不改动当前的网络软环境。
并联解决方案
并联接入的优点是不破坏网络的拓扑结构,只是简单地增加一台设备。只要对用户的网络运行环境作一些软设置。为了防止绕过反垃圾邮件防火墙对邮件服务器的攻击,所以可能需要对防火墙和邮件服务器进行一些配置。例如,通过设置防火墙把SMTP的流量定向到反垃圾邮件服务器上进行处理,关闭对邮件服务器的直接SMTP访问。
第13章 基于Telnet的BBS客户端的设计和实现
作者介绍