24.4.与socket服务器的状态信号交换

问题
我想与服务器进行信号交换以便知道读取的数据内容是什么以及如何进行处理。
解决办法
创建不同的常量来表示协议状态,用这些常量映射与之对应的状态处理函数,在socketData事件处理函数中通过状态映射表调用对应的状态处理函数。
讨论
连接socket服务器需要经过一个完整的信号交换,通常服务器初始化后发送数据给客户端,客户端进行回应,服务器再回应,这个完整的处理过程一直重复直到信号交换完成,这个连接才算建好了。

就像典型的HTTP连接一样,HTTP协议定义了一系列状态代表不同的传输数据,我们现在建立的socket连接也是最原始的无状态的,同样需要建立各种状态以及维护各种状态的函数功能。

解决办法就是创建不同的状态常量代表服务器发送的不同类型的内容,每个状态关联不同的状态处理函数。

连接一个socket服务器需要的信号交换可能有:
当客户端连接到服务器时,服务器立即回应,发送一个整数代表服务器所支持的协议版本。
客户端返回一个整数表示可以通信的协议版本。
服务器发送8自己的认证询问。
客户端发送认证给服务器。
如果客户端的回应不合法或协议不一致或不是规定的信息则关闭连接。

要实现这个信号交换过程,首先要创建代表不同状态的常量,例如建立如下常量:
+展开
-ActionScript
public const DETERMINE_VERSION:int = 0;
public const RECEIVE_CHALLENGE:int = 1;
public const NORMAL:int = 2;

常量设置为什么值并不重要,重要的是这些常量值都应该不同,下一步就是创建代表不同状态的处理函数,如创建readVersion( ), readChallenge( ), 和readNormalProtocol( ),接着要把这些函数与状态常量相关联,如下面的代码:
+展开
-ActionScript
stateMap = new Object( );
stateMap[ DETERMINE_VERSION ] = readVersion;
stateMap[ RECEIVE_CHALLENGE ] = readChallenge;
stateMap[ NORMAL ] = readNormalProtocol;

最后就是在socketData事件处理函数中根据当前的状态调用相应的状态处理函数了,创建currentState变量代表当前状态,根据其值调用对应的处理函数:
+展开
-ActionScript
var processFunc:Function = stateMap[ currentState ];
processFunc( ); // Invoke the appropriate processing function

完整代码如下:
+展开
-ActionScript
package {
import flash.display.Sprite;
import flash.events.ProgressEvent;
import flash.net.Socket;
import flash.utils.ByteArray;
public class SocketExample extends Sprite {
// The state constants to describe the protocol
public const DETERMINE_VERSION:int = 0;
public const RECEIVE_CHALLENGE:int = 1;
public const NORMAL:int = 2;
// Maps a state to a processing function
private var stateMap:Object;
// Keeps track of the current protocol state
private var currentState:int;
private var socket:Socket;
public function SocketExample( ) {
// Initialzes the states map
stateMap = new Object( );
stateMap[ DETERMINE_VERSION ] = readVersion;
stateMap[ RECEIVE_CHALLENGE ] = readChallenge;
stateMap[ NORMAL ] = readNormalProtocol;
// Initialze the current state
currentState = DETERMINE_VERSION;
// Create and connect the socket
socket = new Socket( );
socket.addEventListener( ProgressEvent.SOCKET_DATA, onSocketData );
socket.connect( "localhost", 2900 );
}
private function onSocketData( event:ProgressEvent ):void {
// Look up the processing function based on the current state
var processFunc:Function = stateMap[ currentState ];
processFunc( );
}
private function readVersion( ):void {
// Step 1 - read the version from the server
var version:int = socket.readInt( );
// Once the version is read, the next state is receiving
// the challenge from the server
currentState = RECEIVE_CHALLENGE;
// Step 2 - write the version back to the server
socket.writeInt( version );
socket.flush( );
}
private function readChallenge( ):void {
// Step 3 - read the 8 byte challenge into a byte array
var bytes:ByteArray = new ByteArray( );
socket.readBytes( bytes, 0, 8 );
// After the challenge is received, the next state is
// the normal protocol operation
currentState = NORMAL;
// Step 4 - write the bytes back to the server
socket.writeBytes( bytes );
socket.flush( );
}
private function readNormalProtocol( ):void {
// Step 5 - process the normal socket messages here now that
// that handshaking process is complete
}
}
}

加支付宝好友偷能量挖...


评论(0)网络
阅读(94)喜欢(0)flash/flex/fcs/AIR