`
wgcode
  • 浏览: 576872 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

AS3 Socket从零开始

 
阅读更多

大家如果想学AS3 Socket直接在百度里搜一下,会找到很多AS3与Java服务器的例子,很多朋友也许看得很糊涂,也有很多朋友看懂了,但想学更进一步的学习却又不好找教程了。这里我对网上常见的一个例子加点注释,并在原有的基础上加一些改动。

先附上网上找的AS3客户端代码:

package 
{
import flash.display.Sprite;
import flash.events.*;
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;
public const PORT:int = 5678; // 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.addEventListener( Event.CONNECT, onConnect ); 
btnSend.label = "Send Data";
btnSend.emphasized = true;
btnSend.width = 150;
btnSend.move(20, 20);
//addChild(btnSend); btnSend.addEventListener(MouseEvent.CLICK, sendData);
} private function sendData( event:Event )
{ if (! socket.connected)
{
// Connect to the server 
socket.connect( "localhost", PORT );
} trace("send...");
socket.writeUTFBytes("example\n");
socket.flush(); } private function onConnect(event:Event):void
{
trace( "The socket is now connected..." ); } private function onSocketData( eventrogressEvent ):void
{
trace( "Socket received " + socket.bytesAvailable + " byte(s) of data:" );
//trace(socket.readMultiByte(socket.bytesAvailable, "UTF-8")); 

// 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 readMultiByte( ):void
{
socket.readMultiByte(socket.bytesAvailable, "UTF-8");
} private function readNormalProtocol( ):void
{
// Step 5 - process the normal socket messages here now that
// that handshaking process is complete
}
}
}


java 服务端代码

import java.io.*;
import java.net.*;
public class SocketSever {
public static void main(String[] args) throws IOException{
ServerSocket server=new ServerSocket(5678); while (true) {
Socket client=server.accept();
BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out=new PrintWriter(client.getOutputStream());
//while(true){
String str=in.readLine();
System.out.println(str);
out.println("has receive….");
out.flush();
if("end".equals(str))
break;
//}
client.close();
}
}
}


测试的时候flash得先从组件里拉一个Button组件到舞台上,并取个实例名btnSend,然后先运行java服务端,再启动客户端,点击按钮就会看到连接成功的输出。
上面的代码显得有点乱,如果看不懂没关系,我们把上面的代码精简一下。

首先是AS3,如果我们要用Socket,得先导入import flash.net.Socket;这个包。如果我们把这个类当文档类来使用的话,需要导入import flash.display.Sprite;这个包。最后我们得是否连接成功这个事件,还得导入import flash.events.*;这个包。


所以代码如下:

package 
{
import flash.display.Sprite;
import flash.events.*;
import flash.net.Socket;
public class Main
{ public function Main()
{
// constructor code
}
}
}


http://www.shengshiyouxi.com

第二步,我们需要建立一个Socket并作初始化,然后连接到服务器。加上上面的代码如下:

package 
{
import flash.display.Sprite;
import flash.events.*;
import flash.net.Socket;
public class Main extends Sprite
{
private var socket:Socket;
public function Main()
{
socket = new Socket();
socket.connect( "localhost", 5678);
}
}
}


对应的Java服务端代码:

import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) throws IOException{
ServerSocket server=new ServerSocket(5678);//建立一个Socket服务端。
server.accept();//等待客户端连接,如果没有客户端连接,
//程序会停在此行,而不会执行下一行。
System.out.println("客户端已连接!");//当有客户端连接上来的时候,
//打印输出客户端已连接。
}
}


以上代码可以说是最简单的Socket连接。


到这里,服务端代码暂时不管,先把给客户端的Socket加上事件,所以我们在连接到服务器前先加上以下两行代码:

socket.addEventListener(Event.CONNECT, onSocketConnect);//侦听Socket是否已连接上。

socket.addEventListener(Event.CLOSE, onSocketSeverClose);//侦听服务器是否已关闭。

然后写上事件的处理函数。

完整代码如下:

package 
{
import flash.display.Sprite;
import flash.events.*;
import flash.net.Socket;
public class Main extends Sprite
{
private var socket:Socket;
public function Main()
{
socket = new Socket();//新建一个Socket

socket.addEventListener(Event.CONNECT, onSocketConnect);//侦听Socket是否已连接上。
socket.addEventListener(Event.CLOSE, onSocketSeverClose);//侦听服务器是否已关闭。

socket.connect( "localhost", 5678);//连接到服务器
}

private function onSocketConnect(e:Event):void
{
trace("已连接上服务器!");
}

private function onSocketSeverClose(e:Event):void
{
trace("服务器已关闭!");
}
}
}


启动服务端再测试下。发现我们刚连上服务器,服务器就关闭了。所以我们把服务端代码也改一下。

import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) throws IOException{
ServerSocket server=new ServerSocket(5678);//建立一个Socket服务端。
while(true)
{
server.accept();//等待客户端连接,如果没有客户端连接,程序会停在此行,而不会执行下一行。
System.out.println("客户端已连接!");//当有客户端连接上来的时候,打印输出客户端已连接。
}
}
}


这里我只是在等待客户端连接的地方加了个死循环,这们服务端不会在有客户端连上来后自动关闭了,它会一直等等服务端的连接。大家可以再测试一下。

接下来,我们在连接服务器后,向服务器发送一个字符串。发送字符串会用到Socket的write方法和flush方法。write方法只是将要发送的信息存储起来,但没真正发送出去。而flush方法是将要发送的信息发送到数据流里。完整代码如下:

package 
{
import flash.display.Sprite;
import flash.events.*;
import flash.net.Socket;
public class Main extends Sprite
{
private var socket:Socket;
public function Main()
{
socket = new Socket();//新建一个Socket

socket.addEventListener(Event.CONNECT, onSocketConnect);//侦听Socket是否已连接上。
socket.addEventListener(Event.CLOSE, onSocketSeverClose);//侦听服务器是否已关闭。

socket.connect( "localhost", 5678);//连接到服务器
}

private function onSocketConnect(e:Event):void
{
trace("已连接上服务器!");

//新加代码
socket.writeUTFBytes("abc\n");
socket.flush();
//新加代码

}

private function onSocketSeverClose(e:Event):void
{
trace("服务器已关闭!");
}
}
}


注意:发送的字符串必须加上\n不然服务端不能识别已输入已结束,当然,这只是针对于下面我们下面写的服务端代码而言。
对应的服务端代码如下:

import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) throws IOException{
ServerSocket server=new ServerSocket(5678);//建立一个Socket服务端。
while(true)
{

Socket client=server.accept();//等待客户端连接,如果没有客户端连接,程序会停在此行,而不会执行下一行。
System.out.println("客户端已连接!");//当有客户端连接上来的时候,打印输出客户端已连接。
BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));
String str=in.readLine();
System.out.println(str);
}
}
}


接下来,服务端收到客户端发送的消息后也回一个字符串。有发就要有收,客户端也得同步写接收的语句。在此之前,先给客户端添加一个收到信息的事件侦听。

socket.addEventListener( ProgressEvent.SOCKET_DATA, onSocketData );//侦听服务端是否有消息发送过来。

然后写上事件处理函数

private function onSocketData(e:Event):void

{

var str:String = socket.readMultiByte(socket.bytesAvailable, "UTF-8");

trace(str);

}

完整代码如下:

package 
{
import flash.display.Sprite;
import flash.events.*;
import flash.net.Socket;
public class Main extends Sprite
{
private var socket:Socket;
public function Main()
{
socket = new Socket();//新建一个Socket

socket.addEventListener(Event.CONNECT, onSocketConnect);//侦听Socket是否已连接上。
socket.addEventListener(Event.CLOSE, onSocketSeverClose);//侦听服务器是否已关闭。
socket.addEventListener( ProgressEvent.SOCKET_DATA, onSocketData );//侦听服务端是否有消息发送过来。

socket.connect( "localhost", 5678);//连接到服务器
}

private function onSocketConnect(e:Event):void
{
trace("已连接上服务器!");
socket.writeUTFBytes("abc\n");
socket.flush();
}

private function onSocketData(e:Event):void
{
var str:String = socket.readMultiByte(socket.bytesAvailable, "UTF-8");
trace(str);
}

private function onSocketSeverClose(e:Event):void
{
trace("服务器已关闭!");
}
}
}


对应的服务端代码如下:

import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) throws IOException{
ServerSocket server=new ServerSocket(5678);//建立一个Socket服务端。
while(true)
{

Socket client=server.accept();//等待客户端连接,如果没有客户端连接,程序会停在此行,而不会执行下一行。
System.out.println("客户端已连接!");//当有客户端连接上来的时候,打印输出客户端已连接。
BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));
String str=in.readLine();
System.out.println(str);
PrintWriter out=new PrintWriter(client.getOutputStream());
out.println("cba");
out.flush();
}
}
}


小结:到这里算是写了一个简单的Socket连接,并实现了收发功能,如果从来没接触过Socket的朋友可以从上面的实例中学习Socket,通过上面的小实例可以看出,客户端和服务端必须保持一致,很多朋友学Socket的的难处就是不会写服务端程序,所以写出来的程序没法测试。而去下别人写好的服务端程序又没看懂,不知道如何写对应的客户端,所以就停步不学了。这里我建议有以上问题的朋友了解一下Java语言,学会自己学对应的服务端语言,Java语言和AS3差别不大,写服务端也很简单。相对来说要容易一些。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics