遠(yuǎn)程程序運(yùn)行狀態(tài)的容易監(jiān)控
發(fā)表時(shí)間:2023-07-22 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]民航中南空管局氣象中心數(shù)據(jù)庫(kù)室 歐壯杰 我們知道,在unix操作系統(tǒng)中,遠(yuǎn)程主機(jī)命令行程序的運(yùn)行和進(jìn)程的關(guān)閉可通過(guò)telnet來(lái)實(shí)現(xiàn),當(dāng)客戶機(jī)裝有x-windows時(shí),可以運(yùn)行遠(yuǎn)程主機(jī)圖形界面的程序...
民航中南空管局氣象中心數(shù)據(jù)庫(kù)室 歐壯杰
我們知道,在unix操作系統(tǒng)中,遠(yuǎn)程主機(jī)命令行程序的運(yùn)行和進(jìn)程的關(guān)閉可通過(guò)telnet來(lái)實(shí)現(xiàn),當(dāng)客戶機(jī)裝有x-windows時(shí),可以運(yùn)行遠(yuǎn)程主機(jī)圖形界面的程序且界面顯示在客戶機(jī)上,相當(dāng)于延長(zhǎng)了遠(yuǎn)程主機(jī)顯示屏的距離。但windows產(chǎn)品在windows2000以前只有一個(gè)叫“八爪魚”的不成熟第三方產(chǎn)品可實(shí)現(xiàn)該功能。隨著windows2000的發(fā)布,終端服務(wù)功能成為windows2000的一個(gè)亮點(diǎn),只要在服務(wù)器端和客戶端安裝上相應(yīng)的程序,就可以實(shí)現(xiàn)遠(yuǎn)程桌面的功能。但是對(duì)于要實(shí)時(shí)監(jiān)控通過(guò)慢速的DDN專線連接的遠(yuǎn)程主機(jī)上的程序,則終端服務(wù)占用了太多的帶寬。因此,我們采用自己編程序的方法,用較少的傳輸量就可以實(shí)時(shí)監(jiān)控遠(yuǎn)程主機(jī)的程序。
我們的設(shè)計(jì)方法是:在服務(wù)器端運(yùn)行一個(gè)實(shí)時(shí)進(jìn)程監(jiān)控程序,定時(shí)讀取服務(wù)器進(jìn)程的運(yùn)行情況;在客戶端運(yùn)行一個(gè)終端程序,通過(guò)服務(wù)器端的進(jìn)程監(jiān)控程序把服務(wù)器的進(jìn)程運(yùn)行情況在終端顯示出來(lái),并可在終端發(fā)送指令指示服務(wù)器啟動(dòng)和停止特定的進(jìn)程,甚至重啟遠(yuǎn)程主機(jī)。
1、服務(wù)器端進(jìn)程監(jiān)控程序
在windows2000 和windows 95以上的版本中,Microsoft 提供了一套工具幫助函數(shù)(Tool Help),該套函數(shù)用于獲得當(dāng)前系統(tǒng)中運(yùn)行的進(jìn)程、堆、模塊及進(jìn)程使用的線程的快照集。在windows nt 4.0中是沒有提供。但我們現(xiàn)在的遠(yuǎn)程主機(jī)都是安裝了windows 2000,因此可在上面運(yùn)行該套函數(shù),下面是例子(采用delphi 語(yǔ)言):
procedure TForm1.Button1Click(Sender: TObject);
var i : integer;
ContinueLoop:BOOL;
FSnapshotHandle:THandle;
FProcessEntry32:TProcessEntry32;
begin
FSnapshotHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
FProcessEntry32.dwSize:=Sizeof(FProcessEntry32); file://指定結(jié)構(gòu)的大小
ContinueLoop:=Process32First(FSnapshotHandle,FProcessEntry32);
while integer(ContinueLoop)<>0 do
begin
Demo1.Lines.Add(inttostr(FProcessEntry32.th32ProcessID)+
':'+FProcessEntry32.szExeFile);
ContinueLoop:=Process32Next(FSnapshotHandle,FProcessEntry32);
end;
CloseHandle (FSnapshotHandle);
end;
程序中首先調(diào)用CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0)函數(shù)來(lái)獲得當(dāng)前進(jìn)程快照集的打開句柄。
TProcessEntry32是一個(gè)進(jìn)程入口結(jié)構(gòu),它用于存儲(chǔ)所掃描到的進(jìn)程信息,如進(jìn)程號(hào)、進(jìn)程可執(zhí)行文件名字等。第二步就是調(diào)用Process32First(FSnapshotHandle,FProcessEntry32)函數(shù)來(lái)尋找第一個(gè)進(jìn)程,當(dāng)返回值ContinueLoop為True時(shí)說(shuō)明已找到進(jìn)程;而Process32Next(FSnapshotHandle,FProcessEntry32)用于取得記錄在系統(tǒng)快照集里的下一個(gè)進(jìn)程信息。當(dāng)返回值為False為說(shuō)明列舉已完成。TProcessEntry32結(jié)構(gòu)的th32ProcessID屬性記錄了當(dāng)前進(jìn)程的進(jìn)程號(hào);szExeFile屬性記錄了當(dāng)前進(jìn)程的可執(zhí)行文件名字;獲得每一進(jìn)程的這兩個(gè)信息,就可以知當(dāng)前系統(tǒng)的進(jìn)程運(yùn)行情況。
當(dāng)客戶端軟件提出瀏覽遠(yuǎn)端進(jìn)程要求時(shí),服務(wù)器端可運(yùn)行該段程序并把獲得的信息發(fā)給客戶端。
再有,在windows2000下,可執(zhí)行GetProcessTimes函數(shù)來(lái)獲得該進(jìn)程以內(nèi)核模式已經(jīng)執(zhí)行的時(shí)間和以用戶模式已經(jīng)執(zhí)行的時(shí)間,這樣我們就可大概了解該進(jìn)程對(duì)CPU的占用情況。以便及時(shí)采取相應(yīng)的措施。
當(dāng)獲得服務(wù)器端進(jìn)程后,我們?cè)诳蛻舳丝砂l(fā)出指令,讓服務(wù)器端程序終止某一進(jìn)程或啟動(dòng)某一程序,用TerminateProcess函數(shù)可結(jié)束指定的進(jìn)程及其所擁有的線程,該函數(shù)使得一個(gè)進(jìn)程中的所有線程都終止,且引起該進(jìn)程退出,但進(jìn)程終止的消息不通知給附加的動(dòng)態(tài)連接庫(kù)DLL,因此使用該函數(shù)不能太頻繁。
我們還可以在服務(wù)器端截取屏幕,并把屏幕存為jpg格式圖像后以數(shù)據(jù)流的方式發(fā)送給客戶端。
另外,為了監(jiān)控服務(wù)器上的進(jìn)程所占用的內(nèi)存資源,我們可利用 GetProcessMemoryInfo函數(shù)來(lái)獲得當(dāng)前進(jìn)程所占用內(nèi)存的大小,例子如下:
procedure TForm1.Button1Click(Sender: TObject);
var hd:HWND;
dw:Dword;
PMC: PPROCESS_MEMORY_COUNTERS;
begin
dw:=4294548877;//假設(shè)該數(shù)值為某一進(jìn)程的進(jìn)程號(hào)
hd:=OpenProcess(PROCESS_TERMINATE,FALSE,dw); file://獲得進(jìn)程的句柄
PMC.cb:=sizeof(PMC);
if GetProcessMemoryInfo(hd, PMC, PMC.cb) then
begin
file://調(diào)用PMC.WorkingSetSize來(lái)獲得所占用內(nèi)存的大小
end;
CloseHandle(hd);
end;
需要注意的是GetProcessMemoryInfo函數(shù)只在windows nt/2000 下可用,在windows98中沒有函數(shù)可獲得進(jìn)程內(nèi)存的大小,另外要在uses部分引用PsAPI單元,里面有GetProcessMemoryInfo函數(shù)引用說(shuō)明。
2、客戶端程序
客戶端的程序比較簡(jiǎn)單,主要功能是要實(shí)現(xiàn)指令的發(fā)送和信息的接收。
3、程序間的通信
我們采用socket套接字來(lái)實(shí)現(xiàn)程序間的通信,在服務(wù)器端運(yùn)行一Socket服務(wù)器序,監(jiān)聽來(lái)自客戶端的連接和接受指令。在delphi中,復(fù)雜的Socket函數(shù)被封裝成一控件TserverSocket,該控件繼承自TCustomSocket 對(duì)象,封裝了對(duì)監(jiān)聽端口綁定和監(jiān)聽。只要調(diào)用TserverSocket控件的Open方法,就可使服務(wù)器端的Sockct處于監(jiān)聽狀態(tài),當(dāng)客戶端有連接請(qǐng)求時(shí)將自動(dòng)接受連接,然后在ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket)事件中讀取來(lái)自客戶端的請(qǐng)求。為了安全起見,我們可自定義較高層的協(xié)議,在客端所發(fā)送的信息中加上內(nèi)容標(biāo)識(shí),如"user:abcdef",表示收到用戶的驗(yàn)證,然后和客戶端之間進(jìn)行安全的認(rèn)證。在讀到數(shù)據(jù)時(shí),我們可根據(jù)內(nèi)容做出相應(yīng)的動(dòng)作,如取得進(jìn)程的信息并發(fā)送給客戶。
在客戶端,我們采用TclientSocket控件來(lái)同服務(wù)器端進(jìn)行通信,在指定了服務(wù)器端的IP地址和端口后,調(diào)用Open方法來(lái)和服務(wù)端的Socket取得聯(lián)系并發(fā)送用戶名和密碼到服務(wù)端進(jìn)行驗(yàn)證,之后就可以發(fā)送指令和接收數(shù)據(jù)了。需要說(shuō)明的是,客戶發(fā)送的指令要和服務(wù)器端進(jìn)行商議好。
以上只是一個(gè)初步的應(yīng)用,利用該思路還可做得更多,我們?cè)趯?shí)際應(yīng)用取得了較好的效果。