看來自己還是沒有自信!bs..........myself
posted @ 2007-08-15 14:32 boddi 閱讀(589) | 評論 (3) | 編輯 收藏
|
|||
何去何從?有點迷茫,是沉寂在溫柔之鄉(xiāng)還是去迎接狂風暴雨!
看來自己還是沒有自信!bs..........myself posted @ 2007-08-15 14:32 boddi 閱讀(589) | 評論 (3) | 編輯 收藏 2007最新騙局:
?????建行一同志轉(zhuǎn)送:?今天經(jīng)過一棟大樓門口,門口有一提款機。有一個老伯,一直? 看著我走過他身邊,突然叫住我。他說他不識字,拿一張?zhí)峥羁ㄒ規(guī)退诖髽情T口? 的自動提款機取錢。我回答我無法幫你取,叫警衛(wèi)幫你。結果,他就回答我說不用了? ,繼續(xù)找其他路人幫他取錢。朋友們要記住---取款機可是有攝影機耶。萬一他說我搶? 劫或是偷他的提款卡,甚至他的卡片是偷來的,幫他領錢會在提款機留下影像,絕對? 會讓你百口莫辯!我會警惕?!?是因為已有同事上當,目前仍官司纏身。顯然這是詐騙? 集團在找替身了!?請用力傳出去~~~?騙案真是層出不窮,一不小心就會踏入陷阱,真是? 令人防不勝防! 提醒各位朋友在外多小心!? (2)一業(yè)主,家中突然斷電,看到窗戶外別人家里都有電,就出門查看自家電? 表箱,打開門就被刀子頂著了——持刀入室搶劫傷人家里突然斷電,不要貿(mào)然就開門? 查看,有貓眼的多觀察一會門外動靜,沒貓眼的也隔著門靜聽一段時間,沒有異常響? 動再開門。? (3)各位女同胞們注意了!這是最新騙局? 女同胞請注意?男同胞請叫自己的朋友注意?新出的情況,女性朋友要特別注意啦:? 一位上班的小姐在下班回家的路上看到一個小孩子一直哭,很可憐?,然后就過去問那? 小朋友怎么了.小朋友就跟那個小姐說:?我迷路了,可以請你帶我回家嗎?然后拿一張? 紙條給她看,?說那是他家地址.然后她就笨笨的帶小孩子去了.一般人都有同情心,然后? 帶到那個所謂小孩子的家里以后,她一按鈴,門鈴像是有高壓電,就失去知覺了.隔天醒? 來就被脫光光在一間空屋里,身邊什么都沒有了,她甚至連犯人長啥樣子都沒看見.所以? ,現(xiàn)在人犯案都是利用同情心啊,如果遇到類似這種的,千萬別帶他去,要帶就帶他到派? 出所去好了,走丟的小孩放到派出所一定沒錯啦,請通知身邊所有女性,為了廣大女士? 的安全,看完后麻煩給轉(zhuǎn)發(fā)給所有人。? (4)今天遇到討飯新招,大家注意提防了~~? 今天在家休息,有人按門鈴,開門一看,是個50來歲的老婦女,手里拿了2包喜糖,我? 還以為是鄰居來分喜糖的,結果一開口,聽得出不是本地人,她說什么這2包糖給我們? 的,圖個喜氣,要換一點錢給她,后面還說了一大堆不知道什么,我也沒聽清楚,感? 覺就是不對,嚇的馬上關門,暈!這年頭,還有這么討錢的一剛。? (5)轉(zhuǎn)發(fā):大家注意了!到自動取款機取錢時一定要倍加小心!!!!!? 昨晚在工行自動取款機取錢時,后面來了個老婦女,問我能不能取錢,還說? 什么取款機有個鍵可能壞了,旁邊不知什么時候來了個小女孩,一直想我身邊躋,我? 也沒在意,小孩子淘氣嘛,可是過分的是她竟然把手朝出鈔口放,準備拿我的錢了,? 我感覺不對勁了,立即把她推到一邊,等著把錢取出來。之后我想了一下,她們倆給? 我設了個套:老婦女負責和我瞎聊,吸引我的注意力,小女孩趁我不注意時搶走我的? 錢!如果我不防備的話,錢說不定就被搶走了,這樣的話,我就進套了:(一則我立? 即去追小女孩,去追回我的錢,可是誰又會相信一個小女孩能搶我一個大人的錢呢?? 更可怕的是站在我后面的老婦女將會取光我卡中所有的錢,因為我的卡還在取款機里? 面;二則我不立即去追小女孩,等拿到卡再追,到那時小女孩就無影無蹤了,錢也就? 沒了啊:(她們真的很聰明,很可恥的!!!)? 這是我的親身經(jīng)歷,希望大家以后取錢時一定要警惕起來,注意觀察周圍的所有人,? 并轉(zhuǎn)告周圍的家人、同事、朋友,讓壞蛋分子沒有可乘之機!!!!又出現(xiàn)騙局新招? !!? (6)我父母都退休在家。昨天上午,來一陌生中年人,說自己摩托車油開沒了,加油? 站太遠,摩托車又太重推不動,所以想問我父母要一個可樂瓶去買汽油,剛開口就說? 實在不行就出2、3元買一個空瓶好了。我母親就拿了個空瓶給他,別說他還真從口袋? 里掏出錢來,不過是幾張百元大鈔,還讓我父母找錢。我母親頓生警覺,說算了,不? 過是一個空瓶而已。他10元錢買下來,只不過還是那張百元大鈔。好在我母? 親尚未龍鐘,也不是那種愛貪小便宜的人? 女性朋友一定要認真看完,注意自我安全啊,現(xiàn)在萬惡的社會。。。。朋友發(fā)給我一? 篇報道,現(xiàn)轉(zhuǎn)給各位看看?,出門在外,千萬小心,小心千萬。。。? (7)一對新婚夫婦到巴黎度蜜月。在巴黎,妻子在一間時尚服裝店試衣服?,身為丈夫? 就在試衣間外等候。但等候多時卻不見妻子走出來?,緊張的丈夫要求店員幫忙到里頭? 查看?,卻意外發(fā)現(xiàn)試衣間空無一人。丈夫以為妻子開玩笑作弄人?,要他緊張.于是回到? 酒店等她回來。幾小時后卻不見妻子的蹤影,才知事態(tài)嚴重。丈夫趕忙報警?,并到巴黎? 所有服裝店和醫(yī)院詢問妻子下落。三星期過去了,妻子猶如從人間蒸發(fā),音訊全無,傷? 心的丈夫只能收拾包袱回到?**?。由于無法從絕望中振作,丈夫無心工作,甚至獨自生? 活?,決定把自己放逐,流浪到各地方。幾年后?,他心血來潮到巴厘島,在一破舊的屋子? 參觀一畸形秀?(?freak?show?)?。他見到一臟生銹的鐵籠里,有一女人四肢全無,身軀,? 包括臉部,猶如破布般殘破?,充滿疤痕。她在地上扭曲著?,并發(fā)出有如野獸般的呻吟聲? 。突然間男人驚恐地發(fā)出尖叫聲。他從那毫無人樣的女人臉上見到,他再熟悉不過,屬? 于他新婚不久就告失蹤的妻子臉上的紅色胎記。? (8)另一版本則發(fā)生在上海。幾年前一女通知公安她的表妹在上海市集購物時無故失? 蹤,可是遍尋不著?,直到五年后一友人撞見這表妹在泰國曼谷街道上行乞。恐怖的是她? 不知何故沒了雙手雙腳,身子被鐵鏈綁在燈柱旁。? (9)這是在某一對夫婦去香港游玩時發(fā)生的故事。一對夫妻不知不覺走入了全香港治? 安最壞的地區(qū)的一家精品店里???妻子對店里的衣服樣式十分喜歡?,隨后就進入試衣間? 試衣。可是,先生在外頭等了又等,卻不見妻子出來。由于實在是等太久了?,所以先生? 開門?進去找她,可是試衣間里早已空空如也。他吃驚地向店員詢問妻子到哪里去了,可? 是店員們卻好象是串通好了一樣,都說沒有看見,并堅持根本沒有象他妻子這樣的人來? 過店里。因此他只好請當?shù)氐木靺f(xié)助搜索這家精品店?,可是卻一無所獲。后來他又? 一個人找了一段時間?,直到他的簽證到期。最后不得已他就在找不到妻子的情況下回? 國了。之后經(jīng)過了一年?…?他向公司請了一段長假,再一次回到香港去找他的妻子。他? 帶著妻子的相片走遍香港的大街小巷,但這次仍是一點線索也沒有。終于假期就要結束? 了,他身心疲憊地開始考慮要回國的時候?,有一天無意間經(jīng)過了一間珍奇小屋。小屋的? 看板上寫著?:?達磨(不倒翁)?雖然他對珍奇事物并不感興趣?,但由于連日疲勞他想? 讓自己改變一下心情?,?加上看板上寫著?達磨的文字也引起他的興趣。最后他決定? 進去瞧瞧。但是他不該進去的!因為珍奇小屋里面展出一件令他慘不忍睹的東?…?小屋? 里的舞臺上有一位手腳都被切斷的全裸女性被當成花瓶一樣擺在那里?!?這位女性的舌? 頭已經(jīng)被拔掉了,不斷發(fā)出奇怪的呻吟聲。看到這么惡心的東西真令他恨不得馬上拔腿? 就跑?,但不知為什么他心里感受到一股奇怪的氣氛?,于是他又重新仔細看那女人的面? 孔?…?沒錯!這女人正是他一年前失蹤的妻子。后來,他向當?shù)氐暮诘乐Ц洱嫶蟮内H金? 換取妻子的剩下的軀干。但一切都太遲了,他可憐的妻子早就已經(jīng)瘋了。現(xiàn)在她還住在? 國內(nèi)某家醫(yī)院,繼續(xù)不斷地發(fā)出奇怪的呻吟聲?…? (10)最近有人告訴我,他的朋友在晚上聽到門口有嬰兒在哭,不過當時已很晚了,? 而且她認為這件事很奇怪,于是她打電話給警察。警察告訴她∶?「無論如何,絕對不? 要開?門。」這位女士表示那聲音聽起來象是嬰兒爬到窗戶附近哭,她擔心嬰兒會爬到? 街上,被車子碾過。警察告訴她∶我們已派人前往,無論如何不能開門。警方認為這? 是一個連續(xù)殺人犯,利用嬰兒哭聲的錄音帶,誘使女性以為有人在外面遺棄嬰兒,她? 們出門察看。雖然尚未證實此事,但是警方已接到許多女性打電話來說,他們晚上獨? 自在家時,聽到門外有嬰兒的哭聲,請將這個消息傳給其他人,不要因為聽到嬰兒的? 哭聲而開門。? 請嚴肅看待這貼子!有這么離譜!小心為妙!!!? 以前聽說大活人現(xiàn)場失蹤,后來被賣到馬戲團、被賣器官什么的,只當是天方夜譚。? 結果真的看到發(fā)生在真實中的恐怖故事。? (11)事情是同事群發(fā)郵件告知的。她的朋友,簡稱小a吧,上周和兩個女孩子,簡稱? 小b和小c,去逛羅湖商業(yè)城。羅湖商業(yè)城是深圳假貨集散地,龍蛇混雜,緊靠深圳火? 車站和香港的羅湖口岸,人流量非常大。話說小c內(nèi)急,就去上衛(wèi)生間,小a和小b在洗? 手間外面等。等了很久很久,還是不見小c出來,兩個人有點奇怪了。于是兩個人進去? 催她。誰知道進去一看,人影全無。兩個人倒豎一口冷氣,打手機也沒人接。一個大? 活人,難道就這么活不見人死不見尸的失蹤了?于是趕緊報警。?警察來了,問情事情? 經(jīng)過以后,說了一句令人無比毛骨悚然的話,“你們有沒有看見其他可疑的人進去?? ”,兩個人再三回憶,沒有。因為不可能帶著一個活生生的100多斤的人出來,而她們? 不注意。這時候小a突然想起來,其間有個清潔工打扮的人推著一輛清潔小車進去、接? 著又出來……?警察告訴他們,這種事情已經(jīng)不是第一次發(fā)生,現(xiàn)在深圳警方初步懷疑? 一個犯罪團伙,有組織地在管理疏松的低檔商業(yè)城,利用人們,尤其是女性對清潔工? 沒有防范意識的心理,進行有組織地綁架、販賣人體器官犯罪。別忘了,羅湖商業(yè)城? 離香港和深圳火車站有多么地近。現(xiàn)在已經(jīng)幾天過去了,那個可憐的小c姑娘,仍是活? 不見人死不見尸。我的同事說,小a,也就是我同事的朋友,仍在等小c的消息。但是? 很可能,也許如果幸運的話,活著的小c會被扔在哪個角落,只是失去了她的腎,但是? ,更有可能的是,也許再過幾天或者幾個月、幾年,小c的頭顱和軀體、四肢會在深圳? 的城鄉(xiāng)結合部的垃圾堆被人發(fā)現(xiàn)。如果看到這個發(fā)生在身邊的活生生的恐怖事件,請? 轉(zhuǎn)告身邊的女性親友,一定小心防范清潔工打扮的人,因為他/她很可能會趁你不注意? 把你敲暈,放進清潔車拉走,接下來等著你的是無比恐怖的活人分尸。? posted @ 2007-03-05 17:11 boddi 閱讀(420) | 評論 (2) | 編輯 收藏 遠程方法調(diào)用入門指南(Java RMI Tutorial)Java R MI Tutorial遠程方法調(diào)用入門指南Copyright ? 2005 Stephen Suen. All rights reserved.
Java 遠程方法調(diào)用(Remote Method Invocation, RMI)使得運行在一個 Java 虛擬機(Java Virtual Machine, JVM)的對象可以調(diào)用運行另一個 JVM 之上的其他對象的方法,從而提供了程序間進行遠程通訊的途徑。RMI 是 J2EE 的很多分布式技術的基礎,比如 RMI-IIOP 乃至 EJB。本文是 RMI 的一個入門指南,目的在于幫助讀者快速建立對 Java RMI 的一個感性認識,以便進行更深層次的學習。事實上,如果你了解 RMI 的目的在于更好的理解和學習 EJB,那么本文就再合適不過了。通過本文所了解的 RMI 的知識和技巧,應該足夠服務于這個目的了。 本文的最新版本將發(fā)布在程序員咖啡館網(wǎng)站上(建設中)。歡迎訂閱我們的郵件組,以獲得關于本文的正式發(fā)布及更新信息。 全文在保證完整性,且保留全部版權聲明(包括上述鏈接)的前提下可以在任意媒體轉(zhuǎn)載——須保留此標注。
1. 簡介我們知道遠程過程調(diào)用(Remote Procedure Call, RPC)可以用于一個進程調(diào)用另一個進程(很可能在另一個遠程主機上)中的過程,從而提供了過程的分布能力。Java 的 RMI 則在 RPC 的基礎上向前又邁進了一步,即提供分布式 對象間的通訊,允許我們獲得在遠程進程中的對象(稱為遠程對象)的引用(稱為遠程引用),進而通過引用調(diào)用遠程對象的方法,就好像該對象是與你的客戶端代碼同樣運行在本地進程中一樣。RMI 使用了術語"方法"(Method)強調(diào)了這種進步,即在分布式基礎上,充分支持面向?qū)ο蟮奶匦浴?/p> RMI 并不是 Java 中支持遠程方法調(diào)用的唯一選擇。在 RMI 基礎上發(fā)展而來的 RMI-IIOP(Java Remote Method Invocation over the Internet Inter-ORB Protocol),不但繼承了 RMI 的大部分優(yōu)點,并且可以兼容于 CORBA。J2EE 和 EJB 都要求使用 RMI-IIOP 而不是 RMI。盡管如此,理解 RMI 將大大有助于 RMI-IIOP 的理解。所以,即便你的興趣在 RMI-IIOP 或者 EJB,相信本文也會對你很有幫助。另外,如果你現(xiàn)在就對 API 感興趣,那么可以告訴你,RMI 使用 java.rmi 包,而 RMI-IIOP 則既使用 java.rmi 也使用擴展的 javax.rmi 包。 本文的隨后內(nèi)容將僅針對 Java RMI。 2. 分布式對象在學習 RMI 之前,我們需要了解一些基礎知識。首先需要了解所謂的分布式對象(Distributed Object)。分布式對象是指一個對象可以被遠程系統(tǒng)所調(diào)用。對于 Java 而言,即對象不僅可以被同一虛擬機中的其他客戶程序(Client)調(diào)用,也可以被運行于其他虛擬機中的客戶程序調(diào)用,甚至可以通過網(wǎng)絡被其他遠程主機之上的客戶程序調(diào)用。 下面的圖示說明了客戶程序是如何調(diào)用分布式對象的:
從圖上我們可以看到,分布式對象被調(diào)用的過程是這樣的:
這個場景基于一個基本的法則,即行為的定義和行為的具體實現(xiàn)相分離。如圖所示,客戶端代理對象 Stub 和分布式對象都實現(xiàn)了相同的接口,該接口稱為遠程接口(Remote Interface)。正是該接口定義了行為,而分布式對象本身則提供具體的實現(xiàn)。對于 Java RMI 而言,我們用接口(interface)定義行為,用類(class)定義實現(xiàn)。 3. RMI 架構RMI 的底層架構由三層構成:
這些層之間的交互可以參照下面的示意圖:
和其它分布式對象機制一樣,Java RMI 的客戶程序使用客戶端的 Stub 向遠程對象請求方法調(diào)用;服務器對象則通過服務器端的 Skeleton 接受請求。我們深入進去,來看看其中的一些細節(jié)。
當客戶程序調(diào)用 Stub 時,Stub 負責將方法的參數(shù)轉(zhuǎn)換為序列化(Serialized)形式,我們使用一個特殊的術語,即編列(Marshal)來指代這個過程。編列的目的是將這些參數(shù)轉(zhuǎn)換為可移植的形式,從而可以通過網(wǎng)絡傳輸?shù)竭h程的服務對象一端。不幸的是,這個過程沒有想象中那么簡單。這里我們首先要理解一個經(jīng)典的問題,即方法調(diào)用時,參數(shù)究竟是傳值還是傳引用呢?對于 Java RMI 來說,存在四種情況,我們將分別加以說明。
在調(diào)用參數(shù)的編列過程成功后,客戶端的遠程引用層從 Stub 那里獲得了編列后的參數(shù)以及對服務器端遠程對象的遠程引用(參見 java.rmi.server.RemoteRef API)。該層負責將客戶程序的請求依據(jù)底層的 RMI 數(shù)據(jù)傳輸協(xié)議轉(zhuǎn)換為傳輸層請求。在 RMI 中,有多種的可能的傳輸機制,比如點對點(Point-to-Point)以及廣播(Multicast)等。不過,在當前的 JMI 版本中只支持點對點協(xié)議,即遠程引用層將生成唯一的傳輸層請求,發(fā)往指定的唯一遠程對象(參見 java.rmi.server.UnicastRemoteObject API)。 在服務器端,服務器端的遠程引用層接收傳輸層請求,并將其轉(zhuǎn)換為對遠程對象的服務器端代理對象 Skeleton 的調(diào)用。Skeleton 對象負責將請求轉(zhuǎn)換為對實際的遠程對象的方法調(diào)用。這是通過與編列過程相對的反編列(Unmarshal)過程實現(xiàn)的。所有序列化的參數(shù)被轉(zhuǎn)換為 Java 形式,其中作為參數(shù)的遠程對象(實際上發(fā)送的是遠程引用)被轉(zhuǎn)換為服務器端本地的 Stub 對象。 如果方法調(diào)用有返回值或者拋出異常,則 Skeleton 負責編列返回值或者異常,通過服務器端的遠程引用層,經(jīng)傳輸層傳遞給客戶端;相應地,客戶端的遠程引用層和 Stub 負責反編列并最終將結果返回給客戶程序。 整個過程中,可能最讓人迷惑的是遠程引用層。這里只要明白,本地的 Stub 對象是如何產(chǎn)生的,就不難理解遠程引用的意義所在了。遠程引用中包含了其所指向的遠程對象的信息,該遠程引用將用于構造作為本地代理對象的 Stub 對象。構造后,Stub 對象內(nèi)部將維護該遠程引用。真正在網(wǎng)絡上傳輸?shù)膶嶋H上就是這個遠程引用,而不是 Stub 對象。 4. RMI 對象服務在 RMI 的基本架構之上,RMI 提供服務與分布式應用程序的一些對象服務,包括對象的命名/注冊(Naming/Registry)服務,遠程對象激活(Activation)服務以及分布式垃圾收集(Distributed Garbage Collection, DGC)。作為入門指南,本文將指介紹其中的命名/注冊服務,因為它是實戰(zhàn) RMI 所必備的。其它內(nèi)容請讀者自行參考其它更加深入的資料。 在前一節(jié)中,如果你喜歡刨根問底,可能已經(jīng)注意到,客戶端要調(diào)用遠程對象,是通過其代理對象 Stub 完成的,那么 Stub 最早是從哪里得來的呢?RMI 的命名/注冊服務正是解決這一問題的。當服務器端想向客戶端提供基于 RMI 的服務時,它需要將一個或多個遠程對象注冊到本地的 RMI 注冊表中(參見java.rmi.registry.Registry API)。每個對象在注冊時都被指定一個將來用于客戶程序引用該對象的名稱。客戶程序通過命名服務(參見 java.rmi.Naming API),指定類似 URL 的對象名稱就可以獲得指向遠程對象的遠程引用。在 Naming 中的 lookup() 方法找到遠程對象所在的主機后,它將檢索該主機上的 RMI 注冊表,并請求所需的遠程對象。如果注冊表發(fā)現(xiàn)被請求的遠程對象,它將生成一個對該遠程對象的遠程引用,并將其返回給客戶端,客戶端則基于遠程引用生成相應的 Stub 對象,并將引用傳遞給調(diào)用者。之后,雙方就可以按照我們前面講過的方式進行交互了。
5. 實戰(zhàn) RMI理論離不開實踐,理解 RMI 的最好辦法就是通過例子。開發(fā) RMI 的分布式對象的大體過程包括如下幾步:
RMI 中各個組件之間的關系如下面這個示意圖所示:
回憶我們上一節(jié)所講的,Stub 和 Skeleton 負責代理客戶和服務器之間的通訊。但我們并不需要自己生成它們,相反,RMI 的編譯器 rmic 可以幫我們基于遠程接口和實現(xiàn)類生成這些類。當客戶端對象通過命名服務向服務器端的 RMI 注冊表請求遠程對象時,RMI 將自動構造對應遠程對象的 Skeleton 實例對象,并通過 Skeleton 對象將遠程引用返回給客戶端。在客戶端,該遠程引用將用于構造 Stub 類的實例對象。之后,Stub 對象和 Skeleton 對象就可以代理客戶對象和遠程對象之間的交互了。 我們的例子展現(xiàn)了一個簡單的應用場景。服務器端部署了一個計算引擎,負責接受來自客戶端的計算任務,在服務器端執(zhí)行計算任務,并將結果返回給客戶端。客戶端將發(fā)送并調(diào)用計算引擎的計算任務實際上是計算指定精度的 π 值。
6. 定義遠程接口定義遠程接口與非分布式應用中定義接口的方法沒有太多的區(qū)別。只要遵守下面兩個要求:
對于第一個要求,java.rmi.Remote 接口實際上沒有任何方法,而只是用作標記接口。RMI 的運行環(huán)境依賴該接口判斷對象是否是遠程對象。第二個要求則是因為分布式應用可能發(fā)生任何問題,比如網(wǎng)絡問題等等。 例 1 列出了我們的遠程接口定義。該接口只有一個方法:executeTask() 用以執(zhí)行指定的計算任務,并返回相應的結果。注意,我們用后綴 Remote 表明接口是遠程接口。 例 1. ComputeEngineRemote 遠程接口 package rmitutorial; import java.rmi.Remote; import java.rmi.RemoteException; public interface ComputeEngineRemote extends Remote { public Object executeTask(Task task) throws RemoteException; } 例 2 列出了計算任務接口的定義。該接口也只有一個方法:execute() 用以執(zhí)行實際的計算邏輯,并返回結果。注意,該接口不是遠程接口,所以沒有擴展 java.rmi.Remote 接口;其方法也不必拋出 java.rmi.RemoteException 異常。但是,因為它將用作遠程方法的參數(shù),所以擴展了 java.io.Serializable 接口。 7. 實現(xiàn)遠程接口接下來,我們將實現(xiàn)前面定義的遠程接口。例 3給出了實現(xiàn)的源代碼。 例 3. ComputeEngine 實現(xiàn) package rmitutorial; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; public class ComputeEngine extends UnicastRemoteObject implements ComputeEngineRemote { public ComputeEngine() throws RemoteException { super(); } public Object executeTask(Task task) throws RemoteException { return task.execute(); } } 類 ComputeEngine 實現(xiàn)了之前定義的遠程接口,同時繼承自 java.rmi.server.UnicastRemoteObject 超類。UnicastRemoteObject 類是一個便捷類,它實現(xiàn)了我們前面所講的基于 TCP/IP 的點對點通訊機制。遠程對象都必須從該類擴展(除非你想自己實現(xiàn)幾乎所有 UnicastRemoteObject 的方法)。在我們的實現(xiàn)類的構造函數(shù)中,調(diào)用了超類的構造函數(shù)(當然,即使你不顯式的調(diào)用這個構建函數(shù),它也一樣會被調(diào)用。這里這樣做,只是為了突出強調(diào)這種調(diào)用而已)。該構造函數(shù)的最重要的意義就是調(diào)用 UnicastRemoteObject 類的 exportObject() 方法。導出(Export)對象是指使遠程對象準備就緒,可以接受進來的調(diào)用的過程。而這個過程的最重要內(nèi)容就是建立服務器套接字,監(jiān)聽特定的端口,等待客戶端的調(diào)用請求。 8. 引導程序為了讓客戶程序可以找到我們的遠程對象,就需要將我們的遠程對象注冊到 RMI 的注冊表。這個過程有時被稱為"引導"過程(Bootstrap)。我們將為此編寫一個獨立的引導程序負責創(chuàng)建和注冊遠程對象。例 4 給出了引導程序的源代碼。 例 4. 引導程序 package rmitutorial; import java.rmi.Naming; import java.rmi.RMISecurityManager; public class Bootstrap { public static void main(String[] args) throws Exception { String name = "ComputeEngine"; ComputeEngine engine = new ComputeEngine(); System.out.println("ComputerEngine exported"); Naming.rebind(name, engine); System.out.println("ComputeEngine bound"); } } 可以看到,我們首先創(chuàng)建了一個遠程對象(同時導出了該對象),之后將該對象綁定到 RMI 注冊表中。Naming 的 rebind() 方法接受一個 URL 形式的名字作綁定之用。其完整格式如下: 其中,協(xié)議(Protocol)默認為 rmi;主機名默認為 localhost;端口默認為 1099。注意,JDK 中提供的默認 Naming 實現(xiàn)只支持 rmi 協(xié)議。在我們的引導程序里面只給出了對象綁定的名字,而其它部分均使用缺省值。 9. 客戶端程序例 5 給出了我們的客戶端程序。該程序接受兩個參數(shù),分別是遠程對象所在的主機地址和希望獲得的 π 值的精度。 例 5. Client.java package rmitutorial; import java.math.BigDecimal; import java.rmi.Naming; public class Client { public static void main(String args[]) throws Exception { String name = "rmi://" + args[0] + "/ComputeEngine"; ComputeEngineRemote engineRemote = (ComputeEngineRemote)Naming.lookup(name); Pi task = new Pi(Integer.parseInt(args[1])); BigDecimal pi = (BigDecimal)(engineRemote.executeTask(task)); System.out.println(pi); } } 例 6. Pi.java package rmitutorial; import java.math.*; public class Pi implements Task { private static final BigDecimal ZERO = BigDecimal.valueOf(0); private static final BigDecimal ONE = BigDecimal.valueOf(1); private static final BigDecimal FOUR = BigDecimal.valueOf(4); private static final int roundingMode = BigDecimal.ROUND_HALF_EVEN; private int digits; public Pi(int digits) { this.digits = digits; } public Object execute() { return computePi(digits); } public static BigDecimal computePi(int digits) { int scale = digits + 5; BigDecimal arctan1_5 = arctan(5, scale); BigDecimal arctan1_239 = arctan(239, scale); BigDecimal pi = arctan1_5.multiply(FOUR).subtract( arctan1_239).multiply(FOUR); return pi.setScale(digits, BigDecimal.ROUND_HALF_UP); } public static BigDecimal arctan(int inverseX, int scale) { BigDecimal result, numer, term; BigDecimal invX = BigDecimal.valueOf(inverseX); BigDecimal invX2 = BigDecimal.valueOf(inverseX * inverseX); numer = ONE.divide(invX, scale, roundingMode); result = numer; int i = 1; do { numer = numer.divide(invX2, scale, roundingMode); int denom = 2 * i + 1; term = numer.divide(BigDecimal.valueOf(denom), scale, roundingMode); if ((i % 2) != 0) { result = result.subtract(term); } else { result = result.add(term); } i++; } while (term.compareTo(ZERO) != 0); return result; } } 10. 編譯示例程序編譯我們的示例程序和編譯其它非分布式的應用沒什么區(qū)別。只是編譯之后,需要使用 RMI 編譯器,即 rmic 生成所需 Stub 和 Skeleton 實現(xiàn)。使用 rmic 的方式是將我們的遠程對象的實現(xiàn)類(不是遠程接口)的全類名作為參數(shù)來運行 rmic 命令。參考下面的示例: E:\classes\rmic rmitutorial.ComputeEngine 編譯之后將生成 rmitutorial.ComputeEngine_Skel 和 rmitutorial.ComputeEngine_Stub 兩個類。 11. 運行示例程序遠程對象的引用通常是通過 RMI 的注冊表服務以及 java.rmi.Naming 接口獲得的。遠程對象需要導出(注冊)相應的遠程引用到注冊表服務,之后注冊表服務就可以監(jiān)聽并服務于客戶端對遠程對象引用的請求。標準的 Sun Java SDK 提供了一個簡單的 RMI 注冊表服務程序,即 rmiregistry 用于監(jiān)聽特定的端口,等待遠程對象的注冊,以及客戶端對這些遠程對象引用的檢索請求。 在運行我們的示例程序之前,首先要啟動 RMI 的注冊表服務。這個過程很簡單,只要直接運行 rmiregistry 命令即可。缺省的情況下,該服務將監(jiān)聽 1099 端口。如果需要指定其它的監(jiān)聽端口,可以在命令行指定希望監(jiān)聽的端口(如果你指定了其它端口,需要修改示例程序以適應環(huán)境)。如果希望該程序在后臺運行,在 Unix 上可以以如下方式運行(當然,可以缺省端口參數(shù)): $ rmiregistry 1099 & 在 Windows 操作系統(tǒng)中可以這樣運行: C:\> start rmiregistry 1099 我們的 rmitutorial.Bootstrap 類將用于啟動遠程對象,并將其綁定在 RMI 注冊表中。運行該類后,遠程對象也將進入監(jiān)聽狀態(tài),等待來自客戶端的方法調(diào)用請求。 $ java rmitutorial.Bootstrap ComputeEngine exported ComputeEngine bound 啟動遠程對象后,打開另一個命令行窗口,運行客戶端。命令行的第一個參數(shù)為 RMI 注冊表的地址,第二個參數(shù)為期望的 π 值精度。參考下面的示例: $ java rmitutorial.Client localhost 50 3.14159265358979323846264338327950288419716939937511 12. 其它信息在演示示例程序時,我們實際上是在同一主機上運行的服務器和客戶端,并且無論是服務器和客戶端所需的類都在相同的類路徑上,可以同時被服務器和客戶端所訪問。這忽略了 Java RMI 的一個重要細節(jié),即動態(tài)類裝載。因為 RMI 的特性(包括其它幾個特性)并不適用于 J2EE 的 RMI-IIOP 和 EJB 技術,所以,本文將不作詳細介紹,請讀者自行參考本文給出的參考資料。不過,為了讓好奇的讀者不至于過分失望,這里簡單介紹一下動態(tài)類裝載的基本思想。 RMI 運行時系統(tǒng)采用動態(tài)類裝載機制來裝載分布式應用所需的類。如果你可以直接訪問應用所涉及的所有包括服務器端客戶端在內(nèi)的主機,并且可以把分布式應用所需的所有類都安裝在每個主機的 注意,這種動態(tài)類裝載將需要交互的兩端加載定制的安全管理器(參見 java.rmi.RMISecurityManager API),以及對應的策略文件。 13. 參考資料
posted @ 2006-10-11 09:51 boddi 閱讀(2123) | 評論 (1) | 編輯 收藏 正則表達式(轉(zhuǎn)載)關鍵詞: 正則表達式 ?? 模式匹配 ?? Javascript ?? ??????????????????????????????????????關鍵字:正則表達式 ?模式匹配 Javascript 摘要:收集一些常用的正則表達式。 正則表達式用于字符串處理,表單驗證等場合,實用高效,但用到時總是不太把握,以致往往要上網(wǎng)查一番。我將一些常用的表達式收藏在這里,作備忘之用。本貼隨時會更新。 匹配中文字符的正則表達式: [\u4e00-\u9fa5] 匹配雙字節(jié)字符(包括漢字在內(nèi)):[^\x00-\xff] 應用:計算字符串的長度(一個雙字節(jié)字符長度計2,ASCII字符計1) String.prototype.len=function(){return this.replace([^\x00-\xff]/g,"aa").length;} 匹配空行的正則表達式:\n[\s| ]*\r 匹配HTML標記的正則表達式:/<(.*)>.*<\/\1>|<(.*) \/>/ 匹配首尾空格的正則表達式:(^\s*)|(\s*$) String.prototype.trim = function() 利用正則表達式分解和轉(zhuǎn)換IP地址: 下面是利用正則表達式匹配IP地址,并將IP地址轉(zhuǎn)換成對應數(shù)值的Javascript程序: function IP2V(ip) 不過上面的程序如果不用正則表達式,而直接用split函數(shù)來分解可能更簡單,程序如下: var ip="10.100.20.168" 匹配Email地址的正則表達式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* 匹配網(wǎng)址URL的正則表達式:http://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?
var s="abacabefgeeii" 得用正則表達式從URL地址中提取文件名的javascript程序,如下結果為page1 s="http://www.9499.net/page1.htm" 利用正則表達式限制網(wǎng)頁表單里的文本框輸入內(nèi)容: 用正則表達式限制只能輸入中文:onkeyup="value=value.replace(/[^\u4E00-\u9FA5]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\u4E00-\u9FA5]/g,''))" 用正則表達式限制只能輸入全角字符:?onkeyup="value=value.replace(/[^\uFF00-\uFFFF]/g,'')" onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\uFF00-\uFFFF]/g,''))" 用正則表達式限制只能輸入數(shù)字:onkeyup="value=value.replace(/[^\d]/g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))" 用正則表達式限制只能輸入數(shù)字和英文:onkeyup="value=value.replace(/[\W]/g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))" posted @ 2006-09-13 16:28 boddi 閱讀(364) | 評論 (0) | 編輯 收藏 |
|||