青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

思勤無邪

上學(xué)時(shí),因我年齡最小,個(gè)頭也最小,上課時(shí),就像大猩猩堆里的猴一般。如今,這猴偶爾也把最近的一些情況寫在這里。

   :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
  132 Posts :: 1 Stories :: 178 Comments :: 0 Trackbacks

公告

     吾日常三省吾身,曰思、曰勤、曰無邪。

積分與排名

  • 積分 - 187701
  • 排名 - 140

最新隨筆

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

 

一、 ISAPI 簡介

通用網(wǎng)關(guān)接口 CommonGatewayInterface(CGI) 很早就作為交互式的 Web 應(yīng)用程序的一個(gè)標(biāo)準(zhǔn)廣泛應(yīng)用在 Internet 之中。 CGI 腳本允許人們用多種編程語言 ( Basic C Perl Shell 等等 ) 來編寫簡單的應(yīng)用程序。這些腳本運(yùn)行在 Web 服務(wù)器上, 而在客戶的 Web 瀏覽器上輸出運(yùn)行結(jié)果。客戶的輸入通過環(huán)境變量或者標(biāo)準(zhǔn)輸入設(shè)備來進(jìn)行傳遞, 然后 CGI 程序根據(jù)需要完成特定的操作,并通過 HTML 格式顯示在客戶的瀏覽器中。 CGI 的這一特性給互聯(lián)網(wǎng)帶來了生機(jī),網(wǎng)站的建設(shè)也從此從沉默的處子變?yōu)闊崃业纳倥S著時(shí)間的推移,這位曾經(jīng)轟動(dòng)一時(shí)的白雪公主也日益疲乏起來。

人們?cè)陂L期的使用中還是發(fā)現(xiàn)了 CGI 應(yīng)用程序的一個(gè)很大的缺點(diǎn):性能不高。 我每請(qǐng)求一次 CGE 程序時(shí), CGI 執(zhí)行文件(或者腳本的解釋器)都要為每一個(gè)請(qǐng)求創(chuàng)建一個(gè)新的進(jìn)程。對(duì)于一個(gè)信息量比較大的站點(diǎn)來說,這無疑給服務(wù)器增加了一個(gè)沉重的負(fù)擔(dān)。在以后的歲月里,熱鬧的互聯(lián)網(wǎng)又推出了 ASP JSP 等好多提高安全性及服務(wù)器性能的措施,可其安全性及開發(fā)工具的成熟度遠(yuǎn)遠(yuǎn)不及 VC Delphi 等成功的工具,而作為一個(gè)熟悉軟件編程的程序員來說,利用現(xiàn)成的開發(fā)工具及現(xiàn)有的資源開發(fā)一套網(wǎng)站系統(tǒng)更是得心應(yīng)手。

ISAPI Internet Server Aplication Programing Interfase )就是一種用編程工具進(jìn)行開發(fā),、運(yùn)行于 NT 服務(wù)的一種標(biāo)準(zhǔn)的編程接口, Web 開發(fā)者可用它編寫交互式應(yīng)用程序。 ISAPI 擴(kuò)展( Extension )應(yīng)用程序具有 CGI 腳本同樣的功能,但它比 CGI 具有更快、更有效的性能。

ISAPI for Windows NT 編寫的應(yīng)用程序, Web 用戶可通過填寫 HTML 表單( Form )或單擊 Web 節(jié)點(diǎn)上 HTML 頁面中的鏈接來激活該應(yīng)用程序。服務(wù)器端獲取用戶提供的信息后,被激活的 ISAPI 應(yīng)用程序?qū)Λ@取的信息作出處理。根據(jù) ISAPI 應(yīng)用程序的功能或把獲取的信息存入數(shù)據(jù)庫,或以獲取的信息為條件訪問數(shù)據(jù)庫中的數(shù)據(jù),然后把結(jié)果以 HTML 頁面的形式送回到客戶端。

ISAPI 的應(yīng)用程序被編譯為動(dòng)態(tài)鏈接庫( DLL, Dynamic Linked Library ),該庫在 WWW 服務(wù)( Service )啟動(dòng)時(shí)裝載入內(nèi)存。它要求較少的系統(tǒng)開銷,性能明顯優(yōu)于 CGI 應(yīng)用程序。因?yàn)槊總€(gè)請(qǐng)求并不啟動(dòng)單獨(dú)的進(jìn)程。而如用 CGI 作交互程序, 每個(gè)請(qǐng)求需要啟動(dòng)單獨(dú)的進(jìn)程。 ISAPI 有明顯的性能優(yōu)勢(shì),但其調(diào)試不方面,開發(fā)資料較少, 一直成為開發(fā)人員不優(yōu)選的原因。為了更廣泛地運(yùn)用 ISAPI ,特作此文,以供廣大開發(fā)者更快地進(jìn)入開發(fā)過程。

二、一個(gè)簡單的 ISAPI 程序

New,Object,ISAPI Extension Wizard,Object Name 就起個(gè) FirstISAPI,OK, 第二步什么也不要變,點(diǎn) Finshed 完成。按下 F7 把生成的 DLL 放到 C:inetpubwwwrootfirstisapi 目錄下 ( 建文件夾不用我教吧? ), 打開瀏覽器,在地址欄內(nèi)輸入

http://127.0.0.1/firstisapi/FirstISAPI.dll

OK, 我們立馬可以看到如下內(nèi)容: This default message was produced by the  Internet Server DLL Wizard. Edit your CFirstISAPIExtension::Default() implementation to change it.

你看到了嗎?

如果你看到了上面這一串英文字符,說明你的服務(wù)器可以用啦。

如果你看到了一個(gè)下載文件對(duì)話框,別哭!說明你的服務(wù)器還沒有配置好,下面由我來一步步教你,會(huì)用的朋友也別錯(cuò)過這個(gè)好機(jī)會(huì)!

開始,程序,管理工具, Internet 服務(wù)管理器,打開左邊樹,找到 默認(rèn) Web 站點(diǎn)下的 firstisapi, 把鼠標(biāo)入在上面單擊右鍵,屬性,在 執(zhí)行許可 里面下拉列表,選中 腳本和可執(zhí)行程序 其他什么也別動(dòng)(如果你覺得動(dòng)著好玩的話就動(dòng)吧, 不過服務(wù)器配置不好了可別怪我沒提前 聲明:) .

下面我們要做什么呢 ? 忘了 , 等等 ! , 對(duì)了 , 點(diǎn)擊 OK, 如果沒有呢 , 你的是中文版吧 , 那就點(diǎn)確定吧 !

好了 ,http://127.0.0.1/firstisapi/FirstISAPI.dll-->>>

This default message was produced by the Internet Server DLL Wizard. Edit

your CFirstISAPIExtension::Default() implementation to change it.

這回看到了吧 ?

還沒有 ?

算了 , 別學(xué) ISAPI , 多煩 , 你不煩我都煩了 , 臭機(jī)子 ! ( 想了想 , 這種可能還是有的 , 我還是為人為到底吧 , 免得你又罵娘了 , , 把開光驅(qū) , 2000 的盤放進(jìn)去啊 , 還愣著干么 ? 添加組件 , 重裝一遍你的 INTERNET 服務(wù) !......)

這回不會(huì)不行吧 ? 不行 ?

如此 , 我們的第一個(gè) ISAPI 就做成了 , 你可以放心的說 , 我會(huì)做 ISAPI ........---- ! 這也叫會(huì) ?

對(duì)了 , 忘了 WIN98 的朋友 , 對(duì)不起啊 , 你有沒有裝 PWS

沒有 ?

那裝一個(gè)吧 !

其他的和 2000 大同小異 , 不用我教吧 ?:):)

三、 ISAPI 實(shí)現(xiàn) 客戶 / 服務(wù)器 交互

我們現(xiàn)在已經(jīng)可以做一個(gè)簡單的 ISAPI 程序了,但是,它什么功能也沒有實(shí)現(xiàn), 畢竟我們還沒有加讓它動(dòng)起來的代碼嘛!

CFirstISAPIExtension 類里象做一般程序一樣加入一個(gè)成員函數(shù)

void Getdata(CHttpServerContext *pCtxt, char *data);

然后在 BEGIN_PARSE_MAP(CFirstISAPIExtension, CHttpServer)

END_PARSE_MAP(CFirstISAPIExtension) 之間加入

ON_PARSE_COMMAND(Getdata, CFirstISAPIExtension,ITS_PSTR)

ON_PARSE_COMMAND_PARAMS("data") ,如下所示:

BEGIN_PARSE_MAP(CFirstISAPIExtension, CHttpServer)

// TODO: insert your ON_PARSE_COMMAND() and

// ON_PARSE_COMMAND_PARAMS() here to hook up your commands.

// For example:

ON_PARSE_COMMAND(Getdata, CFirstISAPIExtension,ITS_PSTR)

ON_PARSE_COMMAND_PARAMS("data")

ON_PARSE_COMMAND(Default, CFirstISAPIExtension, ITS_EMPTY)

DEFAULT_PARSE_COMMAND(Default, CFirstISAPIExtension)

END_PARSE_MAP(CFirstISAPIExtension)

ON_PARSE_COMMAND ON_PARSE_COMMAND_PARAMS 是參數(shù)映射宏, ON_PARSE_COMMAND 的第

一個(gè)參數(shù) Getdata 是要處理事件的函數(shù)名,第二個(gè)參數(shù) CFirstISAPIExtension 為以 CHttpServer 為父類的應(yīng)用程序子類,后面的參數(shù)要傳給 Getdata 函數(shù)的參數(shù)列表,它們可以是: ITS_EMPTY 數(shù) 據(jù); ITS_PSTR 串; ITS_I2 short 型; ITS_I4 long 型; ITS_R4 float 點(diǎn) 數(shù); ITS_R8 double 點(diǎn) 數(shù)。 參數(shù)的個(gè)數(shù)一般與下面 ON_PARSE_COMMAND_PARAMS 解析的參數(shù)相對(duì)應(yīng)。我們?cè)谶@里可以 data 參數(shù)賦給一個(gè)初值,當(dāng)我們?cè)跒g覽器里沒有傳上來這個(gè)參數(shù)的實(shí)際數(shù)值時(shí)就是它了。如 data=www.ourcode.net; 這里 data 就是我們定義函數(shù) Getdata 里所要傳入的參數(shù)名。

有了上面這些準(zhǔn)備工作,下面我們就可以添加代碼了,因?yàn)樗推匠>幊虝r(shí)沒什么兩樣,因此我們就簡單地加上一點(diǎn)代碼看看我們勞動(dòng)了半天到底做了些什么?

如下:

void CFirstISAPIExtension::Getdata(CHttpServerContext *pCtxt, char *data)

{

StartContent(pCtxt);// HTML 文件頭

WriteTitle(pCtxt);// 寫標(biāo)題

*pCtxt << _T(" 這是你提交上來的數(shù)據(jù): rn");// 向?yàn)g覽器發(fā)送數(shù)據(jù)

*pCtxt <<data <<"rn";// 寫上一個(gè)換行和回車

EndContent(pCtxt)

}  

CHttpServerContext *pCtxt 是一個(gè)服務(wù)器上下文標(biāo)志, 我們向?yàn)g覽器傳輸數(shù)據(jù)就全靠

它。 *pCtxt << 后的字串就是瀏覽器里的 HTML 源碼,因此,你可以把 " 這是你提交上來的數(shù)據(jù):

rn" ,改成你想要的 HTML ,想怎么改隨你吧!:)

現(xiàn)在是不是要按下 F7 了?哈哈,好, F7 ,馬上把 FirstISAPI.dll   Ctrl+C,Ctrl+V........

" 無法創(chuàng)建或替換 FirstISAPI: 指定的文件正被 Windows 使用 " ,沒法了?我就重起計(jì)算機(jī)啦,誰教它裝入內(nèi)存呢!(其實(shí)只要重啟 IIS 或結(jié)束進(jìn)程 Win2003 w3wp.exe Win2000 aspnet_wp.exe

下面 ISAPI 調(diào)試的文章,不愛老重起計(jì)算機(jī)的朋友可以看一下。

ISAPI 在運(yùn)行時(shí)是 IIS 的一部分,而 IIS 又作為 NT 的一個(gè)服務(wù)而運(yùn)行。這一事實(shí)使用調(diào)試過程變得復(fù)雜了,因?yàn)樵?/span> IIS 運(yùn)行時(shí), VC++ 的調(diào)試器不能夠接管 ISA 。為了解決這個(gè)問 題,微軟公司以兩種形式發(fā)行了 IIS :作為一項(xiàng)服務(wù),以及作為一個(gè)單獨(dú)的可執(zhí)行程序。 對(duì)于后一種情況,我們就可以在命令行上來控制服務(wù)器。雖然這樣可以解決上述問題并使得開發(fā)過程變得容易一些,但實(shí)現(xiàn)起來顯得很繁瑣。下面我們來介紹這個(gè)過程。

當(dāng)用戶處于 debug 調(diào)試模式時(shí), VC++( 以及 IIS) 將在用戶的帳號(hào)和權(quán)限下運(yùn)行。由于通常 IIS 完成的一些工作是不允許大多數(shù)用戶有相應(yīng)的權(quán)限的,因此用戶(或用戶的系統(tǒng)管理員)需要做以下工作:

在桌面上選擇 開始程序管 理工具(公用)域用戶管理器 ”, 打開域用戶管理器;

規(guī)則 菜單中選擇 用戶 權(quán)限

選擇 顯示高級(jí)用戶權(quán)限 查框;

權(quán)限 下拉列表中選擇 以操作系統(tǒng)方式操作

選擇 添加 按鈕得到 添加 用戶及組 對(duì)話框,選擇 顯示用戶 按鈕,并在 列表中選擇用戶使用的帳號(hào),然后選擇 添加 按鈕;

選擇 確定 按鈕;

對(duì) 產(chǎn)生安全審核 權(quán)限重復(fù) 上述步驟。

為了使這些設(shè)置生效,用戶必 須先退出登錄,然后再登錄回來。

IIS 中包含了三項(xiàng)服務(wù): FTPPublishing Service,GopherPublishingService WorldWideWeb 。由于調(diào)試器要在命令行上運(yùn)行 IIS ,所以所有這三項(xiàng)服務(wù)都必須停止。 這可以通過 控制面板 中的 服務(wù) 程序或者使用 IIS “Internet 服務(wù)管理器 來實(shí)現(xiàn)。如果需要進(jìn)行大量的調(diào)試工作, 我們建議用戶通過 控制面板 中的 服務(wù) 程序來關(guān)閉 IIS 服務(wù)并禁止它們自動(dòng)啟動(dòng),這樣可以避免用戶每次啟動(dòng)計(jì)算機(jī)時(shí)都要進(jìn)行關(guān)閉服務(wù)的操作。

接下來就必須對(duì)工程進(jìn)行一些 配置了:

Project 菜單中選擇 Settings 菜單 項(xiàng);

選擇 Debug 面板,并在 Category 下拉 列表中選擇 General

Executablefordebugsession 框中輸入 或者尋找 IIS 執(zhí)行文件的路徑 (通常情況下位于 WINNTsystem32inetsrvinetinfo.exe );

Programarguments 框中輸入 -ew3svc ,如 3 所示;圖3  Debug 面板設(shè)置選擇 Link 面板;

Outputfilename 框中輸入被編譯 后的 DLL 將被放置的路徑和文件名。這個(gè)路徑必須位于 Web 服務(wù)器的根目錄下或者某個(gè)虛擬目標(biāo)下,以便客戶可 以通過 URL 來訪問。例如,我們的 Web 服務(wù)器的目錄是 c:InetPubwwwrootfirstisapi ,我們把 firstisapi.dll 放置在該目錄下,這樣客戶就可以使用 下面的 URL 來訪問它:

http://127.0.0.1/firstisapi/firstisapi.dll

如果用戶現(xiàn)在還沒有退出登錄 以改變權(quán)限,請(qǐng)現(xiàn)在行動(dòng),然后再登錄回來。

如此,我們的服務(wù)器 DLL 就大功告成啦,趕快在瀏覽器里輸入 http://127.0.0.1/firstisapi/firstisapi.dll?Getdata&data= 這是我發(fā)給服務(wù)器的信息!

OK

這是你提交上來的數(shù)據(jù):

這是我發(fā)給服務(wù)器的信息!

OK

要是我們想以 FORM 的表單形式向服務(wù)器提交數(shù)據(jù)呢?

把下面這段 HTML 源碼存為一個(gè) firstisapi.htm 文件,放在 DLL 相同目錄下。

<form method="post" action="firstisapi.dll?">

<p align="center">   </p>

<input type="hidden" name="MfcISAPICommand" VALUE="Getdata">

<p align="center"> 要提交的數(shù)據(jù): <input type="text" name="data" size="20"></p>

<p align="center"><input type="submit" value=" 提交 " > </p></form> </body>

四、 ISAPI 操作數(shù)據(jù)庫

上面我們定義了一個(gè) Getdata 函數(shù) , 在函數(shù)里我們實(shí)現(xiàn)了這樣一個(gè)功能 : 把客戶傳送上的數(shù)據(jù)發(fā)給客戶 . 要是操作數(shù)據(jù)庫呢 ? 一樣的道理 , 我們只要在自己定義的函數(shù)里添加上操作數(shù)據(jù)庫的代碼 , 就可以實(shí)現(xiàn)存取數(shù)據(jù)庫 . 輸入的數(shù)據(jù)在變量 data 里,輸出給客戶機(jī)用 *pCtxt 發(fā)給瀏覽器。

現(xiàn)在我們建立一個(gè)數(shù)據(jù)庫,用什么庫由你選取吧,可以是 ACCESS,SQL Server ,Sbase 等,我們只要用數(shù)據(jù)源來操作它就行了,我們?cè)诮ê脦旌蠼⑾到y(tǒng)數(shù)據(jù)源(不要建成用戶數(shù)據(jù)源啊?為什么?問比爾 . 蓋茨去吧) FirstODBC, 用下面的 SQL 建立一個(gè)簡單的表。

: 用戶資料

create table user_info (

id int (4) not null,

friend_id int(4) not null,

user_name varchar (30) not null,

user_sex varchar (2) not null,

address varchar (20),

age int (4),

zip char (6),

phone varchar (20) )

有了數(shù)據(jù)源,我們就可以添加代碼實(shí)現(xiàn)數(shù)據(jù)庫的查詢,修改等。同上一節(jié)一樣,在 CFirstISAPIExtension 里添加一個(gè)成員函數(shù)

void Reg(CHttpServerContext *pCtxt,char *user_name,char *sex,char*address,int age,

char*zip,char*phone)

參數(shù)分別是 : 用戶名 , 性別 , 地址 , 年齡 , 郵編和電話 . 我們要它實(shí)現(xiàn)的功能是把用戶通過表單提交的數(shù)據(jù)寫到 FirstODBC 數(shù)據(jù)庫 . 然后同樣在

BEGIN_PARSE_MAP(CFirstISAPIExtension, CHttpServer)

END_PARSE_MAP(CFirstISAPIExtension) 之間加入

ON_PARSE_COMMAND(Reg, CFirstISAPIExtension,

ITS_PSTR ITS_PSTR ITS_PSTR ITS_I2 ITS_PSTR ITS_PSTR)

ON_PARSE_COMMAND_PARAMS("user_name sex address='' age=20 zip='' phone='')

,如下所示:

BEGIN_PARSE_MAP(CFirstISAPIExtension, CHttpServer)

// TODO: insert your ON_PARSE_COMMAND() and

// ON_PARSE_COMMAND_PARAMS() here to hook up your commands.

// For example:

ON_PARSE_COMMAND(Reg, CFirstISAPIExtension,ITS_PSTR ITS_PSTR ITS_PSTR ITS_I2 I

ITS_PSTR ITS_PSTR)

ON_PARSE_COMMAND_PARAMS("user_name sex address age zip phone)

ON_PARSE_COMMAND(Getdata, CFirstISAPIExtension,ITS_PSTR)

ON_PARSE_COMMAND_PARAMS("data")

ON_PARSE_COMMAND(Default, CFirstISAPIExtension, ITS_EMPTY)

DEFAULT_PARSE_COMMAND(Default, CFirstISAPIExtension)

END_PARSE_MAP(CFirstISAPIExtension)

下面我們定義自己的函數(shù)并進(jìn)行數(shù)據(jù)庫的操作 , 單擊左邊 FirstISAPI classes,New Class,

Name:CUserSet,Base class:CRecordset---------------OK,ODBC:FirstODBC,

Table Name:user_info,OK.

( 請(qǐng)先看看 stdafx.h 里有沒有 #include )

void Reg(CHttpServerContext *pCtxt,char *user_name,char *sex,char*address,

int age,char*zip,char*phone)

{// 打開數(shù)據(jù)庫源代碼

StartContent(pCtxt); // 打印 <HTML> <BODY> 標(biāo)記

WriteTitle(pCtxt); // 打印 <TITLE> 標(biāo)題內(nèi)容 </TITLE> 標(biāo)記等

CDatabase db;

if(!db.Open(_T("FirstODBC"), // (系統(tǒng)源名)

FALSE, //bExclusive

FALSE, //bReadOnly

_T("ODBC; UID=sa; PWD=;"), //lpszConnect (與數(shù)據(jù)庫的連接方式)

FALSE))

{ //bUseCursorLib

*pCtxt << "Could not open database.";

return;

}

CRecordset set(&db);

try

{

set.Open();

}

catch (CDBException* pEx)

{

*pCtxt << _T("Error Selecting from table:");

TCHAR szErrorMessage[1024];

if (pEx->GetErrorMessage(szErrorMessage, sizeof(szErrorMessage)))

{

*pCtxt << szErrorMessage;

*pCtxt << _T("rn");

}

return;

}

set.AddNew();

set.Edit();

set.m_id=0;

set.m_user_name=user_name;

set.m_sex=sex;

set.m_address=address;

set.m_age=age;

set.m_zip=zip;

set.m_phone=phone;

set.Update();

set.Close();

db.Close();

*pCtxt << _T(" 你已成功注冊(cè) !rn");

// 打印 </BODY> </HTML> 標(biāo)記

EndContent(pCtxt);

}

把下面的 HTML 存為 reg.htm

<HTML>

<BODY>

<CENTER>

<FONT COLOR='#FF0000'><H3> 請(qǐng)?jiān)谙旅孑斎肽愕淖?cè)信息 ( * 的為必填內(nèi)容 )</H3>

</FONT>

</CENTER>

<HR>

<CENTER>

<form method="post" action="firstisapi.dll?">

<p align="center">   </p>

<input type="hidden" name="MfcISAPICommand" VALUE="Reg">

<p align="center"> 姓名: <input type="text" name="user_name" size="20"></p>

<p align="center"> 性別:

<select name="sex" size="1">

<option selected value="1"> </option>

<option value="0"> </option>

</select></p>

<p align="center"> 地址: <input type="text" name="address" size="20"></p>

<p align="center"> 年齡: <input type="text" name="age" size="20"></p>

<p align="center"> 郵編: <input type="text" name="zip" size="20"></p>

<p align="center"> 電話: <input type="text" name="phone" size="20"></p>

<p align="center"><input type="submit" value=" 提交 " > </p></form>

</center>

</BODY>

</HTML>

然后放到 firstisapi 目錄里 ,..................

http://127.0.0.1/firstisapi/reg.htm 這樣在瀏覽器的表單里輸入你的數(shù)據(jù)后提交 , 看看你我服務(wù)器數(shù)據(jù)庫 , , 有了 -----------> 你已成功注冊(cè) !! 本想再做一個(gè)查詢程序 , 可是時(shí)間太緊 , 還是自己想想吧 , 和注冊(cè)程序沒什么兩樣 , 只要再加一個(gè) Chaxun(...) OK That is all right! 程序還有一些不完美的地方就是還不能檢驗(yàn)用戶名是否已被注冊(cè),還沒有到得 ID 的最大值,不過在此只是為了演示如何操作數(shù)據(jù)庫,筆者因此沒有深慮,有興趣的朋友自己可以加上這方面的代碼。

五、利用 ISAPI 進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)傳送

所謂網(wǎng)絡(luò)數(shù)據(jù)傳送 , 簡單地說 , 就是把數(shù)據(jù)從一臺(tái)計(jì)算機(jī)傳輸?shù)骄W(wǎng)絡(luò)上的另外一臺(tái)計(jì)算機(jī) . 說起數(shù)據(jù)傳輸 , 大家最熟的不過 socket 套接字了 , 無論在 UNIX,WINDOWS, 它一貫都是公認(rèn)的傳輸方案 . 筆者在研究了 ISAPI 之后 , 成功地實(shí)現(xiàn)了用 ISAPI 進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)傳輸 , 并且解決了局域網(wǎng)防火墻內(nèi)數(shù)據(jù)的有效傳輸 .

首先 , 我們要建立服務(wù)器數(shù)據(jù)接收 ISAPI 程序 . 在第三節(jié) <ISAPI 實(shí)現(xiàn) 客戶 / 服務(wù)器 交互 > 里我們已經(jīng)建立了一個(gè) Getdata(..char *data) 函數(shù) , 其中 data 里存放的就是我們從客戶機(jī)傳上來的數(shù)據(jù) , 在這個(gè)函數(shù)里 , 我們就可以對(duì)它進(jìn)行處理 , 如寫文件 , 寫數(shù)據(jù)庫等 , 再通過 *pCtxt 向客戶發(fā)送回執(zhí) . 關(guān)于如何寫庫寫文件已超出本節(jié)范圍 , 在此不再贅述。

在第三節(jié)里,我們是通過 FORM 表單通過瀏覽器把數(shù)據(jù)發(fā)送給服務(wù)器,在這里,我們要通過我們客戶機(jī)的程序向服務(wù)器發(fā)送數(shù)據(jù)。在你的程序里添加一個(gè)成員函數(shù):

BOOL SendData(char *ip,char *request, char *buffer, unsigned int bufferlen)

其中參數(shù) ip 為服務(wù)器 IP 地址,如果是本機(jī)調(diào),傳入 127.0.0.1;request 為要發(fā)送到服務(wù)器的數(shù)據(jù),最終由 Getdata ()接收,存放在 data 里供服務(wù)器處理程序處理 ;buffer 為服務(wù)器傳回回執(zhí)存放綬沖區(qū),即 *pCtxt 串行回的數(shù)據(jù) bufferlen buffer 綬沖區(qū)長度。 SendData 代碼如下:

BOOL SendData(char *ip,char *request, char *buffer, unsigned int bufferlen)

{

int ret=0;

CString URL;

URL="http://";

URL+=(CString)ip;

URL+="/firstisapi/firstisapi.dll?Getdata&data=";

URL+=(CString)request;

//

//AfxMessageBox(URL);

CInternetSession session;

CInternetFile *cf;

//----------------

try

{

cf = (CInternetFile * )session.OpenURL (URL);

}

catch (CInternetException * Exp)

{

char err[1024];

Exp->GetErrorMessage (err, 1024, NULL);

AfxMessageBox(err);

cf = NULL;

Exp->Delete ();

}

if (cf)

{

ret=cf->Read(buffer, bufferlen);

cf->Close ();

}

session.Close ();

return(ret);

}

這樣我們?cè)诔绦蚶锟梢赃@樣調(diào)用它:

void CSassDlg::OnButton1()

{

// TODO: Add your control notification handler code here

CString ip="127.0.0.1",data=" 這是我要發(fā)給服務(wù)器的數(shù)據(jù) ",buffer;

BOOL b=SendData((char *)LPCTSTR(ip),(char *)LPCTSTR(data),

buffer.GetBuffer(1204), 1024);

if(b)

{

MessageBox(" 數(shù)據(jù)發(fā)送成功 ");

}

}

這樣,我們只要把要發(fā)送給服務(wù)器的數(shù)據(jù)傳給 SendData 的第二個(gè)參數(shù),服務(wù)器 data 就可收到,你想怎么處理就怎么處理吧。

六、 ISAPI 傳輸數(shù)據(jù)的加密

為了提高數(shù)據(jù)傳的安全性,可靠性,我們?cè)跀?shù)據(jù)傳輸之前都要對(duì)數(shù)據(jù)進(jìn)行加密,但是無論哪種加密算法,進(jìn)行加密的數(shù)據(jù)都有可能出現(xiàn)諸如 "@#$%^&*-+" 及不可字符,可是用 ISAPI 這種方法傳輸時(shí), 服務(wù)器經(jīng)過 ON_PARSE_COMMAND ON_PARSE_COMMAND_PARAMS 參數(shù)映射宏進(jìn)行處理后,如 "%,&" 等字符將會(huì)進(jìn)行自動(dòng)轉(zhuǎn)換或作為分隔字符處理 , 這樣, 服務(wù)器收到的數(shù)據(jù)將會(huì)是錯(cuò)誤的。為了保證數(shù)據(jù)傳輸?shù)目煽啃裕P者經(jīng)過多方面研究,自己定義了下面兩個(gè)函數(shù),分別作為客戶機(jī)加密后上傳前數(shù)據(jù)處理和服務(wù)器接收到數(shù)據(jù)后解密前處理。客戶機(jī)加密后上傳前數(shù)據(jù)處理函數(shù):

void code(char *buf, int len, char *outstr)// 加密后處理

{

CString str;

int outstr_len;

outstr_len=0;

char *tmp;

tmp=new char[16];

outstr[0]=0;

for (int i=0; i<len ;i++)

{

tmp[0]=0;

if(buf[i]=='%'||buf[i]=='&'||

buf[i]=='!'||buf[i]=='?'||

buf[i]=='+'||buf[i]==''||

buf[i]=='/')

{

str.Format("%%%x",buf[i]);

strcpy(tmp,str);

outstr_len+=3;

}

else

{

tmp[0]=buf[i];

tmp[1]=0;

outstr_len++;

}

if (buf[i]=='$')

{

strcpy(tmp,"$$");outstr_len+=2;}

if (buf[i]==0)

{

strcpy(tmp,"$0");outstr_len+=2;

}

strcat(outstr,tmp);

}

return;

}

其中 buf 為傳入數(shù)據(jù)綬沖區(qū)指針, len buf 數(shù)據(jù)長度, outbuf 為處理后數(shù)據(jù)存放綬沖區(qū) . 處理時(shí)將諸如 "%,&,+" 等特殊字符及 0 字符進(jìn)行處理,這樣, 數(shù)據(jù)傳送到服務(wù)器后將會(huì)是正確的,之后經(jīng)過服務(wù)器處理函數(shù)進(jìn)行還原,再解密,那我們的數(shù)據(jù)就不會(huì)有錯(cuò)了。

服務(wù)器接收到數(shù)據(jù)后解密前處理函數(shù):

int decode(char *buff, int len, char *outstr)

// 上傳后處理

{

int i, p;

char v;

p=0;

for (i=0; i<len; i++)

{

if (buff[i]=='$')

{

if (buff[i+1]=='$')

{

v='$';

}

else

{

if(buff[i+1]=='0')

v=0;

}

i++;

}

else

{

v = buff[i];

}

outstr[p]=v;

p++;

}

return(p);

}

其中 buff 為傳入數(shù)據(jù)綬沖區(qū)指針, len buff 數(shù)據(jù)長度, outstr 為處理后數(shù)據(jù)存放綬沖區(qū) .

處理流程:對(duì) Data 進(jìn)行加密 -->code 函數(shù)進(jìn)行處理 --> 服務(wù)器接到 data-- >decode 進(jìn)行上傳后處理 --> 解密

七、 ISAPI 網(wǎng)絡(luò)數(shù)據(jù)傳送進(jìn)階(網(wǎng)絡(luò)大數(shù)據(jù)包傳送)

筆者曾嘗試用上述方法傳輸大數(shù)據(jù)包,可是發(fā)現(xiàn)這種方法只可傳輸小于 2K 的數(shù)據(jù)包,這無疑成為它一個(gè)缺點(diǎn)。經(jīng)過多方面的研究,發(fā)現(xiàn)這種方法是用 GET 方法發(fā)送數(shù)據(jù), 操作系統(tǒng)本身就限制了它的數(shù)據(jù)量。以后經(jīng)過測(cè)試,如用 POST 方法傳輸,發(fā)送數(shù)據(jù)包的大小將不受限制。下節(jié)將講解如何用 POST 方法向服務(wù)器發(fā)送數(shù)據(jù)。

BOOL PostData(char *ip,char *request,char *out_buf,int buf_len)

{

BOOL ret=FALSE;

char *buffer,*buff,*out;

buffer=new char[2048];

int bb_len=strlen(request);

buff=new char[bb_len];

out=new char[bb_len+1000];

CInternetSession session;

CHttpFile* pFile=NULL;

CHttpConnection* pConnection=NULL;

CString m_ip,sql;

m_ip=(CString)ip;

//---------------------------- 對(duì) request 加密

strcpy(buff,request);

for(int i=0;i<bb_len;i++)//

buff[i]=buff[i]^(char)((i+0x56)%255);

code (buff,bb_len,out);// 上傳前處理

//-----------------------------------

sql=(CString)out;

CString strHeaders =_T("Content-Type: application/x-www-form-urlencoded");

CString str,strFormData = _T("data=");

strFormData+=sql;

try

{

pConnection =

session.GetHttpConnection(m_ip);

pFile =

pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST,

_T("/firstisapi/firstisapi.dll?Getdata"));

BOOL result = pFile->SendRequest(strHeaders,

(LPVOID)(LPCTSTR)strFormData, strFormData.GetLength());

DWORD dwRet;

pFile->QueryInfoStatusCode(dwRet);

//--------------

if (dwRet == HTTP_STATUS_OK)

{

buf_len=pFile->Read(buffer,2048);

str=(CString)buffer;

str=str.Left(buf_len);

ret=TRUE;

}

else

str=" 服務(wù)器處理錯(cuò)誤! ";

pFile->Close ();

delete pFile;

pConnection->Close();

delete pConnection;

}

catch(CInternetException* pEx)

{

TCHAR szErr[1024];

pEx->GetErrorMessage(szErr, 1024);

str=szErr;

pEx->Delete();

}

catch (...)

{

str=" 和服務(wù)器通信時(shí)發(fā)生意外! ";

}

session.Close();

strcpy(out_buf,str);

buf_len=str.GetLength ();

MessageBox(NULL, str, " 系統(tǒng)提示 ", MB_OK);

delete buffer;

delete buff;

delete out;

return ret;

}

其中參數(shù) ip 為服務(wù)器 IP 地址,如果是本機(jī)調(diào),傳入 127.0.0.1; request 為要發(fā)送到服務(wù)器的數(shù)據(jù),最終由 Getdata ()接收,存放在 data 里供服務(wù)器處理程序處理 ;buffer 為服務(wù)器傳回回執(zhí)存放綬沖區(qū),即 *pCtxt 串行回的數(shù)據(jù) bufferlen buffer 綬沖區(qū)長度。服務(wù)器接收程序同前,這樣,我們就可以發(fā)送大于 2K 的數(shù)據(jù)了。

 

posted on 2006-05-31 17:43 思勤無邪 閱讀(4665) 評(píng)論(12)  編輯 收藏 引用 所屬分類: C++其他與技術(shù)相關(guān)

Feedback

# 很不錯(cuò)的東西 2006-09-12 16:38 @read
雖然簡單但是實(shí)用,  回復(fù)  更多評(píng)論
  

# re: 整理的一些ISAPI編程基礎(chǔ) 2007-03-06 14:21 CUNSHAN
謝謝  回復(fù)  更多評(píng)論
  

# re: 整理的一些ISAPI編程基礎(chǔ) 2007-06-08 10:59 niunv
我想請(qǐng)問一下,我在調(diào)試注冊(cè)那一段的時(shí)候,提交注冊(cè)運(yùn)行到添加記錄這部分時(shí)一直沒有反應(yīng),再刷新提交就提示

服務(wù)器錯(cuò)誤
服務(wù)器遇到內(nèi)部錯(cuò)誤或錯(cuò)誤配置無法完成該請(qǐng)求.

如果把這段代碼去掉,則運(yùn)行是正常的..加上以后就不行了,請(qǐng)問這個(gè)要怎么解決呢.我的表是把id設(shè)置為自增的,所以我有改過CUserSet,去掉了ID字段.
set.AddNew();

set.Edit();

set.m_user_name=user_name;

set.m_user_sex=sex;

set.m_address=address;

set.m_age=age;

set.m_zip=zip;

set.m_phone=phone;

set.Update();   回復(fù)  更多評(píng)論
  

# re: 整理的一些ISAPI編程基礎(chǔ) 2007-06-08 11:48 niunv
我的問題已解決,我修改初始化時(shí)m_nDefaultType = dynaset;就可以更新了.之前我沒有在AddNew的地方進(jìn)行try調(diào)試,就顯示
服務(wù)器錯(cuò)誤
服務(wù)器遇到內(nèi)部錯(cuò)誤或錯(cuò)誤配置無法完成該請(qǐng)求.
這樣,加了調(diào)試以后就提示記錄集為只讀,查了一下MSDN修改m_nDefaultType 就好了.還有,set.Edit();這句我刪除了..
初學(xué),讓你笑話了,請(qǐng)多見指點(diǎn)!謝謝你提供這么好的例子,讓我一下子在腦子里有了比較實(shí)際的概念,前段時(shí)間看的一些教程什么的,總是看不懂是怎么回事,你的這篇文章讓我覺得講得通欲易懂,又能理解ISAPI編程的思想.謝謝!!  回復(fù)  更多評(píng)論
  

# re: 整理的一些ISAPI編程基礎(chǔ) 2007-06-08 11:59 niunv
是通俗易懂,打錯(cuò)字了,..
還有個(gè)問題想請(qǐng)教一下,就是CDatabase.ExecuteSQL()直接執(zhí)行insert的話要好一點(diǎn)嗎?你能講講為什么這里要通過AddNew()來添加呢?是因?yàn)榕缮惱锏腄oFieldExchange嗎?  回復(fù)  更多評(píng)論
  

# re: 整理的一些ISAPI編程基礎(chǔ) 2008-04-06 17:54 jevinss
D:\Program Files\Microsoft Visual Studio\MyProjects\Pisapi\Pisapi.cpp(183) : error C2039: 'm_user_name' : is not a member of 'CRecordset'
d:\program files\microsoft visual studio\vc98\mfc\include\afxdb.h(564) : see declaration of 'CRecordset'
D:\Program Files\Microsoft Visual Studio\MyProjects\Pisapi\Pisapi.cpp(185) : error C2039: 'm_sex' : is not a member of 'CRecordset'
d:\program files\microsoft visual studio\vc98\mfc\include\afxdb.h(564) : see declaration of 'CRecordset'
D:\Program Files\Microsoft Visual Studio\MyProjects\Pisapi\Pisapi.cpp(187) : error C2039: 'm_address' : is not a member of 'CRecordset'
d:\program files\microsoft visual studio\vc98\mfc\include\afxdb.h(564) : see declaration of 'CRecordset'
D:\Program Files\Microsoft Visual Studio\MyProjects\Pisapi\Pisapi.cpp(189) : error C2039: 'm_age' : is not a member of 'CRecordset'
d:\program files\microsoft visual studio\vc98\mfc\include\afxdb.h(564) : see declaration of 'CRecordset'
D:\Program Files\Microsoft Visual Studio\MyProjects\Pisapi\Pisapi.cpp(191) : error C2039: 'm_zip' : is not a member of 'CRecordset'
d:\program files\microsoft visual studio\vc98\mfc\include\afxdb.h(564) : see declaration of 'CRecordset'
D:\Program Files\Microsoft Visual Studio\MyProjects\Pisapi\Pisapi.cpp(193) : error C2039: 'm_phone' : is not a member of 'CRecordset'
d:\program files\microsoft visual studio\vc98\mfc\include\afxdb.h(564) : see declaration of 'CRecordset'
Error executing cl.exe.
Creating browse info file...

Pisapi.dll - 6 error(s), 0 warning(s)


這是什么原因?老是通不過?  回復(fù)  更多評(píng)論
  

# re: 整理的一些ISAPI編程基礎(chǔ) 2008-04-06 22:10 超人
你沒有把'm_user_name' 、'm_sex' 、'm_address' 、'm_age' 、'm_zip' 、'm_phone' 設(shè)置成為CRecordset' 的成員啊?你看一看它們放到哪里去了吧@jevinss
  回復(fù)  更多評(píng)論
  

# re: 整理的一些ISAPI編程基礎(chǔ) 2008-04-15 18:43 jevinss
服務(wù)器遇到內(nèi)部錯(cuò)誤或錯(cuò)誤配置無法完成該請(qǐng)求. 還是不行啊,,誰來幫幫我???...  回復(fù)  更多評(píng)論
  

# re: 整理的一些ISAPI編程基礎(chǔ) 2008-04-16 11:15 jevinss
我的IIS是裝在另外一臺(tái)機(jī)子上,是不是ODBC在別的機(jī)子上就不能連接啊?  回復(fù)  更多評(píng)論
  

# re: 整理的一些ISAPI編程基礎(chǔ) 2008-04-17 21:37 hexing
我快要瘋了,弄了兩天,一直都是內(nèi)部錯(cuò)誤....反正就是加不到到數(shù)據(jù)庫里面去,跪求高手幫我一下啊!!  回復(fù)  更多評(píng)論
  

# re: 整理的一些ISAPI編程基礎(chǔ) 2008-04-19 15:27 tign

ISAPI技術(shù)群


QQ群號(hào):60328982   回復(fù)  更多評(píng)論
  

# re: 整理的一些ISAPI編程基礎(chǔ) 2008-04-30 19:07 qqqqqqqqqq
我想請(qǐng)問一下,ISAPI中如何利用 catch ()來輸出異常啊?  回復(fù)  更多評(píng)論
  

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美一区1区三区3区公司| 久久中文字幕一区| 国内成人精品视频| 欧美国产日韩二区| 欧美激情在线观看| 亚洲一区中文| 欧美一区不卡| 亚洲欧洲精品一区二区| 亚洲精品在线观| 国产精品一区二区你懂得| 麻豆精品视频在线观看视频| 免费日韩成人| 亚洲——在线| 久久国产精品久久w女人spa| 亚洲精品网站在线播放gif| 欧美chengren| 欧美日本亚洲| 久久精品国产清高在天天线| 另类尿喷潮videofree| 在线亚洲欧美视频| 欧美一激情一区二区三区| 亚洲国产精品尤物yw在线观看| 亚洲免费观看| 国产专区一区| 最新日韩在线| 国产日韩欧美一区二区三区四区 | 欧美激情一区二区三区在线 | 久久久久久网| 欧美精品成人一区二区在线观看| 午夜国产精品视频免费体验区| 久久久久国产一区二区三区四区 | 亚洲欧美日韩在线一区| 久久精品日产第一区二区三区| 日韩网站在线| 午夜久久一区| av不卡在线看| 欧美一区亚洲| 亚洲神马久久| 蜜桃久久av一区| 午夜老司机精品| 欧美电影电视剧在线观看| 欧美一区二区在线免费播放| 欧美成人在线免费观看| 久久久国产精品一区二区三区| 欧美精品电影| 免费视频久久| 国产精品毛片va一区二区三区| 欧美成人黑人xx视频免费观看| 国产精品美女在线| 亚洲国产精品福利| 国内外成人免费激情在线视频网站| 亚洲精品女av网站| 国产性猛交xxxx免费看久久| 亚洲美女视频| 亚洲国产你懂的| 欧美一区二区在线播放| 亚洲午夜一二三区视频| 欧美+亚洲+精品+三区| 久久久噜噜噜久久| 国产精品卡一卡二卡三| 亚洲国产小视频在线观看| 精品av久久707| 亚洲欧美激情精品一区二区| 夜色激情一区二区| 可以看av的网站久久看| 久久久久久久一区| 国产精品女同互慰在线看| 亚洲麻豆国产自偷在线| 亚洲黄色影片| 久久久青草婷婷精品综合日韩 | 国产精品九色蝌蚪自拍| 亚洲欧洲日韩在线| 亚洲二区精品| 久久狠狠久久综合桃花| 欧美一区二区精美| 国产精品多人| 日韩一二三在线视频播| 99xxxx成人网| 欧美国产精品久久| 欧美成人精品影院| 精品91在线| 久久国产66| 久久精品一区二区| 国产欧美日本一区二区三区| 亚洲视频一区二区| 亚洲欧美国产日韩天堂区| 欧美午夜久久久| 日韩视频精品在线| 一级日韩一区在线观看| 欧美激情免费在线| 亚洲激情偷拍| 日韩图片一区| 欧美美女视频| 亚洲巨乳在线| 一区二区欧美在线| 欧美日韩性视频在线| 亚洲精品日韩在线| 在线一区视频| 国产精品h在线观看| 9l视频自拍蝌蚪9l视频成人| 一区二区三区欧美激情| 欧美日韩小视频| 亚洲视频在线一区| 欧美一区二区免费视频| 国产日产欧产精品推荐色 | 伊人久久亚洲美女图片| 久久国产欧美| 免费日韩成人| 最新国产乱人伦偷精品免费网站| 免费视频一区| 亚洲人成久久| 在线亚洲免费视频| 国产精品美女久久久浪潮软件| 亚洲夜间福利| 欧美一区观看| 国内精品久久久久影院薰衣草| 久久国产精彩视频| 欧美成人在线影院| 亚洲美女黄色| 欧美性猛片xxxx免费看久爱| 亚洲一区二三| 久久五月激情| 亚洲欧洲视频在线| 欧美日韩国产成人在线免费 | ●精品国产综合乱码久久久久 | 欧美二区视频| 日韩小视频在线观看专区| 欧美日韩在线观看视频| 午夜国产一区| 美女爽到呻吟久久久久| 亚洲精品你懂的| 欧美午夜精品理论片a级按摩| 亚洲伊人第一页| 久久在线播放| 亚洲免费观看在线视频| 国产精品大全| 久久精品国产精品亚洲| 亚洲第一在线综合在线| 亚洲女人天堂av| 黄页网站一区| 欧美紧缚bdsm在线视频| 亚洲一区二区免费看| 久热精品视频在线| 日韩系列在线| 国产情侣久久| 美女被久久久| 亚洲网站啪啪| 榴莲视频成人在线观看| 一区二区三区高清| 国产亚洲精品一区二555| 亚洲午夜一区二区三区| 久久午夜电影| 亚洲天堂男人| 好看不卡的中文字幕| 欧美精品手机在线| 欧美亚洲综合久久| 亚洲国产免费| 欧美中文字幕在线| 亚洲精品在线观| 国产精品综合| 欧美成人午夜剧场免费观看| 亚洲一区免费视频| 亚洲成人在线免费| 欧美一区二区免费观在线| 欧美国产亚洲另类动漫| 午夜在线精品偷拍| 亚洲日本中文| 国产日韩精品一区二区三区| 欧美成人久久| 久久不射电影网| 一区二区欧美精品| 欧美成人一区在线| 欧美一区在线看| 99re热这里只有精品视频| 国产自产女人91一区在线观看| 欧美人妖在线观看| 久久久夜色精品亚洲| 亚洲一二三区在线| 亚洲国产精品一区在线观看不卡| 欧美中文在线免费| 一区二区三区久久网| 亚洲大胆人体视频| 国产精品视频专区| 欧美日韩精品在线播放| 久久亚洲综合| 亚洲一卡二卡三卡四卡五卡| 亚洲国产裸拍裸体视频在线观看乱了中文 | 国产丝袜一区二区| 国产精品第13页| 欧美人与性动交α欧美精品济南到| 久久国内精品自在自线400部| 一区二区三区精品国产| 亚洲国产欧美日韩精品| 可以免费看不卡的av网站| 午夜在线一区| 亚洲男人的天堂在线aⅴ视频| 亚洲美女av黄| 91久久精品一区| 伊人精品视频| 国产有码在线一区二区视频|