《通信網(wǎng)絡(luò)程序設(shè)計》課件第12章_第1頁
《通信網(wǎng)絡(luò)程序設(shè)計》課件第12章_第2頁
《通信網(wǎng)絡(luò)程序設(shè)計》課件第12章_第3頁
《通信網(wǎng)絡(luò)程序設(shè)計》課件第12章_第4頁
《通信網(wǎng)絡(luò)程序設(shè)計》課件第12章_第5頁
已閱讀5頁,還剩146頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第12章應(yīng)用層網(wǎng)絡(luò)編程12.1SMTP/POP3?協(xié)議編程12.2HTTP編程12.3FTP編程12.4SNMP編程小結(jié)

網(wǎng)絡(luò)通信的低層協(xié)議開發(fā)總是繁瑣和復(fù)雜的,其根本目標(biāo)最終還是服務(wù)于工作在應(yīng)用層上的進(jìn)程,因此應(yīng)用層網(wǎng)絡(luò)編程才是終極目標(biāo)。實現(xiàn)應(yīng)用層的編程方法大體可以分為兩種,即按照應(yīng)用層協(xié)議使用通用編程接口和調(diào)用應(yīng)用層協(xié)議專用編程接口。前者是前面花費大量篇幅所介紹知識的深入運用,后者是借助于開發(fā)平臺提供商對低層接口進(jìn)行封裝的一種便捷手段。本章結(jié)合具體的應(yīng)用層協(xié)議,對這兩種方法分別進(jìn)行了介紹。本章從FTP協(xié)議入手,首先采用基于WinSockAPI的最原始接口,講解編程實現(xiàn)SMTP/POP3應(yīng)用編程;接著使用微軟提供的WinInet實現(xiàn)基于HTTP和FTP的應(yīng)用層協(xié)議編程;最后使用SNMPAPI實現(xiàn)基于SNMP的應(yīng)用層協(xié)議編程。服務(wù)器的設(shè)計可重點參閱第8章的完成端口技術(shù),本章則更加側(cè)重于客戶端的編程。

互聯(lián)網(wǎng)電子郵件(ElectronicMail,E-mail)提供了快速傳遞信息的功能,是現(xiàn)在人們在互聯(lián)網(wǎng)上最常用的遠(yuǎn)程網(wǎng)絡(luò)通信工具。在TCP/IP協(xié)議中,完成該服務(wù)的協(xié)議主要是SMTP和POP3。12.1SMTP/POP3協(xié)議編程12.1.1SMTP/POP3協(xié)議簡介

1.SMTP

SMTP(SimpleMailTransferProtocol),即簡單郵件傳輸協(xié)議,它的目標(biāo)是可靠高效地傳送郵件,它獨立于傳送子系統(tǒng)且僅要求一條可以保證傳送數(shù)據(jù)單元順序的通道。SMTP的一個重要特點是它能夠接力傳送郵件,傳送服務(wù)提供了進(jìn)程間通信環(huán)境(IPCE),此環(huán)境可以包括一個網(wǎng)絡(luò)、幾個網(wǎng)絡(luò)或一個網(wǎng)絡(luò)的子網(wǎng)。因此,SMTP通常工作在兩種情況下:一是電子郵件從客戶端傳輸?shù)椒?wù)器;二是從某一個服務(wù)器傳輸?shù)搅硪粋€服務(wù)器。

SMTP設(shè)計基于以下通信模型:針對用戶的郵件請求,“發(fā)送SMTP進(jìn)程”與“接收SMTP進(jìn)程”之間建立一個雙向傳送通道。接收SMTP的可以是最終接收者,也可以是中間傳送者。SMTP命令由發(fā)送SMTP發(fā)出,由接收SMTP接收,而應(yīng)答則反方面?zhèn)魉汀R坏﹤魉屯ǖ澜?,SMTP發(fā)送者就發(fā)送MAIL命令指明郵件發(fā)送者。如果SMTP接收者可以接收郵件,則返回OK應(yīng)答。SMTP發(fā)送者再發(fā)出RCPT命令確認(rèn)郵件是否接收到。如果SMTP接收者接收,則返回OK應(yīng)答;如果不能接收到,則發(fā)出拒絕接收應(yīng)答(但不終止整個郵件操作),雙方將如此重復(fù)多次。當(dāng)接收者收到全部郵件后會接收到特別的序列,如果接收者成功處理了郵件,則返回OK應(yīng)答。SMTP提供傳送郵件的機制,當(dāng)接收方與發(fā)送方連接在同一個傳送服務(wù)下時,郵件可以直接由發(fā)送方主機傳送到接收方主機;或者,當(dāng)兩者不在同一個傳送服務(wù)下時,通過中繼SMTP服務(wù)器傳送。為了能夠給SMTP服務(wù)器提供中繼能力,它必須擁有最終目的主機地址和郵箱名稱。

由此可見,SMTP是一個命令(請求)/響應(yīng)協(xié)議。SMTP命令和響應(yīng)都是基于ASCII文本的,并以CR和LF符結(jié)束。響應(yīng)包括一個表示返回狀態(tài)的三位數(shù)字代碼。常見的SMTP命令與響應(yīng)分別如表12-1和表12-2所示。表12-1SMTP的基本命令表12-2SMTP服務(wù)器響應(yīng)碼應(yīng)答碼由三位構(gòu)成,每一位都有特定的意義。第一位應(yīng)答表示是成功的、失敗的或未完成的。通過這一位,不復(fù)雜的SMTP發(fā)送就可以容易地決定下一步的操作,如果發(fā)送方希望大概了解究竟出了什么問題,它可以檢測第二位,而第三位則保存了最后更完整的信息。也就是說,從第一位到第三位,接收方可以一步比一步精確地確定接收方的狀態(tài)。

SMTP是在TCP協(xié)議的25號端口監(jiān)聽連接請求的。為了加深對命令(請求)/響應(yīng)協(xié)議以及SMTP的理解,下面列舉一個簡單的SMTP的連接和發(fā)送過程描述:

(1)建立TCP連接。

(2)客戶端先發(fā)送HELO命令以標(biāo)識發(fā)件人自己的身份,然后發(fā)送MAIL命令,服務(wù)器端以O(shè)K作為響應(yīng),表明準(zhǔn)備接收。

(3)客戶端發(fā)送RCPT命令,以標(biāo)識該電子郵件的計劃接收人,可以有多個RCPT行,服務(wù)器端則表示是否愿意為收件人接受郵件。

(4)協(xié)商結(jié)束,發(fā)送郵件,用命令DATA發(fā)送。

(5)以“.”表示結(jié)束輸入內(nèi)容一起發(fā)送出去。

(6)結(jié)束此次發(fā)送,用QUIT命令退出。表12-3SMTP會話過程為了了解編程前服務(wù)器端的狀態(tài),可以利用Telnet遠(yuǎn)程登錄我們SMTP客戶端程序?qū)?yīng)的主機觀察郵件傳輸?shù)臅掃^程。以下是通過Telnet連接SMTP郵件服務(wù)器“eqmanager@.”發(fā)送一封電子郵件的SMTP協(xié)議交互過程,其中用戶名為“hellowxd”,密碼為“888888”。了解了這一交互過程,對于設(shè)計SMTP客戶端程序具有重要的參考價值,具體如圖12-1所示。圖12-1Telnet連接SMTP服務(wù)器需提請注意的是,目前很多黑客與病毒把SMTP的25端口作為窺探服務(wù)器內(nèi)部或傳播病毒的通道,因此25端口上的操作被認(rèn)為非常危險。為了避免25端口上的安全隱患,一方面,SMTP服務(wù)器增加了身份認(rèn)證的功能(如前述),另一方面許多安全軟件還限制或屏蔽了對遠(yuǎn)端服務(wù)器25端口的連接。為了使得Telnet過程不受影響,除了要有郵件服務(wù)器上合法的用戶名和密碼之外,還應(yīng)當(dāng)關(guān)閉安全軟件對25端口的監(jiān)控。

關(guān)于SMTP的更多介紹,可以參閱RFC821。

2.POP3

SMTP是與POP(PostOfficeProtocol,郵局協(xié)議)聯(lián)合使用的。POP用于接收電子郵件,適用于C/S結(jié)構(gòu)的脫機模型的電子郵件協(xié)議,目前已發(fā)展到第三版,稱為POP3。

POP3工作時,當(dāng)客戶機與服務(wù)器連接并查詢新電子郵件時,被該客戶機指定的所有將被下載的郵件都將被程序下載到客戶機,下載后,電子郵件客戶機就可以刪除或修改任意郵件,而無需與電子郵件服務(wù)器進(jìn)一步交互。POP3在TCP/110端口上等待客戶連接請求。POP3客戶向POP3服務(wù)器發(fā)送命令并等待響應(yīng),POP3命令采用命令行形式,用ASCII碼表示。服務(wù)器響應(yīng)由一個單獨的命令行或多個命令行組成,響應(yīng)的第一行以ASCII文本“+OK”或“-ERR”指出相應(yīng)的操作狀態(tài)是成功還是失敗。在POP3協(xié)議中有三種狀態(tài),即認(rèn)可、處理和更新狀態(tài)。當(dāng)客戶機與服務(wù)器建立聯(lián)系時,一旦客戶機提供了自己身份并成功確認(rèn),即由認(rèn)可狀態(tài)轉(zhuǎn)入處理狀態(tài),在完成相應(yīng)的操作后客戶機發(fā)出quit命令,則進(jìn)入更新狀態(tài),更新之后最后重返認(rèn)可狀態(tài)。

SMTP和POP3配合工作的過程如圖12-2所示。圖12-2TCP/IP互聯(lián)網(wǎng)上電子郵件的傳輸過程

12.1.2Base64編碼

E-mail只能傳送ASCII碼格式的文字信息,而ASCII碼是7位代碼,非ASCII碼格式的文件在傳送過程中就需要先編成7位的ASCII代碼,然后才能通過E-mail進(jìn)行傳送;如果不經(jīng)過編碼,則在傳送過程中會因為ASCII碼7位的限制而被分解,分解之后收信方將無法正確解釋ASCII字符,從而導(dǎo)致郵件傳輸失敗。在互聯(lián)網(wǎng)上,由于產(chǎn)生時間、生產(chǎn)廠家和使用協(xié)議的不同,對傳輸數(shù)據(jù)的編碼各不相同,最主要的編碼方式有UU編碼(Unix-to-Unixencoding)、MIME標(biāo)準(zhǔn)(MultipurposeInternetMailExtensions)等UU編碼解決了E-mail只能傳送ASCII文件的問題,但這種方式其實并不是很方便,因而,在Internet上使用一種新的編碼標(biāo)準(zhǔn)MIME(MultipurposeInternetMailExtensions),一般譯為“多媒體郵件傳送模式”。顧名思義,它可以傳送多媒體文件,在一封電子郵件中附加各種格式文件一起送出。

MIME定義了兩種編碼方式:QP(Quote-Printable)與Base64。QP的規(guī)則是:不對文件中的數(shù)據(jù)進(jìn)行特殊編碼,僅將8位的數(shù)據(jù)轉(zhuǎn)成7位。QP編碼適用于非ASCII碼的文字內(nèi)容,例如中文字符文件。而Base64的編碼規(guī)則是將整個文件重新編碼成小于或等于7位的數(shù)據(jù),通常用于傳送二進(jìn)制文件。編碼的方式不同會影響編碼之后的文件大小。具有MIME功能的E-mail軟件大都能自動判別郵件采用何種編碼,然后自動選擇用QP或Base64來解碼。

QP編碼是將一個字節(jié)用兩個十六進(jìn)制數(shù)值表示,然后在前面加“=”。如一段QP編碼后的數(shù)據(jù)為=A4=AE=A6=A1=A7=DA=AC=B1=E7=A9=A7=A1=AB=DC=B0=AA=B

Base64編碼后的文字通常為

PGquYaZuoUmn2qxPseepc6dnoUGr3LCqv70ms773t3ymYqa5plakaq5hptu

通過上述方法,郵件就可以傳輸二進(jìn)制數(shù)了,包括聲音、圖像、文本及可執(zhí)行文件。收信人通過支持MIME的軟件,把編碼后的文件翻譯過來,讀者在了解Base64的原理后,可以很容易地編程實現(xiàn)。

12.1.3SMTP客戶端設(shè)計

在了解了SMTP的工作原理后,本節(jié)進(jìn)行一個簡單的SMTP客戶端程序的實現(xiàn)。

本程序固化了SMTP的會話過程,假設(shè)郵件由me@發(fā)往him@,并帶有一個用戶設(shè)定路徑的文件為附件。編碼采用Base64編碼方式。

#include<winsock2.h>

#include<string.h>

#include<stdio.h>

constintBASE64_MAXLINE=76;

constcharEOL[]="\r\n";

constcharBASE64_TAB[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ"

"abcdefghijklmnopqrstuvwxyz0123456789+/";

constcharHEADER[]=

"HELO\r\n"

//"AUTHLOGIN\r\n"http://+BASE64USER+BASE64PASS①

"MAILFROM:me@\r\n"

"RCPTTO:him@\r\n"

"DATA\r\n"

"FROM:me@\r\n"

"TO:him@\r\n"

"SUBJECT:thisisatest\r\n"①有些SMTP服務(wù)器在進(jìn)行身份認(rèn)證時,要求對用戶名和密碼進(jìn)行基于Base64的編碼處理,在進(jìn)行測試時可利用諸如/tools/base64.aspx類似的Based64在線編碼器的幫助下,完成該項工作。

"Date:2011-5-18\r\n"

"X-Mailer:shadowstar'smailer\r\n"

"MIME-Version:1.0\r\n"

"Content-type:multipart/mixed;boundary=\"#BOUNDARY#\"\r\n"

//"Content-Type:text/plain;charset=gb2312\r\n"

"\r\n";

constcharCONTENT[]=

"\r\n--#BOUNDARY#\r\n"

"Content-Type:text/plain;charset=gb2312\r\n"

"Content-Transfer-Encoding:quoted-printable\r\n"

"\r\n"

"/*************************************************************"

"*UseSMTPtosendaneMailwithanAttachmentandverify*"

"*************************************************************"

"*/\r\n"

"\r\n";

constcharATT_HEADER[]=

"\r\n--#BOUNDARY#\r\n"

"Content-Type:application/octet-stream;name=smtp.exe\r\n"

"Content-Disposition:attachment;filename=smtp.exe\r\n"

"Content-Transfer-Encoding:base64\r\n"

"\r\n";

intANSIToBase64(constchar*szInANSI,intnInLen,char*szOutBase64,intnOutLen){…};\\略

intmain(intargc,char*argv[])

{

WSADATAwsaData;

intSockFD;

structsockaddr_inServAddr;

charbuf[0x100];

intx;

FILE*fp;

char*aatt=newchar[0x400000];

char*batt=newchar[0x555556];

//①套接字初始化

WSAStartup(MAKEWORD(2,2),&wsaData);

LPHOSTENTpHost=gethostbyname("");

SockFD=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

ServAddr.sin_family=AF_INET;

ServAddr.sin_addr.s_addr=*(ULONG*)pHost->h_addr_list[0];

ServAddr.sin_port=htons(25);

//②連接郵件服務(wù)器并發(fā)送郵件頭和內(nèi)容

connect(SockFD,(structsockaddr*)&ServAddr,sizeof(ServAddr));

send(SockFD,HEADER,strlen(HEADER),0);//sendHEADER

send(SockFD,CONTENT,strlen(CONTENT),0);//sendCONTENT

send(SockFD,ATT_HEADER,strlen(ATT_HEADER),0);//sendATT_HEADER

//③打開本地文件作為郵件附件

fp=fopen(argv[0],"rb");//readattachment

fseek(fp,0,2);

x=ftell(fp);

if(x>0x400000)x=0;

rewind(fp);

fread(aatt,x,1,fp);

fclose(fp);

x=ANSIToBase64(aatt,x,batt,0x555556);

//④發(fā)送郵件附件

send(SockFD,batt,x,0);//sendbase64attachment

send(SockFD,".\r\n",strlen(".\r\n"),0);//end

send(SockFD,"QUIT\r\n",strlen("QUIT\r\n"),0);//quit

//⑤關(guān)閉套接字

closesocket(SockFD);

WSACleanup();

delete[]aatt;

delete[]batt;

return0;

}

本程序?qū)崿F(xiàn)了基本的SMTP操作(程序中歸納為五步),與實際的郵件服務(wù)客戶端在功能、界面等方面還相差甚遠(yuǎn),但基本反映了郵件客戶端的基本骨架。

直接使用POP3設(shè)計程序的用戶較少,編程方法與上述程序類似,這里就不做過多介紹。

互聯(lián)網(wǎng)之所以能夠發(fā)展成為萬維網(wǎng),是因為它提供了一種更加方便的信息瀏覽方式,這就是Web。Web技術(shù)基于TCP/IP協(xié)議中的HTTP,更加注重信息的描述本身,而封裝了與繁瑣的TCP進(jìn)程相關(guān)的維護。12.2HTTP編程

12.2.1HTTP簡介

HTTP(HyperTextTransferProtocol)即超文本傳輸協(xié)議,是一種用于從Web服務(wù)器端傳送超文本標(biāo)記語言文件到客戶端瀏覽器的傳輸協(xié)議,它是Internet上常見的協(xié)議之一。我們通常訪問的網(wǎng)頁,就是通過HTTP協(xié)議進(jìn)行傳送的。HTTP用名字標(biāo)識某一資源時(即在瀏覽器中輸入網(wǎng)址),遵循統(tǒng)一資源名(UniformResourceName,URN)的規(guī)則,當(dāng)前網(wǎng)絡(luò)中最常用的URN是統(tǒng)一資源定位符(UniformResourceLocator,URI),當(dāng)客戶端在瀏覽器中輸入一個URL或單擊一個URL超鏈接時,就確定了要訪問的地址。以/

resource/index.html為例介紹URL的組成,其中:

http://:表示使用HTTP協(xié)議;

www:代表1個Web服務(wù)器;

/:Web服務(wù)器的域名或站點服務(wù)器的名稱;

resource/:Web服務(wù)器上的子目錄,類似機器中的文件夾;

index.html:Web服務(wù)器上resource子目錄中的一個網(wǎng)頁文件,即Web服務(wù)器傳送給客戶端瀏覽器的文件。

HTTP使用TCP協(xié)議的80端口進(jìn)行可靠數(shù)據(jù)傳輸,一個HTTP會話由客戶端開始發(fā)起,包括以下4個步驟(如圖12-3所示)。

圖12-3HTTP會話過程

(1)客戶機與WWW服務(wù)器或代理服務(wù)器建立連接(TCP)。

(2)客戶機發(fā)送一個請求給WWW服務(wù)器或代理服務(wù)器,請求的格式為:請求命令符

+

URL

+

協(xié)議版本號+MIME信息(含請求修飾符、客戶機信息和其他可能的內(nèi)容)。

(3)

WWW服務(wù)器或代理服務(wù)器接到請求后,給予響應(yīng)信息,其格式為:狀態(tài)行

+

響應(yīng)碼

+

MIME信息(含服務(wù)器信息、實體信息和其他可能的內(nèi)容)。

(4)客戶端接收WWW服務(wù)器或代理服務(wù)器返回的信息,并通過瀏覽器顯示在用戶的屏幕上。

Http協(xié)議的請求命令如表12-4所示。所有命令必須全為大寫,否則服務(wù)器會認(rèn)為是不可識別的。表12-4Http協(xié)議請求命令對于上述請求命令,服務(wù)器會根據(jù)具體情況返回響應(yīng)碼,這與12.1.1節(jié)介紹的SMTP協(xié)議非常類似,響應(yīng)碼的含義如表12-5所示。表12-5HTTP請求響應(yīng)碼

12.2.2WinInetAPI

WinInet是一個網(wǎng)絡(luò)編程接口,包含了對Internet底層協(xié)議HTTP、FTP、Gopher(已不太使用)的訪問。借助WinInet接口,不必了解WinSock、TCP/IP和特定Internet協(xié)議的細(xì)節(jié)就可以編寫出高水平的Internet客戶端程序。WinInet為HTTP、FTP、Gopher提供了統(tǒng)一的函數(shù)集,也就是Win32API接口,從而簡化了這幾種協(xié)議的編程。

1.Hinternet句柄

進(jìn)行WinInetAPI客戶端程序設(shè)計時需要使用一個特殊類型的句柄,即Hinternet。Hinternet不同于常規(guī)的Win32句柄,為WinInet所特有。Hinternet句柄由WinInetAPI函數(shù)創(chuàng)建,并且不同的函數(shù)所創(chuàng)建的Hinternet句柄之間還存在著承接關(guān)系,必須遵循這種承接關(guān)系進(jìn)行嵌套引用。最高級別的Hinternet句柄由InternetOpen()函數(shù)創(chuàng)建,下一級別的Hinternet句柄創(chuàng)建函數(shù)(包括InternetOpenUrl()和InternetConnect())必須引用這個句柄來創(chuàng)建,依次類推,圖12-4說明了Hinternet句柄的承接關(guān)系。圖12-4Hinternet句柄的承接關(guān)系基于WinInetAPI的HTTP、FTP的編程步驟是:首先,通過InternetOpen()函數(shù)創(chuàng)建位于根部的Hinternet句柄,通過其進(jìn)一步建立Http、FTP的連接;然后,使用InternetConnect()函數(shù)創(chuàng)建一個指定的連接,該連接將通過傳遞給它的參數(shù)為指定的站點初始化HTTP、FTP連接并創(chuàng)建一個從根句柄分支出去的Hinernet句柄;接著,HttpOpenRequest()和FtpOpenFile()、FtpFindFirstFile()等函數(shù)將使用InternetConnect()所創(chuàng)建的句柄以建立到指定站點的連接來進(jìn)行數(shù)據(jù)的交互;最后,關(guān)閉Hinternet句柄,釋放資源。

2.HTTP函數(shù)

一個基于WinInetAPI的HTTP的完整編程需要用到以下函數(shù)。

1)

WinInet初始化函數(shù)

HINTERNETInternetOpen(INLPCSTRlpszAgent, //應(yīng)用程序名,可以自定義

INDWORDdwAccessType, //存取類型

INLPCSTRlpszProxyName, //CERN代理服務(wù)器地址

INLPCSTRlpszProxyBypass, //代理服務(wù)器地址

INDWORDdwFlags); //標(biāo)記,一般設(shè)置為0

其中,參數(shù)dwAccessType可以是INTERNET_OPEN_TYPE_PRECONFIG,表示使用IE中的連接設(shè)置;也可以是INTERNET_OPEN_TYPE_DIRECT,表示直接連接到服務(wù)器;或

者是INTERNET_OPEN_TYPE_PROXY,表示通過代理服務(wù)器進(jìn)行連接。參數(shù)dwFlags可以是INTERNET_FLAG

_DONT_CACHE,表示不在緩存中保存取得的內(nèi)容;或是INTERNET_FLAG_OFFLINE,表示脫機方式。

2)打開Url來讀取數(shù)據(jù)函數(shù)

HINTERNETInternetOpenUrl(INHINTERNEThInternetSession, //由InternetOpen返回的句柄

INLPCSTRlpszUrl, //文件的Url地址

INLPCSTRlpszHeaders, //發(fā)送到服務(wù)器的數(shù)據(jù)頭

INDWORDdwHeadersLength, //發(fā)送到服務(wù)器的數(shù)據(jù)頭長度

INDWORDdwFlags, //標(biāo)記

INDWORDdwContext); //上下文標(biāo)記其中,參數(shù)dwFlags可以是INTERNET_FLAG_RELOAD,表示強制重讀數(shù)據(jù);或是INTERNET_FLAG_DONT_CACHE,表示不保存到緩存;或是INTERNET_FLAG_TRANSFER_ASCII,表示使用文本數(shù)據(jù);或是INTERNET_FLAG_TRANSFER_BINARY,表示使用二進(jìn)制數(shù)據(jù)。

3)建立Internet的連接函數(shù)

HINTERNETInternetConnect(INHINTERNEThInternetSession, //由InternetOpen返回的句柄

INLPCSTRlpszServerName, //服務(wù)器的地址HTTP地址

ININTERNET_PORTnServerPort, //HTTP協(xié)議端口號(缺省80)

INLPCSTRlpszUsername, //用戶名

INLPCSTRlpszPassword, //用戶密碼

INDWORDdwService, //決定服務(wù)類型

INDWORDdwFlags, //標(biāo)識

INDWORDdwContext); //上下文

其中,參數(shù)dwService可以是INTERNET_SERVICE_FTP,表示連接到一個FTP服務(wù)器;也可以是INTERNET_SERVICE_HTTP,表示連接到一個HTTP服務(wù)器。

4)打開一個HTTP請求的句柄函數(shù)

HINTERNETHttpOpenRequest(INHINTERNEThHttpSession, //InternetConnect句柄

INLPCSTRlpszVerb, //命令字

INLPCSTRlpszObjectName, //命令對象

INLPCSTRlpszVersion, //HTTP版本,缺省為“HTTP/1.0”

INLPCSTRlpszReferer, //一個網(wǎng)址,可以為空

INLPCSTRFAR*lpszAcceptTypes,//程序接收的文件類型列表

INDWORDdwFlags, //標(biāo)識

INDWORDdwContext); //上下文

其中,參數(shù)dwFlags可以使用or連接多個標(biāo)志,包括INTERNET_FLAG_NO_CACHE_WRITE,表示不緩沖寫;INTERNET_FLAG_KEEP_CONNECTION,表示保持連接;INTERNET_

FLAG_SECURE,表示使用PCT/SSL。

5)向HTTP服務(wù)器發(fā)送指定的請求函數(shù)

BOOLHttpSendRequest(INHINTERNEThHttpRequest, //HttpOpenRequest句柄

INLPCSTRlpszHeaders, //服務(wù)請求的數(shù)據(jù)頭

INDWORDdwHeadersLength, //服務(wù)請求的數(shù)據(jù)頭的長度

INLPVOIDlpOptional, //標(biāo)題后任意數(shù)據(jù)的地址,用于

//POST和PUT操作

DWORDdwOptionalLength); //數(shù)據(jù)的長度

6)設(shè)置一個Internet選項函數(shù)

BOOLInternetSetOption(INHINTERNEThInternet, //句柄

INDWORDdwOption, //Internet選項

INTERNET_OPTION_SEND_TIMEOUT //發(fā)送請求和連接時的

//超時時間

INTERNET_OPTION_RECEIVE_TIMEOUT, //接收請求和連接時的

//超時時間

INLPVOIDlpBuffer, //緩存區(qū)

INDWORDdwBufferLength); //緩存區(qū)大小其中,參數(shù)dwOption可以是INTERNET_OPTION_SEND_TIMEOUT,表示發(fā)送請求和連接時的超時時間;或者是INTERNET_OPTION_RECEIVE_TIMEOUT,表示接收請求和連接時的超時時間。

關(guān)于其他更多的WinInetAPI函數(shù)這里不作過多的介紹,可以參考MSDN。

12.2.3HTTP客戶端設(shè)計

本節(jié)介紹一個基于WinInetAPI函數(shù)的HTTP客戶端程序設(shè)計。該程序按照典型的HTTP客戶端程序的處理流程設(shè)計,簡化操作流程可分為七個步驟:①調(diào)用InternetOpen建立一個HINTERNET會話句柄;②調(diào)用InternetConnect建立與HTTP服務(wù)器的連接;③調(diào)用HttpOpenRequest初始化下載網(wǎng)頁的請求;④調(diào)用HttpSendRequert發(fā)送一個HTTP請示;⑤調(diào)用HttpQueryInfo獲取HTTP請求信息;⑥調(diào)用InternetReadFile讀文件;⑦依次調(diào)用InternetCloseHandle結(jié)束HTTP會話。以下就是該wininethttp2.cpp文件的程序代碼。

#include"stdafx.h"

#include"urlmon.h"

#include"wininet.h"

#pragmacomment(lib,"wininet.lib")

#pragmacomment(lib,"urlmon.lib")

typedefHRESULTSTDAPICALLTYPESHOWHTMLDIALOGFN(HWNDhwndParent,

IMoniker*pmk,VARIANT*pvarArgIn,TCHAR*pchOptions,VARIANT*pvArgOut);

char*buffer;

FILE*fp;

BOOLShowHtml()

{

SHOWHTMLDIALOGFN*pfnShowHTMLDialog;

HINSTANCEhinstMSHTML=LoadLibrary(TEXT("MSHTML.DLL")); //裝載動態(tài)鏈接庫

pfnShowHTMLDialog=

(SHOWHTMLDIALOGFN*)GetProcAddress(hinstMSHTML,TEXT("ShowHTMLDialog"));

if(pfnShowHTMLDialog==NULL)returnFALSE;

WCHAR*url=L"c:\\tempweb.html"; //此文件名可直接用地址名稱代替

if(hinstMSHTML) //裝載動態(tài)鏈接庫成功

{

SHOWHTMLDIALOGFN*pfnShowHTMLDialog;

pfnShowHTMLDialog=

(SHOWHTMLDIALOGFN*)GetProcAddress(hinstMSHTML,TEXT("ShowHTMLDialog"));

if(pfnShowHTMLDialog)

{//根據(jù)URL得到IMoniker*變量,需使用urlmon.lib

IMoniker*moniker=NULL;

if(FAILED(CreateURLMoniker(NULL,(LPWSTR)url,&moniker)))

{

FreeLibrary(hinstMSHTML);

returnFALSE;

}

char*pOptions=

(char*)L"dialogHeight:768px;dialogWidth:1024px;help:yes;status:yes;scroll:yes";

//這里必須是UNICODE型的字符串,否則更改不了窗口的大小

pfnShowHTMLDialog(NULL,moniker,NULL,pOptions,NULL);

//調(diào)用ShowHTMLDialog函數(shù)顯示臨時文件中的網(wǎng)頁

if(moniker!=NULL)moniker->Release();

returnTRUE; //顯示成功,返回TRUE

}

elsereturnFALSE; //GetProcessAddress失敗

FreeLibrary(hinstMSHTML);

}

elsereturnFALSE; //裝載動態(tài)鏈接庫失敗

}

BOOLopenwebpage()

{

//①建立會話

HINTERNEThSession=::InternetOpen("MYHTTPclient",PRE_CONFIG_INTERNET_ACCESS,

NULL,INTERNET_INVALID_PORT_NUMBER,0);

//②建立連接

HINTERNEThConnect=::InternetConnect(hSession,"",

//服務(wù)器名,記住不要加http://

INTERNET_INVALID_PORT_NUMBER,"","",INTERNET_SERVICE_HTTP,0,0);

//③初始化下載請求

HINTERNEThHttpFile=::HttpOpenRequest(hConnect,"GET","",//填寫欲打開的網(wǎng)頁名

HTTP_VERSION,NULL,0,INTERNET_FLAG_DONT_CACHE,0);

//④發(fā)送下載請求

BOOLbSendRequest=::HttpSendRequest(hHttpFile,NULL,0,0,0);

//⑤獲取文件長度

charbufQuery[32];

DWORDdwLengthBufQuery=sizeof(bufQuery);

BOOLbQuery=::HttpQueryInfo(hHttpFile,HTTP_QUERY_CONTENT_LENGTH,

bufQuery,&dwLengthBufQuery,NULL);

//轉(zhuǎn)換文件的下載頁面長度從ASCII字符串到DWORD.

DWORDdwFileSize=(DWORD)atol(bufQuery);

//為文件分配長度

buffer=newchar[dwFileSize+1];

//⑥讀取文件到內(nèi)存

DWORDdwBytesRead;

BOOLbRead=::InternetReadFile(hHttpFile,buffer,dwFileSize+1,&dwBytesRead);

//內(nèi)存末尾加入0字符

buffer[dwBytesRead]=0;

//將下載的網(wǎng)頁寫入臨時文件

fp=fopen("c:\\tempweb.html","wt+");

intnum=fwrite(buffer,sizeof(char),dwFileSize+1,fp);

fclose(fp);

//⑦關(guān)閉所有Internet句柄

::InternetCloseHandle(hHttpFile);

::InternetCloseHandle(hConnect);

::InternetCloseHandle(hSession);

returnTRUE;

}

intmain(intargc,char*argv[])

{

openwebpage(); //打開并下載網(wǎng)頁

ShowHtml(); //啟動顯示html的對話框

return0;

}上述程序?qū)⒛繕?biāo)網(wǎng)頁下載到本地,調(diào)用了一個網(wǎng)頁顯示對話框?qū)⑾螺d的文件用分辨率為1024

×

768的、帶滾動條的窗口顯示出來,顯示工作是由ShowHtml實現(xiàn)的??梢哉f,這個程序就是一個簡單的瀏覽器。如果在此程序上添加自動URL定位分析、多線程爬蟲

(又稱網(wǎng)頁蜘蛛,即spider)、網(wǎng)頁字符分析、倒排序表建立、檢索反饋等模塊,就又變成了網(wǎng)絡(luò)搜索引擎。

由于WinInetAPI短小精悍、效率高,因此目前在Wince平臺下應(yīng)用的也很多,主要用于手機瀏覽器等應(yīng)用的設(shè)計。

基于文件傳輸服務(wù)就是讓用戶連接上一個遠(yuǎn)程計算機,并查看遠(yuǎn)程計算機有哪些文件,然后把文件從遠(yuǎn)程計算機上復(fù)制到本地計算機,或把本地計算機的文件傳送給遠(yuǎn)程計算機。這種服務(wù)為網(wǎng)絡(luò)用戶的文件共享提供了極大的方便。在TCP/IP協(xié)議中,完成該服務(wù)的協(xié)議主要是FTP協(xié)議。12.3FTP編程

12.3.1FTP簡介

FTP(FileTransferProtocol,文件傳輸協(xié)議)是Internet上用來傳送文件的協(xié)議,在Internet上通過FTP服務(wù)器可以進(jìn)行文件的上傳(Upload)或下載(Download)。與前面介紹的SMTP和POP3類似,F(xiàn)TP也是一個請求/響應(yīng)協(xié)議,并且是實時聯(lián)機服務(wù),在使用它之前必須具有該服務(wù)的一個用戶(用戶名和口令)。工作時,客戶端必須先登錄到作為服務(wù)器一方的計算機上,用戶登錄后可以進(jìn)行文件搜索和文件傳送等有關(guān)操作。使用FTP可以傳送所有類型的文件,如文本文件、二進(jìn)制可執(zhí)行文件、圖像文件、聲音文件及數(shù)據(jù)壓縮文件等。與SMTP、POP3類似,F(xiàn)TP的主要操作都是基于各種命令基礎(chǔ)之上的。常用的命令分為登錄、退出登錄、傳輸參數(shù)、文件操作命令、獲得信息命令、其他命令等,表12-6給出了FTP協(xié)議主要命令,服務(wù)器應(yīng)答碼代表的含義可以在表12-7中查詢到。表12-6FTP命令表12-7FTP服務(wù)器應(yīng)答碼含義相比于SMTP和HTTP,F(xiàn)TP協(xié)議要復(fù)雜得多。復(fù)雜的原因是FTP協(xié)議要用到兩個TCP連接:一個是命令鏈路,用來在FTP客戶端與服務(wù)器之間傳遞命令;另一個是數(shù)據(jù)鏈路,用來上傳或下載數(shù)據(jù)。對于這兩條鏈路,F(xiàn)TP協(xié)議有兩種工作方式:PORT方式和PASV方式,即主動式和被動式。PORT(主動)式的連接過程是:客戶端向服務(wù)器的FTP端口(默認(rèn)是21)發(fā)送連接請求,服務(wù)器接受連接并建立一條命令鏈路。當(dāng)需要傳送數(shù)據(jù)時,客戶端在命令鏈路上用PORT命令告訴服務(wù)器:

“我打開了××××端口,你過來連接我”。于是服務(wù)器從20端口向客戶端的××××端口發(fā)送連接請求,建立一條數(shù)據(jù)鏈路來傳送數(shù)據(jù)。PASV

(被動)式的連接過程是:客戶端向服務(wù)器的FTP端口(默認(rèn)是21)發(fā)送連接請求,服務(wù)器接受連接,建立一條命令鏈路。當(dāng)需要傳送數(shù)據(jù)時,服務(wù)器在命令鏈路上用PASV命令告訴客戶端:“我打開了××××端口,你過來連接我”。于是客戶端向服務(wù)器的××××端口發(fā)送連接請求,建立一條數(shù)據(jù)鏈路來傳送數(shù)據(jù)。概括而言,主動模式是客戶端向服務(wù)器敲門,然后客戶端開門;被動模式是客戶端向服務(wù)器敲門,然后服務(wù)器開門?;贔TP命令和應(yīng)答碼的客戶端與服務(wù)器交互過程如圖12-5所示。對于FTP的更多介紹,可以參閱RFC959等更多文獻(xiàn),為了突出網(wǎng)絡(luò)編程多線程設(shè)計,下面的編程實習(xí)將對FTP連接過程進(jìn)行簡化,并只采用一個TCP連接傳送命令與數(shù)據(jù)。

12.3.2WinInet類

為了能夠在較高層次建立Internet客戶應(yīng)用程序,使編程過程得到進(jìn)一步簡化,MFC對WinInetAPI函數(shù)進(jìn)行了封裝,從而使程序員從那些復(fù)雜的端口和協(xié)議細(xì)節(jié)中解脫出來。WinInet類繼承了WinInetAPI的FTP、HTTP、Gopher的功能,提供了13個對這三種服務(wù)進(jìn)行訪問的類:CInternetSession、CInternetConnection、CFtpConnection、CGopherConnection、CHttpConnection、CInternetFile、CGopherFile、CHttpFile、CFileFind、CFtpFileFind、CGopherFileFind、CGopherLocator、CInternetException,在afxinet.h文件中聲明。這里著重介紹基于WinInet類進(jìn)行FTP客戶端編程時所需要使用的四個類:CInternetSession、CFtpConnection、CInternetFile、CInternetException。

1.CInternetSession類

CInternetSession類負(fù)責(zé)創(chuàng)建并初始化一個或幾個同步Internet會話,如其成員函數(shù)GetFtpConnection()就可以創(chuàng)建一個CFtpConnection對象,實現(xiàn)打開與FTP服務(wù)的一個連接。如果需要還可以向代理服務(wù)器描述連接。圖12-6CInternetSession類的派生結(jié)構(gòu)

CInternetSession類提供的QueryOption()、SetOption()、OpenURL()、GetFtpConnection()、GetHttpConnection()、GetGopherConnection()、EnableStatusCallback()、EnableStatusCallback()、ServiceTypeFromHandle()等成員函數(shù),用于完成對連接屬性的查詢、設(shè)置等操作。另外,還提供成員函數(shù)GetContext()、Close()、SetCookie()、GetCookie()、GetCookieLength(),實現(xiàn)對Cookie的查詢、設(shè)置等操作。此外,它還重載了OnStatusCallback()函數(shù),用于更新操作狀態(tài)、重載函數(shù)operator(),HINTERNET用于從當(dāng)前Internet會話中得到Windows句柄。12.3.1節(jié)中描述的FTP客戶端與服務(wù)器端復(fù)雜的交互過程就是由成員函數(shù)GetFtpConnection()所完成的。

CInternetSession類的派生結(jié)構(gòu)如圖12-6所示。2.CFtpConnection類

CFtpConnection類管理到Internet服務(wù)器的FTP連接,并允許用戶操作服務(wù)器上的目錄和文件。CFtpConnection類無需專門創(chuàng)建,只需調(diào)用GetFtpConnection()成員函數(shù)得到其返回值即可。圖12-7CFtpConnection類的派生結(jié)構(gòu)

CFtpConnection類的操作函數(shù)有:SetCurrentDirectory()、GetCurrentDirectory()、RemoveDirectory()、GetCurrentDirectory-AsURL()、CreateDirectory()、Rename()、Remove()、PutFile()、GetFile()、OpenFile()、Close(),可以完成設(shè)置服務(wù)器上的FTP目錄、得到連接的當(dāng)前目錄等操作。圖12-8CInternetFile類派生結(jié)構(gòu)

3.CInternetFile類

CInternetFile類及其派生類允許對使用Internet協(xié)議的遠(yuǎn)程系統(tǒng)中的文件進(jìn)行操作。同樣,CInternetFile類無需專門創(chuàng)建,在FTP編程中只需調(diào)用CFtpConnection的OpenFile()成員函數(shù)得到其返回值即可。

CInternetFile類的操作函數(shù)有SetWriteBufferSize()和SetReadBufferSize(),可以完成設(shè)置寫入緩沖區(qū)的尺寸、設(shè)置讀出緩沖區(qū)的尺寸等操作。CInternetFile類重載了CFile類的Seek()、Read()、Write()、Abort()、Flush()、Close()、ReadString()、WriteString()函數(shù),使之適合于對FTP服務(wù)器上的文件進(jìn)行相應(yīng)操作。該類的對象也可以使用operatorHINTERNET從當(dāng)前Internet會話中得到Windows句柄。CInternetFile類還有一個成員m_hFile,代表了與它的對象相關(guān)的文件句柄。

4.CInternetException類

CInternetException類代表與Internet操作相關(guān)的異常,該類包含兩個公共數(shù)據(jù)成員:一個保存與異常有關(guān)的錯誤碼,另一個保存導(dǎo)致錯誤應(yīng)用程序的上下文ID。

CInternetException類用成員函數(shù)Dump()或GetErrorMessage()獲得相關(guān)的錯誤信息。它的兩個參數(shù)m_dwError、m_dwContext分別代表前面提到的錯誤碼和上下文ID。CInternetException類派生結(jié)構(gòu)如圖12-9所示。

關(guān)于更多的WinInet類可以參閱MSDN。

12.3.3FTP客戶端設(shè)計

FTP客戶端的設(shè)計與HTTP的設(shè)計十分類似,用戶要實現(xiàn)某些行為,必須具備先決條件(如讀取文件,就必須先建立一個Internet連接)。與前一節(jié)不同的是,本節(jié)采用MFC的WinInet類的編程方法進(jìn)行實現(xiàn),表12-8列出了一般的FTP客戶端行為要實現(xiàn)某個目標(biāo)所必須使用的方法。

表12-8MFCWinInet類FTP客戶端設(shè)計流程表12-9MFCWinInet類FTP客戶端文件刪除設(shè)計流程

對于網(wǎng)絡(luò)中的設(shè)備管理員有進(jìn)行網(wǎng)絡(luò)管理信息收集與設(shè)置的需求,對于這種需求可以通過SNMP這種應(yīng)用層協(xié)議的支持來實現(xiàn)。雖然SNMP不是直接為用戶傳遞信息設(shè)計的,但是對于傳輸信息的網(wǎng)絡(luò)管理至關(guān)重要,也是需要加以重視的一種應(yīng)用協(xié)議。12.4SNMP編程

12.4.1SNMP簡介

SNMP(SimpleNetworkManagementProtocol)即簡單網(wǎng)絡(luò)管理協(xié)議,它為網(wǎng)絡(luò)管理系統(tǒng)提供了底層網(wǎng)絡(luò)管理的框架。SNMP是一種無連接協(xié)議,其工作是通過使用請求報文和返回響應(yīng)的方式,在管理代理和管理員之間傳送信息,這種機制減輕了管理代理的負(fù)擔(dān)。SNMP網(wǎng)絡(luò)管理主要分為四部分:被管理節(jié)點(設(shè)備)、客戶代理、網(wǎng)絡(luò)管理工作站、網(wǎng)絡(luò)管理協(xié)議。實際上,SNMP采用了C/S模型的一種特殊形式:代理/管理站模型,對網(wǎng)絡(luò)的管理與維護是通過管理工作站與SNMP代理間的交互工作完成的,每個SNMP從代理負(fù)責(zé)回答SNMP管理工作站的各種查詢了??蛻舳舜戆惭b在被管理節(jié)點設(shè)備上。

1.MIB庫

SNMP管理者收集網(wǎng)絡(luò)設(shè)備信息并記錄在MIB(ManagementInformationBase,管理信息庫)中,這些網(wǎng)絡(luò)設(shè)備信息包括設(shè)備特性、數(shù)據(jù)吞吐量、通信超載和錯誤等。MIB數(shù)據(jù)對象以一種樹狀分層結(jié)構(gòu)進(jìn)行組織,其每個分枝都有一個專用的名字和一個數(shù)字形式的標(biāo)識符?;谶@個樹狀分層結(jié)構(gòu),可以使用MIB瀏覽器方便而且簡潔的方式訪問整個MIB數(shù)據(jù)庫。MIB中的對象使用Oid(對象標(biāo)志符)。Oid是以SMI(StructureofManagementInformation)管理信息結(jié)構(gòu)為基礎(chǔ)的一系列點分符號,如.,這些點分符號在任何網(wǎng)絡(luò)設(shè)備中都唯一標(biāo)識某一個數(shù)據(jù)參數(shù),例如IBM為.4.1.2},Cisco為{.4.1.9},Novell為{.4.1.23}等。這里,SMI實際上起到規(guī)范MIB內(nèi)容的作用,可以理解成一種語言,它使MIB中描述的信息不存在二義性。對具體oid數(shù)據(jù)的含義可在/網(wǎng)站進(jìn)行查詢。

2.SNMP操作

SNMP協(xié)議定義了請求/設(shè)置網(wǎng)絡(luò)管理數(shù)據(jù)的操作,可用于處理管理代理定義的各種任務(wù)。SNMP協(xié)議之所以易于使用,這是因為它對外提供了三種用于控制MIB對象的基本操作命令,分別是Set、Get和Trap,如表12-10所示。表12-10SNMP命令的含義

3.SNMP報文

SNMP提供的操作實現(xiàn)了網(wǎng)絡(luò)管理員和管理代理之間的信息交換,這些信息是裝載在SNMP報文數(shù)據(jù)報中的。一條SNMP報文由三部分組成:版本(version)域、分區(qū)(community)域和SNMP協(xié)議數(shù)據(jù)單元(ProtocolDataUnit,PUD)域,數(shù)據(jù)包的長度不是固定的。

版本域:用于說明現(xiàn)在使用的是哪個版本的SNMP協(xié)議,管理工作站與客戶代理必須使用相同版本的SNMP協(xié)議。

分區(qū)域:分區(qū)是基本的安全機制,用于實現(xiàn)SNMP網(wǎng)絡(luò)管理員訪問SNMP管理代理時的身份驗證。協(xié)議數(shù)據(jù)單元域:指明了SNMP的消息類型及相關(guān)參數(shù)。SNMPv1的PDU有五種類型,有些是報文請求(Request),有些則是響應(yīng)(Response)。它們包括GetRequest、GetNextRequest、SetRequest、GetResponse、Trap。SNMPv2又增加了兩種PDU類型:GetBulkRequest和InformRequest。

12.4.2SNMP的開發(fā)方法

SNMP的開發(fā)需要在被管理的設(shè)備上安裝SNMP客戶端代理,并使用合適的開發(fā)工具。

1.SNMP代理安裝

在運用SNMP應(yīng)用程序之前,需要查看目標(biāo)系統(tǒng)中是否已經(jīng)安裝有SNMP客戶端代理,Windows操作系統(tǒng)下的查看方法是:單擊“開始→運行→cmd”,按“回車”鍵,輸入命令“netstartsnmp”,如圖12-10所示,表示SNMP已安裝,否則需先安裝SNMP客戶端代理。圖12-10SNMP客戶端代理安裝情況查詢

Windows平臺下安裝SNMP客戶端代理的方法如下:

(1)打開控制面板,雙擊“添加/刪除程序”項。

(2)在彈出的“添加/刪除程序”對話框的左窗格中,單擊“添加/刪除Windows組

件”項。

(3)在彈出的“Windows組件向?qū)А敝须p擊“管理和監(jiān)視工具”項。

(4)在彈出的“管理和監(jiān)視工具”對話框中勾選“簡單網(wǎng)絡(luò)管理協(xié)議”,單擊“確定”按鈕。安裝協(xié)議時需要用到與當(dāng)前操作系統(tǒng)相配套的系統(tǒng)安裝盤,然后可能需要重啟。

(5)再按前面執(zhí)行“netstartsnmp”命令那樣啟動SNMP服務(wù)。

2.SNMP的開發(fā)工具

在基于SNMP的開發(fā)時,有以下幾種選擇:

(1)采用直接網(wǎng)絡(luò)編程的方法直接發(fā)UDP包,這樣最原始、靈活,基本上完全自主,但是開發(fā)過于麻煩。

(2)在Windows系統(tǒng)下可以使用Microsoft提供的WinsnmpAPI函數(shù)。

(3)選擇一些第三方的源SNMP開發(fā)包,比如像NET-SNMP、SNMP++

等。

本書重點介紹基于WinsnmpAPI函數(shù)的SNMP協(xié)議編程。

12.4.3WinsnmpAPI主要函數(shù)

整個SNMP編程要經(jīng)過一個創(chuàng)建、執(zhí)行、銷毀的過程,即先加載SNMP的功能,接著執(zhí)行所進(jìn)行的操作,最后釋放占用資源,進(jìn)一步細(xì)分可分為:①SNMP加載;②建立會話;③設(shè)置傳輸模式;④創(chuàng)建實體;⑤設(shè)置重傳模式;⑥設(shè)置超時時間;⑦設(shè)置重傳次數(shù);⑧創(chuàng)建上下文句炳;⑨創(chuàng)建變量捆綁列表;⑩追加綁定列表;創(chuàng)建PDU;發(fā)送消息;接收消息、提取數(shù)據(jù)報;計算返回列表數(shù)目,取得返回結(jié)果;清理現(xiàn)場。以下介紹Winsnmp編程時需要使用的主要API函數(shù)。

1)加載SNMP函數(shù)

加載SNMP用到函數(shù)SnmpStartup(),原型如下:

SnmpStartup(smiLPUINT32nMajorVersion, //WinSNMPAPI主版本號

smiLPUINT32nMinorVersion, //WinSNMPAPI副本號

smiLPUINT32nLevel, //SNMP執(zhí)行支持級別

smiLPUINT32nTranslateMode, //默認(rèn)的實體/上下文傳輸模式

smiLPUINT32nRetransmitMode); //默認(rèn)的重發(fā)機制

2)建立會話函數(shù)

建立SNMP會話使用函數(shù)SnmpOpen()或SnmpCreateSession(),原型如下:

HSNMP_SESSIONSnmpOpen(HWNDhWnd, //接收消息窗口句炳

UINTwMsg); //hWnd窗口需要接收的消息碼

HSNMP_SESSIONSnmpCreateSession(HWNDhWnd, /接收消息窗口句炳

UINTwMsg, //hWnd窗口需要接收的消息碼

SNMPAPI_CALLBACKpfnCallBack,//回調(diào)函數(shù)句柄

LPVOIDlpClientData);//回調(diào)函數(shù)數(shù)據(jù)指針

第二個函數(shù)并沒有被完全確定下來,它只是為程序員在編程過程中不是基于Windows的編程提供一種選擇。

3)設(shè)置傳輸模式函數(shù)

設(shè)置傳輸模式使用函數(shù)SnmpSetTranslateMode(),原型如下:

SNMPAPI_STATUSSnmpSetTranslateMode(smiUINT32nTranslateMode);

該函數(shù)只有一個參數(shù),有以下幾種選擇:SNMPAPI_TRANSLATED(不常用)、SNMPAPI_UNTRANSLATED_V1(版本V1)、SNMPAPI_UNTRANSLATED_V2(版本V2),可以選擇任一個參數(shù)。

4)創(chuàng)建實體函數(shù)

創(chuàng)建實體用到的函數(shù)是HSNMP_ENTITYSnmpStrToEntity(),原型如下:

HSNMP_ENTITYSnmpStrToEntity( HSNMP_SESSIONsession, //WinSNMP會話句柄

LPCSTRstring); //用于識別實體的字符串指針

該函數(shù)的第一個參數(shù)是第2步返回的會話句炳,第二個參數(shù)與第3步中設(shè)置的傳輸模式有關(guān),如果你選擇后兩個參數(shù),那么這里的string就是所要發(fā)送消息的網(wǎng)絡(luò)設(shè)備IP地址或接收消息的管理設(shè)備IP地址。該函數(shù)返回一個實體句炳。

5)設(shè)置重傳模式函數(shù)

設(shè)置重傳模式用到的函數(shù)是SnmpSetRetransmitMode(),原型如下:

SNMPAPI_STATUSSnmpSetRetransmitMode(smiUINT32nRetransmitMode);

該函數(shù)只有一個參數(shù),有以下兩種選擇:SNMPAPI_ON,標(biāo)識啟動重傳模式;SNMPAPI_OFF,標(biāo)識關(guān)閉重傳模式。

6)設(shè)置超時時間函數(shù)

設(shè)置超時時間用到的函數(shù)是SnmpSetTimeout(),原型如下:

SNMPAPI_STATUSSnmpSetTimeout( HSNMP_ENTITYhEntity, //實體句柄

smiTIMETICKSnPolicyTimeout); //超時的時間

該函數(shù)的第一個參數(shù)是第4步返回的實體句炳,通常設(shè)置目標(biāo)實體的超時時間,也就是接收消息的網(wǎng)絡(luò)設(shè)備的實體。

7)設(shè)置重傳次數(shù)函數(shù)

用到的函數(shù)是SnmpSetRetry(),原型如下:

SNMPAPI_STATUSSnmpSetRetry(HSNMP_ENTITYhEntity, //實體句柄

smiUINT32nPolicyRetry); //重傳次數(shù)

該函數(shù)的第一個參數(shù)是第4步返回的實體句柄,通常設(shè)置目標(biāo)實體的重傳次數(shù),也就是接收消息的網(wǎng)絡(luò)設(shè)備的實體。

8)創(chuàng)建上下文句柄函數(shù)

創(chuàng)建上下文句柄用到的函數(shù)是SnmpStrToContext(),原型如下:

HSNMP_CONTEXTSnmpStrToContext(HSNMP_SESSIONsession, //會話句柄

smiLPCOCTETSstring); //字符串結(jié)構(gòu)指針

該函數(shù)的第一個參數(shù)是第2步返回的會話句柄,第二個參數(shù)與設(shè)置的傳輸模式有關(guān)。該函數(shù)返回一個上下文句柄。由第1步、第4步、第8步得到三個重要的句柄:會話句柄、實體句柄、上下文句柄。

9)創(chuàng)建變量捆綁列表函數(shù)

創(chuàng)建變量捆綁列表用到的函數(shù)是SnmpCreateVbl(),原型如下:

HSNMP_VBLSnmpCreateVbl(HSNMP_SESSIONsession, //會話句柄

smiLPCOIDname, //指向變量名的指針

smiLPCVALUEvalue); //指向變量值的指針

10)追加綁定列表函數(shù)

追加綁定列表用到的函數(shù)是SnmpSetVb(),原型如下:

SNMPAPI_STATUSSnmpSetVb(HSNMP_VBLvbl, //綁定列表句柄參數(shù)

smiUINT32index, //變量綁定索引

smiLPCOIDname //實體變量名部分指針

smiLPCVALUEvalue); //實體變量值部分指針

11)數(shù)據(jù)發(fā)送函數(shù)

數(shù)據(jù)發(fā)送用函數(shù)SnmpCreatePdu(),原型如下:

HSNMP_PDUSnmpCreatePdu(HSNMP_SESSIONsession, //會話句柄

smiINTPDU_type, //PDUtype

smiINT32request_id, //PDU請求標(biāo)識

smiINTerror_status, //錯誤狀態(tài)

smiINTerror_index, //錯誤索引

HSNMP_VBLvarbindlist); //變量綁定列表句柄第二個參數(shù)很重要,它表示想要執(zhí)行的操作方式,有如下的選項:SNMP_PDU_GET、SNMP_PDU_GETNEXT、SNMP_PDU_RESPONSE、SNMP_PDU_SET、SNMP_PDU_V1TRAP、SNMP_PDU_GETBULK、SNMP_PDU_TRAP。第三個參數(shù)request_id對于異步操作用來標(biāo)志某一個請求的消息。error_status和error_index在SNMP_PDU_GETBULK操作中分別為PDU中的non_repeaters域和max_repetitions域指定一個值。error_status僅對SNMP_PDU_GETBULK請求有效,error_index僅對SNMP

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論