flashas3.0編程教程actionscript3.0socket與Socket服務器建立連接_第1頁
flashas3.0編程教程actionscript3.0socket與Socket服務器建立連接_第2頁
flashas3.0編程教程actionscript3.0socket與Socket服務器建立連接_第3頁
flashas3.0編程教程actionscript3.0socket與Socket服務器建立連接_第4頁
flashas3.0編程教程actionscript3.0socket與Socket服務器建立連接_第5頁
已閱讀5頁,還剩8頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、ActionScript3.0 Socket編程與Socket服務器建立連接解決方法:通過調用Socket.connect( )或者XMLSocket.connect( )方法并網(wǎng)絡連接的事件消息.:連接一臺 Socket 服務器你需要確定兩個信息,一個是 Socket 服務器的或者 IP 地址,另一個是服務器的端.無論你使用的是 Socket 還是 XMLSocket 類的實例,連接請求都是完全的一樣的,兩個類都是使用一個名叫 connect()的方法,該方法有兩個參數(shù):host :該參數(shù)為字符串類型,可以是一個,例如,也可以是一個 IP 地址,例如01.如果 Socket 服務器與你該 F

2、lash 影片發(fā)布的 Web 服務器是同一個,該參數(shù)為Null. port :該參數(shù)為一個表示 Socket 服務器一個 policy 文件,用于指定允許端因為 Flash端口的值.該值最小為 1024.除非在服務器中有小于 1024.Socket 編程是一個異步的過程,connect()方法不會等到接完成后再執(zhí)行下一行代碼的執(zhí)行.如果你想在接完全執(zhí)行完之前與一個Socket 完全綁定,那么你將會得到一個意想不到的結果,并且你當前的代碼將不能工作.在嘗試一個新的 Socket 連接的時候功,Socket 或者 XMLSocket 會發(fā)出最好先添加接事件器.當接建立成接事件,這就可以讓你知道交互

3、已經(jīng)準備好了.下面舉了一個 Socket 實例與本地 Socket 服務器的 2900 端口建立連接的例子:package import flash.display.Sprite; import flash.events.*; import .Socket;public class SocketExle extends Sprite private var socket:Socket;public function SocketExsocket = new Socket();le() / Add an event listener to be notified when the connect

4、ion/ is madesocket.addEventListener( Event.CONNECT, onConnect );/ Connect to the serversocket.connect( localhost, 2900 );private function onConnect( event:Event ):void trace( The socket is now connected. );如果你想通過XMLSocket 與服務器建立連接代碼也是基本一樣的.首先你創(chuàng)建了件器,然后調用 connect()方法.所不同的是 Socket 實例改為了XMLSocket:接事pack

5、age import flash.display.Sprite; import flash.events.*;import .XMLSocket;public class SocketExle extends Sprite private var socket:XMLSocket;public function SocketExle() socket = new XMLSocket();/ Add an event listener to be notified when the connection is madesocket.addEventListener( Event.CONNECT,

6、 onConnect );/ Connect to the serversocket.connect( localhost, 2900 );private function onConnect( event:Event ):void trace( The xml socket is now connected. );如果連接失敗,可那是下面兩種原因的一種:一種是連接立即失敗和運行時錯誤,另一種是如果無法完成連接從而產(chǎn)生一個 ioError 或者securityError 事件.關于錯誤事件處理信息的描述,打算改日.請牢記,當與一個主機建立一個 Socket 連接時,Flash Player 要

7、遵守如下安全沙箱規(guī)則.1.Flash 的.swf 文件和主機必須嚴格的在同一個,才可以成功建立連接.一個從網(wǎng)上發(fā)布的.swf 文件是不可以本地未通過認證的.swf 文件是不可以本地服務器的.任何網(wǎng)絡資源的.4.你想跨域或者連接低于 1024 的端口,必須使用一個跨域策略文件.如果嘗試連接未認證的域或者口服務,這樣就了安全沙箱策略,同時會產(chǎn)生一個securityError 事件.這些情況都可以通過使用一個跨域策略文件解決.無論是 Socket 對象還是XMLSocket 對象的策略文件,都必須在連接之前通過使用flash.system.Security.lo方法載入策略文件.具體如下:olicy

8、File()Security.loolicyFile(/cross,還定義了端.xml);.如果你不設置端獲得的改策略文件不僅定義了允許的Flash,那么Player 默認為 80 端口(HTTP 協(xié)議默認端口).在中可以使用逗號隔開設置多個端.下面這個例子就是允許80 和 110 端口.-policy.dtdcross-從Socket服務器讀數(shù)據(jù)解決方法:對于 Socket 實例,先收到 socketData 事件,然后調用如下兩個方法的一個,比如,readByte() 或者 read bytesAvailable.(), 在事件控制器中確定不會去讀過去的對于 XMLSocket 實例,先收

9、到 data 事件,然后從事件控制器 XML 數(shù)據(jù).裝載的:從一個 socket 連接接收的數(shù)據(jù)依賴于你使用的 Socket 的類型.socket 和 XMLSocket 都可以從服務器接受到數(shù)據(jù),但是它們處于不同重量級的技術.讓我們在XMLSocket 之前先關注下 Socket 類.我都知道 socket 在 Flash 中是一個異步的行為.因此,它就不能簡單的創(chuàng)建一個Socket 連接,然后就立刻嘗試去數(shù)據(jù).read 方法不能等到從服務器傳過來數(shù)據(jù)之后在返回.換句話說,你只能在客戶端從服務器載入所有數(shù)據(jù)之后才可以數(shù)據(jù).在數(shù)據(jù)可用之前讀數(shù)據(jù)會產(chǎn)生一個錯誤.通過 socketData 事件廣

10、播到 Socket 實例,這樣就可以知道什么時候數(shù)據(jù)可以被.那么要為 socketData 事件添加一個事件器,任何時候只要有新的數(shù)據(jù)從一個 socket 服務器發(fā)送過來,都會觸發(fā)事件控制器.在事件處理器的寫入要執(zhí)行的代碼去和處理收到的數(shù)據(jù).從一個前端服務器數(shù)據(jù),Socket 類為提供了許多不同的方法,這些方法依賴于你所讀得數(shù)據(jù)類型.例如,你可以通過readByte()方法讀一個byte 數(shù)據(jù),或者通過一個使用 readUnsigned()方法去讀一個無符號整數(shù).下面這個表列出來能夠從服務器的數(shù)據(jù)類型,返回值,和 read 方法每次讀入的字節(jié)數(shù).Table:Socketreadmethodsf

11、orvariousdaypes有兩個額外的方法沒有在上面這個表中描述.它們分別是readBytes()和readUTFBytes().readBytes()方法只可以讓 socket 讀數(shù)據(jù)但不能返回一個值,并且該方法需要 3 個參數(shù):bytes:一個 flash.util.ByteArray 實例從 socket 中收到的數(shù)據(jù).方法:返回值類型描述字節(jié)數(shù)read( ):從 Socket一個值.1readByte( ):從 Socket一個 byte 值.1readDouble( ):Number從 Socket一個 IEEE 754 雙精度浮點數(shù).8readFloat( ):Number從

12、Socket一個 IEEE 754 單精度浮點數(shù).4read( ):從 Socket一個有符號 32-bit 整數(shù)值.4readObject( ):*從Socket一個AMF-encoded對象.nreadShort( ):從 Socket一個有符號 16-bit 整數(shù)值.2readUnsignedByte( ):u從 Socket一個無符號字節(jié).1readUnsigned( ):u從 Socket一個無符號 32-bit 整數(shù)4readUnsignedShort( ):u從 Socket一個無符號 16-bit 整數(shù).2readUTF( ):String從 Socket一個一個 UTF8 字

13、符串.noffset:一個u為 0. length:一個u值,指定從什么位置開始socket 中收到數(shù)據(jù)的偏移量.默認值值,用于指定bytes 的數(shù)量.默認值為 0,意思就是說將所有的可用的數(shù)據(jù)都放入 ByteArray 中.另一個 readUTFBytes()方法,只需要一個長度參數(shù)用于指定 UTF-8 字節(jié)的讀入數(shù)量,并且該方將所有讀入的字節(jié)碼轉換成為字符串類型.注意:在從一個 Socket 讀數(shù)據(jù)之前,首先要判斷 bytesAvailable 的屬性.如果你不知道要讀入的數(shù)據(jù)類型是什么就去讀數(shù)據(jù)的話,將會產(chǎn)生一個錯誤 (flash.errors.EOFError).下面的例子代碼連接了一

14、個 socket 服務器,并顯示每次從服務器發(fā)來的數(shù)據(jù).package import import importflash.display.Sprite; flash.events.ProgressEvent; .Socket;publicclass SocketExle extends Sprite private var socket:Socket;public function SocketEx socket = new Socket();le() / Listen for when data is received from the socket serversocket.addEve

15、ntListener( onSocketData );ProgressEvent.SOCKET_DATA,/ Connect to the server socket.connect( localhost, 2900 );private function onSocketData( event:ProgressEvent ):void trace( Socket received + socket.bytesAvailable + byte(s) ofdata: );/ Loop over all of the received data, and only read a byte if th

16、ere/ is one availablewhile ( socket.bytesAvailable ) / Read a byte from the socket and display it var data:= socket.readByte();trace( data );在上面的這個例子中, 如果一個 socket 服務器發(fā)送回一個消息( 例如 o),當一個客戶段連入服務器就會返回并輸出下面類似的文字:Socket received 5 byte(s) of data: 72101108108111注意:一旦數(shù)據(jù)從 socket 讀出,它就不能再次被讀.例如,讀一個字節(jié)之后,這個字節(jié)

17、就不能再放回來,只能讀后邊的字節(jié).當收到的數(shù)據(jù)為ASCII 編碼,你可以通過readUTFBytes()方法重新構建一個字符串.readUTFBytes()方法需要知道多少個字節(jié)需要轉換為字符串.你可以使用 bytesAvailable 去讀所有的字節(jié)數(shù)據(jù):var string:String = socket.readUTFBytes(socket.bytesAvailable);XMLSocket 類的動作和Socket 類相比在從服務器接受數(shù)據(jù)的風格相似.兩者都是通過事件器來數(shù)據(jù)接收通知的,這主要取決于 Flash 異步的 Socket實現(xiàn).然而,在處理實際數(shù)據(jù)的時候有很大的不同.有個 X

18、MLSocket 實例在從服務器完數(shù)據(jù)后分發(fā)數(shù)據(jù)事件.通過flash.events.DataEvent.DATA 常量定義的數(shù)據(jù)事件包含一個data 屬性,該屬性包含了從服務器收到的信息.注意:使用 XMLSocket 從服務器返回的數(shù)據(jù)總是認為是一個字符串類型的數(shù)據(jù).這樣不用為任何數(shù)據(jù)類型的數(shù)據(jù)指定方法.這些從服務器返回的數(shù)據(jù)是沒有經(jīng)過任何處理的原始數(shù)據(jù).因此,你不能通過XMLSocket 連接立即使用XML,你發(fā)送和接收的都是純字符串數(shù)據(jù).如果你期望 XML,在你處理數(shù)據(jù)之前,你必須首先將這些數(shù)據(jù)轉換為一個 XML 的實例.下面的這段代碼在初始化的時候通過 XMLSocket 連接到了本地

19、服務器的 2900 端口.在連接成功之后,一個消息會發(fā)送到服務器.onData 事件者控制從服務器返回的響應.在本例中返回字符串 .你可以通過事件的 data 屬性發(fā)現(xiàn)為字符串數(shù)據(jù),然后XML 類的構造函數(shù)將字符串轉換成為了XML 實例.最后,通過使用E4X 語法的XML 實例的一部分信息.(關于通過使用 E4X 處理 XML 的另外.)詳細信息,需要package import import import importflash.display.Sprite; flash.events.Event; flash.events.DataEvent; .XMLSocket;publicclass

20、 SocketExle extends Sprite private var xmlSocket:XMLSocket;public function SocketExle() xmlSocket = new XMLSocket();/ Connect listener to send a message to theserver/ after we make a sucsful connectionxmlSocket.addEventListener( Event.CONNECT, onConnect );/ Listen for when data is received from the

21、socket serverxmlSocket.addEventListener( DataEvent.DATA, onData);/ Connect to the server xmlSocket.connect( localhost, 2900 );private function onConnect( event:Event ):void xmlSocked( );private function onData( event:DataEvent ):void /The raw string returned from the server. It might look something

22、like this:trace( event.data );/ Convert the stringo XMLXML( event.data );var response:XML=new/ Using E4X, ac/ element nodes the sucs attribute of the testhe response./ Output: truetrace( response.test.sucs );注意:在 data 事件分發(fā)數(shù)據(jù)之前,XMLSocket 實例必須從服務器收到一個表示為空的 byte(0).也就是說,從服務器僅僅只發(fā)送所需要的字符串是不夠的,必須在結尾處加入一個表

23、示為空的 byte.同Socket服務器進行握手,并確定收到了什么樣的數(shù)據(jù)和如何處理這些數(shù)據(jù)解決方法:創(chuàng)建不同的常量來協(xié)議的狀態(tài).使用這些常量將指定的處理函數(shù)到相應的狀態(tài).在一個 socketData 事件控制器中,通過狀態(tài)調用這些函數(shù)的.:建立 Socket 連接通常要處理握手這個環(huán)節(jié).尤其是在服務器初始化需要向客戶端發(fā)送數(shù)據(jù).然后客戶端通過一種特殊的方式相應這些數(shù)據(jù),接著服務器因此再次響應.整個處理過程直到握手完成并且建立起一個正常的連接為止.處理服務器的不同響應是非難的,主要的原因是 socketData 事件控制器不能保存上下文的順序.也就是說,服務器的響應不會告訴你為什么響應,也不告

24、訴你這些響應數(shù)據(jù)被那個處理程序來處理.要想知道如何處理這些從服務器返回的響應不能從響應的本身來獲得,尤其在響應變化的時候.或許一個響應返回了兩個字節(jié)碼,另一個返回了一個整數(shù)值還跟了一個雙精度浮點數(shù).這樣看來讓響應本身處理自己是一題.通過創(chuàng)建一個狀態(tài)量來標注不同的上下文,服務器通過這些上下文將數(shù)據(jù)發(fā)送到客戶端.與這些狀態(tài)量都有一個相關聯(lián)的函數(shù)來處理該數(shù)據(jù),這樣你就可以很輕松的按照當前的協(xié)議狀態(tài)去調用正確的處理函數(shù).當你要與一個 Socket 服務器建立連接需要考慮如下幾個步驟: 1.當與服務器連接的時候,服務器立刻返回一個標志服務器可以支持的最高協(xié)議版本號的整數(shù)值.2.客戶端在響應的時候會返回一

25、個實際使用協(xié)議的版本號.3.服務器返回一個 8byte 的鑒定碼.4.然后客戶端將這鑒定碼返回到服務器.5.如果客戶端的響應不是服務器端所期望的,或者,就在這個時候該協(xié)議變成了一個常規(guī)操作模式,于是握手結束.實際上在第四步可以在鑒定碼中包含的安全響應.你可以通過發(fā)送各種加密方法的密匙來代替逐個發(fā)送的鑒定碼.這通常使用在客戶端向用戶索要的時候,然后成為了加密過的 8byte 鑒定碼.該加密過的鑒定碼接著返回到服務器.如果響應的鑒定碼匙服務器所期望的,客戶端就知道該后同意建立連接.是正確的,然實現(xiàn)握手框架,你首先要為處理從服務器返回的不同類型的數(shù)據(jù)分別創(chuàng)建常量.首先,你要從步驟 1 確定版本號.然

26、后從步驟 3 收取鑒定碼.最后就是步驟 5的常規(guī)操作模式.可以如下常量:public public publicconst const constDETERMINE_VER:= 0;= 1;RECEIVE_CHALLENGE:NORMAL:= 2;常量的值并不重要,重要的是這些值要是不同的值,兩兩之間不能有相同的整數(shù)值.下一個步驟就要為不同的數(shù)據(jù)創(chuàng)建不同處理函數(shù)了.創(chuàng)建的這三個函數(shù)分別被命名為 readVer創(chuàng)建完這三個函數(shù)后,( ), readChallenge( ) 和 readNormalProtocol( ).就必須將這三個函數(shù)分別到前面不同狀態(tài)常量,從而分別處理在該狀態(tài)中收到的數(shù)據(jù).

27、代碼如下:s s s seMap = new Object();eMap eMap eMapDETERMINE_VER RECEIVE_CHALLENGE NORMAL=readVer;readChallenge; readNormalProtocol;最后一步是編寫 socketData 事件處理控制器,只有通過這樣的方式,建立在當前協(xié)議狀態(tài)之上的正確的處理函數(shù)才可以被調用.首先需要創(chuàng)建一個currentSe 的變量.然后使用seMap 去查詢與currentSe 相關聯(lián)的函數(shù),這樣處理函數(shù)就可以被正確調用了.var prosFunc:Function = seMap currentSe ;

28、prosFunc(); / Invoke the appropriate prosing function下面是一點與薄記相關的處理程序.在你的代碼中更新 currentS保當前協(xié)議的狀態(tài).e 從而確前面所探討的握手步驟的完整的代碼如下: package import import import importflash.display.Sprite; flash.events.ProgressEvent; .Socket; flash.utils.ByteArray;public class SocketExle extends Sprite / The public public publi

29、cseconstants to describethe protocol= 0;= 1;const const constDETERMINE_VER:RECEIVE_CHALLENGE: NORMAL:= 2;/ Maps a se to a prosingfunctionprivate var seMap:Object;/ Keeps track of the current protocol seprivate var currentSe:;private var socket:Socket;public function SocketExle( map)/ s s s sInitialz

30、es the seseMap = new Object();eMap eMap eMapDETERMINE_VER RECEIVE_CHALLENGE NORMAL=readVer;readChallenge; readNormalProtocol;/Initialze the current securrentSe = DETERMINE_VER;/ Create and connect the socket socket = new Socket();socket.addEventListener( onSocketData );socket.connect( localhost, 290

31、0 );ProgressEvent.SOCKET_DATA,private function onSocketData( event:ProgressEvent ):void / Look up the prosing function based on the current sevar prosFunc:Function= seMap currentSe ;prosFunc();private function readVer():void from the server ();/ Step var ver1 - read the ver:= socket.read/ Oncethe ve

32、ris read, the next se is receiving/ the challenge from the servercurrentSe = RECEIVE_CHALLENGE;/ Step 2- write the verback tothe serversocket.write socket.flush( ver););private functionreadChallenge():void/ Step 3 - read the 8 byte challenge var bytes:ByteArray = new ByteArray( socket.readBytes( byt

33、es, 0, 8 );o a byte array);/ After the challenge is received,/ the normal protocol operationthe next se iscurrentSe = NORMAL;/ Step 4- write the bytes back tothe serversocket.writeBytes( bytes ); socket.flush();private function readNormalProtocol():void / Step 5 - pros the normal socket messages her

34、e nowt/ndshaking pros is complete與Socket服務器斷開,或者當服務器想與你斷開的時候發(fā)消息給你解決方法:通過調用 Socket.close( )或者 XMLSocket.close( )方法顯性的斷開與服務器的連接.同時可以通過close 事件獲得服務器主動斷開的消息.:通常情況下需要對程序進行下工作.比如說,你創(chuàng)建了一個對象,當這個對象沒有用的時候 Socket 服務器,都要在就要刪除它.因此,無論什么時候連接一個完成了必要的任務之后顯性的斷開連接. 一直留著無用的 Socket 連接浪費網(wǎng)絡資源,應該盡量避免這種情況.如果你沒有斷開一個連接,那么這個服務

35、器會繼續(xù)保持著這個無用的連接.這樣一來就很快會超過了服務器最大 Socket 連接上線.Socket 和 XMLSocket 對象斷開連接的方法是一樣的.你只需要調用 close()方法就可以了:/ Ame socket is a connected Socket instancesocket.close();/ Disconnect from the server同樣的,XMLSocket 對象斷開連接的方法一樣:/ Ame xmlSocket is a connected XMLSocket instancexmlSocket.close();/ Disconnect from the s

36、erverclose()方法用于通知服務器客戶端想要斷開連接.當服務器主動斷開連接會發(fā)消息通知客戶端.可以通過調用addEventListener()方法一個close 事件的一個器.Socket 和XMLSocket 都是使用 Event.CLOSE 作為連接斷開事件類型的;例如:/ Add an event listenerto be notified when the server disconnects/ the cntsocket.addEventListener(Event.CLOSE, onClose );注意:調用 close()方法是不會觸發(fā) close 事件的,只用服務器主動發(fā)起斷

溫馨提示

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

評論

0/150

提交評論