用flash去開發(fā)應用,,免不了網(wǎng)絡通訊,特別是網(wǎng)絡游戲,需要用到即使通訊。
as3提供了兩個支持即時通訊的類:XMLSocket和Socket,前者其實是只支持發(fā)送字符串,而后者就強大多了,支持發(fā)送字節(jié),相對來說比較底層,而這也給我們更多的發(fā)揮空間。
其實,flash?socket的網(wǎng)絡底層接受數(shù)據(jù),就以與C++服務器通訊為例子,C++服務器一般會發(fā)一段一段數(shù)據(jù)過來,每段數(shù)據(jù)都是由一定結(jié)構(gòu)組成的,一般是消息頭和消息頭,然后再逐步分層解析。
在這里,我只說接受網(wǎng)絡底層的處理,一般一段數(shù)據(jù)前面,還有有一個4個字節(jié)左右的數(shù)據(jù),表示的是后面網(wǎng)絡流里的數(shù)據(jù)有多少....
看下簡單示意圖
?
我們網(wǎng)絡底層需要做的處理,就是根據(jù)頭4個字節(jié)判斷出后面的數(shù)據(jù)大小,然后把那一整塊取出來,拋給上層解析,然后又在不停地偵聽,收到指定大小之后,又做類似的操作,下面看詳細的代碼
/**
* @(#)NetBottomHandle.as
* @author soda.C mail:sujun10@21cn.com
* @version 1.0
* <br>Copyright (C), 2007 soda.C
* <br>This program is protected by copyright laws.
* <br>Program Name:GameHall
* @data 2008-3-20
*/
package org.sujun.net
{
import flash.net.Socket;
import flash.events.ProgressEvent;
import flash.utils.ByteArray;
/**
* socket數(shù)據(jù)流里的底層處理,從這里接受到服務器的數(shù)據(jù),滿足條件后就會拋出需要的字節(jié)
* 對數(shù)據(jù)流的數(shù)據(jù),不做任何處理
*/
public class NetBottomHandle
{
private var socket :Socket;
private var listener :Function; //接受網(wǎng)絡解析出來的數(shù)據(jù)
private var msgLen :int; //消息長度
private var msgLenMax :int; //收到的消息最大長度
private var headLen :int; //消息頭長度
private var isReadHead :Boolean; //是否已經(jīng)讀了消息頭
private var bytes :ByteArray; //所讀數(shù)據(jù)的緩沖數(shù)據(jù),讀出的數(shù)據(jù)放在這里
public function NetBottomHandle()
{
msgLenMax = 5000; //5000字節(jié)
headLen = 4; //4個字節(jié)
bytes = new ByteArray();
}
/**
* 設置一個網(wǎng)絡通訊實例
*/
public function setSocket(socket:Socket):void
{
this.socket = socket;
//監(jiān)聽......
socket.addEventListener(ProgressEvent.SOCKET_DATA, onServerData,false,0,true);
}
/**
* 接受在網(wǎng)絡層里收到的原始數(shù)據(jù),傳遞過來的數(shù)據(jù)為描述長度,以及ByteArray對象functon(len,bytes)
* @param listener:接受數(shù)據(jù)函數(shù)
*/
public function receiverNetData(listener:Function):void
{
this.listener = listener;
}
/**
* 服務器發(fā)送過來的數(shù)據(jù)都在這里接收,最底層的
*/
private function onServerData(event:ProgressEvent):void
{
//一有收到數(shù)據(jù)的事件,就通過這個函數(shù)進行檢驗
parseNetData();
}
/**
* 解析網(wǎng)絡數(shù)據(jù)流
*/
private function parseNetData():void
{
//如果需要讀信息頭
if(isReadHead)
{
if(socket.bytesAvailable >= headLen)
{
//讀出指示后面的數(shù)據(jù)有多大
msgLen = socket.readUnsignedInt();
isReadHead = false;
}
}
//如果已經(jīng)讀了信息頭,則看能不能收到滿足條件的字節(jié)數(shù)
if(!isReadHead && msgLen <= msgLenMax)
{
//如果為0,表示收到異常消息
if(msgLen == 0)
{
//一般消息長度為0的話,表示與服務器出了錯,或者即將被斷開等,通知客戶端,進行特別處理
listener(msgLen,null);
return ;
}
//數(shù)據(jù)流里的數(shù)據(jù)滿足條件,開始讀數(shù)據(jù)
if(socket.bytesAvailable >= msgLen)
{
//指針回歸
bytes.position = 0;
//取出指定長度的網(wǎng)絡字節(jié)
socket.readBytes(bytes, 0, msgLen);
listener(msgLen,bytes);
}
}
isReadHead = false;
//如果數(shù)據(jù)流里還滿足讀取數(shù)據(jù)條件,繼續(xù)讀取數(shù)據(jù)
if(socket.bytesAvailable >= headLen)
{
parseNetData();
}
}
}
}
?
更多文章、技術交流、商務合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

