2008/02/17 | [转]Flex和java的socket通信
类别(flash As) | 评论(1) | 阅读(2867) | 发表于 01:08

[转]Flex和java的socket通信

服务端:java jdk1.5 (使用工具:eclipse3.2)

客户端:flex 2

(一)连接

目的:实现flex和java的连接
服务端代码:Server1.java

import java.net.*;


import java.io.*;


public class Server1 {



public static void main(String[] args) {



ServerSocket server=null;



try{



server=new ServerSocket(8888);
//x1

System.out.println("服务器套接字已经被创建");



while(true){




System.out.println("等待客户机");



Socket newSocket=server.accept();//x2



System.out.println("已与客户机连接");



}



}catch(IOException ie)



{



System.out.println(ie);



}finally{



Try


{



if(server!=null) server.close();//x3



}catch(IOException ie){}



}



}


}

 

知识点:

X1:使用指定的端口号创建了一服务器套接字对象。

X2:调用accept()方法来等待客户机的连接请求。

X3:关闭服务器套接字。如果一直没有客户机器提出连接请求,服务器套接字将会继续等待。

编译后运行如图:

客户端代码:Client1.mxml

 

<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creati f width="349" height="326">

<mx:Script>


<![CDATA[


import flash.net.Socket; //导入类包


private var socket:Socket;
//创建Socket对象


internal function initApp():void


{


socket=new Socket(); //new出来,这时候才能被使用


socket.connect("127.0.0.1",8888);  //连接服务器


socket.addEventListener(Event.CONNECT,funConnect);


//监听是否连接上服务器


socket.addEventListener(Event.CLOSE,funClose);


//监听服务器是否关闭


}


private function funConnect(event:Event):void


{


myText.text+="已经成功连接到服务器!\n";


}


private function funClose(event:Event):void


{


myText.text+="和服务器断开!\n"


}


]]>

</mx:Script>


<mx:TextArea x="10" y="10" width="327" height="309" id="myText"/>

</mx:Application>

 

界面很简单,就是拖了一个TextArea组件来记录连接状态。

运行结果

http://www.greenidea.net/files/源文件.rar

知识点:

在as3.0中,所有和网络通信有关的类都位于flash.net包中,这里使用的是Socket类对象。

下买你用Socket 对象建立一个新的Socket对象:

var socket:Socket=new Socket();

或者

var socket:Socket=new Socket(“127.0.0.1”,8888);

这条语句设置了服务器地址为127.0.0.1 端口是8888

当指定了了服务器地址和端口,Socket对象将自动开始连接服务器。如果不指定,则需要条用connect方法才开始执行连接动作,比如:

var socket:Socket=new Socket();

socket.connect(“127.0.0.1”,8888);

完成连接动作后,接下来要获取服务端得返回信息。Socket对象利用时间机制来处理服务器端的信息,我们只要给Socket对象添加相关的事件监听函数就可以捕捉到服务器端的信息,Socket对象的事件主要有:

1 Event.CLOSE 连接中断事件。

2 Event.CONNECT 连接状态事件,表示已经成功连接了服务器。

3 IOErrorEvent.IO_ERROR 信息传递错误事件,一般是由服务器地址错误引起的。

4 ProgressEvent.SOCKET_DATA 服务器信息事件,当收到服务器的新信息时被触发。

(二)单向通信

目的:客户端向服务端发消息,服务端将消息显示在屏幕上,不给客户端发送任何数据。

服务器将反复进行一下过程。
1 等待客户机连接请求
2 连接客户机
3 在断开客户机连接之前,接收字符串
4 断开客户机连接
5 返回至第一步

获取与客户机连接的套接字的输入流,过程如下。

Socket socket=server.accept(); //返回与客户机连接的套接字
InputStream is=socket.getInputStream();  //获取套接字的InputStream
InputStreamReader isr=new InputStreamReader(is);
BufferedReader reader= new BufferedReader(isr); //字符串流

服务端代码:Server2.java
=========================================

import java.net.*;
import java.io.*;
public class Server2 {
private BufferedReader reader; //负责输入
private ServerSocket server;   //服务器套接字
private Socket socket;      //套接字
        public Server2(){}  //缺省构造函数
        void startServer()  //启动服务器
        {
                try
                {
                        server=new ServerSocket(8888);    //创建服务器套接字
                        System.out.println("服务器套接字建立完毕");
                        while(true)
                        {
                          System.out.println("等待客户机");
                          socket=server.accept(); //若客户机提出连接请求,与socket连接
                          System.out.println("完成与客户机的连接");
                          //获取socket输入流,“utf-8”这个编码设置是为了更好显示中文
reader=new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));                                                                
getMessage();//读取来自客户机的数据,并输出至画面上
                        }
                }catch(Exception e)
                {
                        System.out.println(e);
                }
        }
        void getMessage()  //读取来自套接字的信息
        {
                try
                {
                        while(true)    //循环
                        {
                                System.out.println("客户机:"+reader.readLine());
                        }
                }catch(Exception e){}
                finally{
                        System.out.println("客户机中断连接");
                        try
                        {
                                if(reader!=null) reader.close(); //关闭套接字的输入流
                                if(socket!=null) socket.close();  //关闭套接字
                                reader=null;
                                socket=null;
                        }catch(Exception e){}
                }
        }
        public  static void main(String[] args)
        {
                Server2 server=new Server2();
                server.startServer();
        }

}

======================================

 

客户端代码:Client2.mxml
==================================================================================

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" fontSize="12" creationComplete="initApp()">
<mx:Script>
        <![CDATA[
                import flash.net.Socket; //导入类包
                import flash.utils.ByteArray;  //ByteArray用来在读取数据的时候使用
                private var socket:Socket=new Socket(); //定义Socket
                //初始化程序
                internal function initApp():void
                {
                        socket.connect("127.0.0.1",8888); //连接服务器
                        socket.addEventListener(Event.CONNECT,funConnect); //监听是否连接
                        socket.addEventListener(Event.CLOSE,funClose); //监听连接关闭
                }
                internal function funConnect(event:Event):void
                {
                        myText.text+="连接已建立 \n";
                }
                internal function funClose(event:Event):void
                {
                        myText.text+="连接已关闭 \n";
                }
                internal function sendMessage(msg:String):void//发送数据对应按钮click事件
                {
                        var message:ByteArray=new ByteArray();//新建一个ByteArray存放数据
                        //写入数据,writeUTFBytes方法,以utf-8格式传数据避免中文乱码
message.writeUTFBytes(msg +"\r\n");       
socket.writeBytes(message);  //写入Socket的缓冲区
                        socket.flush();  //调用flush方法发送信息
                        myText.text+=msg+"\r\n";  //在客户端屏幕上输出发送的内容
                        myInput.text="";  //清空发言框
                }
        ]]>
</mx:Script>
        <mx:TextArea x="10" y="10" width="703" height="263" id="myText"/>
        <mx:TextInput x="10" y="297" width="605" id="myInput"/>
        <mx:Button x="648" y="297" label="发送" id="myBtn" click="sendMessage(myInput.text)"/>
       
</mx:Application>

=======================================
知识点在(一)中已经讲过,就不重复了。
运行效果

 

服务端

客户端

(三)多客户通信

目的:做一个简单的多玩家多线程的猜拳游戏。每个客户机都与服务端的一个套接字进行通信,但是各个客户机之间不进行通信。服务器受到客户机的连接请 求时会创建新的套接字并使其与客户机连接。然后启动线程与客户机进行数据交换。套接字管理器是一个Vector,用于管理套接字的个数及其连接状态。

游戏描述:玩家通过向服务器发送0,1,2这个三个数字,用来代表剪刀,锤包,袱。服务器接到信息后会随机产生0,1,2这三个数字的其中的一个。在客户机上通过比较来进行判断输赢。
先放效果图
服务端:

客户端:

服务端代码:Server4.java
=========================================

import java.net.*;
import java.io.*;
import java.util.*;

public class Server4 {
        private ServerSocket server;
        Vector sManager=new Vector();//管理套接字的Vector
        Random rnd=new Random();//创建随机数的发生器
       
        public Server4(){}
        void startServer() //运行服务器
        {
                try
                {
                        server=new ServerSocket(8888);
                        System.out.println("服务器套接字已创建成功!");
                        while(true)
                        {
                                Socket socket=server.accept();
                                System.out.println("已经与客户机连接");
                                new KBBCom_Thread(socket).start();
                                sManager.add(socket);
                                System.out.println("当前客户机连结数:"+sManager.size());
                        }
                }catch(Exception e){}
        }
        public static void main(String[] args) {
               
                Server4 server=new Server4();
                server.startServer();
        }
        class KBBCom_Thread extends Thread  //与客户机进行通信的线程累
        {
                Socket socket;   //套接字引用变量
                private DataInputStream reader;   //套接字输入流
                private DataOutputStream writer;  //套接字输出流
                KBBCom_Thread(Socket socket)   //构造函数
                {
                        this.socket=socket;
                }
                public void run()
                {
                        try
                        {
                        //获取套接字的输入输出流
                                reader=new DataInputStream(socket.getInputStream());
                                writer=new DataOutputStream(socket.getOutputStream());
                                String msg;
//如果收到客户端发来的数据
                                while((msg=reader.readUTF())!=null)
                                {
                                        //向客户机传送0-2之间的整型随机数
                                                writer.writeUTF(rnd.nextInt(3)+"\n");
                                                writer.flush();
                                                System.out.println("来自客户机:"+msg);

                                }
                        }catch(Exception e){}finally
                        {
                                try
                                {
                                        sManager.remove(socket);  //删除套接字
                                        //关闭输入输出流及套接字
                                        if(reader!=null)reader.close();
                                        if(writer!=null)writer.close();
                                        if(socket!=null)socket.close();
                                        reader=null;
                                        writer=null;
                                        socket=null;
//向屏幕输出相关信息
                                        System.out.println("客户机离开");
                                        System.out.println("当前客户机的连接数:"+sManager.size());
                                }catch(Exception e){}
                        }
                }
        }

}

=====================================
知识点:套接字管理器(Vector)会将于客户机连接的套接字添加到其列表中,在客户机断开连接后,在将相应的套接自从列表中删除,从中可以看出,客户机连接数与列表中添加套接字数目是一致的。
Vector sManager=new Vector();
sManager.add(socket); // 向列表添加套接字
sManager.remove(socket);   //从列表移除套接字
sManager.size();  //获取客户机连接数

 

客户端代码:Client4.mxml

 

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" fontSize="12" creationComplete="initApp()" width="353" height="336">
<mx:Script>
        <![CDATA[
       
                import flash.net.Socket;
                import flash.utils.ByteArray;
                import flash.events.ProgressEvent;
               
                private var socket:Socket=new Socket();
                private var intClient:int;//定义客户端数字出拳
                private var intServer:int; //定义服务端数字出拳
                private var intSY:int;   //定义输赢判断
                private var strClient:String; //客户端文字出拳
                private var strServer:String;   //服务端的文字出拳
                internal function initApp():void
                {
                        socket.connect("127.0.0.1",8888);
                        socket.addEventListener(Event.CONNECT,funConnect);
                        socket.addEventListener(Event.CLOSE,funClose);
                        socket.addEventListener(ProgressEvent.SOCKET_DATA,funSocket);
                       
                }
                internal function funConnect(event:Event):void
                {
                        myText.text+="连接已建立 \n";
                }
                internal function funClose(event:Event):void
                {
                        myText.text+="连接已关闭 \n";
                }
                internal function sendMessage(msg:String):void
                {
                        var message:ByteArray=new ByteArray();
                        message.writeUTF(msg); //发送出拳数字
                        socket.writeBytes(message);
                        socket.flush();
                        intClient=int(msg);
                        switch(intClient)  //将数字转换成文字用于发布到屏幕上
                        {
                                case 0:
                                        strClient="剪刀";
                                        break;
                                case 1:
                                        strClient="锤";
                                        break;
                                case 2:
                                        strClient="包袱";
                                        break;
                        }
                        myText.text+="你出:"+strClient+";  ";
                        myInput.text="";
                }
                internal function funSocket(event:ProgressEvent):void  //接到服务器信息
                {
                        var msg:String="";
                        while(socket.bytesAvailable)
                        {
                                msg=socket.readUTF();
                                intServer=int(msg);
                                intSY=intClient-intServer;  //通过数值判断输赢
                                switch(intServer)  //将数字转换成文字用于发布到屏幕上
                                {
                                        case 0:
                                                strServer="剪刀";
                                                break;
                                        case 1:
                                                strServer="锤";
                                                break;
                                        case 2:
                                                strServer="包袱";
                                                break;
                                }
                                myText.text+="服务器出:"+strServer+";  ";
                                //判断输赢的算法
                                if(intSY>0&&intSY<2)
                                {
                                        myText.text+=" 结果:你赢了 \n";
                                }else if(intClient==intServer)
                                {
                                        myText.text+=" 结果:平手 \n";
                                }else if(intSY<0&&intSY>-2)
                                {
                                        myText.text+=" 结果:你输了 \n";
                                }else if(intSY>=2)
                                {
                                        myText.text+=" 结果:你输了 \n";
                                }else if(intSY<=-2)
                                {
                                        myText.text+=" 结果:你赢了 \n";
                                }
                                myText.verticalScrollPosition = myText.maxVerticalScrollPosition;// myText滚动到最下面
                        }
                               
                }
               
        ]]>
</mx:Script>
        <mx:TextArea x="10" y="32" width="331" height="263" id="myText"/>
        <mx:TextInput x="10" y="303" width="245" id="myInput"/>
        <mx:Button x="273" y="304" label="发送" id="myBtn" click="sendMessage(myInput.text)"/>
        <mx:Label x="10" y="10" text="规则:0代表剪刀;1代表锤;2代表包袱" width="331" fontWeight="bold"/>
       
</mx:Application>

 

附录:
参考资料
《java编程基础,应用与实例》 [韩]徐明浩著 武传海译 人民邮电出版社
《flex 第一步》 邱彦林著 清华大学出版社

http://www.greenidea.net/files/源文件1.rar

(四)一个简单的聊天室

目的:做一个简单的聊天室,用来实现消息广播。

服务端:

客户端:

服务端代码:Server5.java

 

import java.net.*;
import java.io.*;
import java.util.*;
public class Server5 {

        private ServerSocket server;
        private BManager bMan=new BManager();//消息广播者
        public Server5(){}  //构造函数
        void startServer()  //启动服务器
        {
                try{
                        server=new ServerSocket(8888); //创建服务器套接字
                        System.out.println("服务器套接字建立完毕");
                        while(true)
                        {
                                Socket socket=server.accept();//若客户机提请求,socket连接
                                new Chat_Thread(socket).start();//启动线程
                                bMan.add(socket);//添加套接字
                                bMan.sendClientInfo();//使用套接字输出当前聊天人数
                        }
                }catch(Exception e){
                        System.out.println(e);
                }
        }
        public static void main(String[] args) {
                Server5 server=new Server5();
                server.startServer();
        }
        class Chat_Thread extends Thread  //与客户机进行通信的线程累
        {
                Socket socket; //套接字引用变量
                private BufferedReader reader;//引用套接字输入流;
                private PrintWriter writer;//引用套接字输出流;
                Chat_Thread(Socket socket)//构造函数
                {
                        this.socket=socket;
                }
                public void run()
                {
                       
                        try
                        {
                                reader=new BufferedReader(new InputStreamReader(socket.getInputStream(),"utf8"));
                                writer=new PrintWriter(socket.getOutputStream(),true);
                                String msg;
                                //从输出流获取信息
                                while((msg=reader.readLine())!=null)
                                {
                                        System.out.println(msg);
                                        //向所有客户机传送信息
                                        bMan.sendToAll(msg);
                                }
                        }catch(Exception e)
                        {
                               
                        }finally
                        {
                                try {//从消息广播者立标中删除socket
                                        bMan.remove(socket);
                                        if(reader !=null) reader.close();
                                        if(writer !=null) writer.close();
                                        if(socket !=null) socket.close();
                                        reader=null;
                                        writer=null;
                                        socket=null;
                                        System.out.println("客户机离开");
                                        //向所有客户机传送当前连接数
                                        bMan.sendClientInfo();
                                } catch (Exception e) {}
                        }
                       
                }
        }
}

//消息广播者类,继承Vector类
class BManager extends Vector
{
        BManager (){}//构造函数
        void add(Socket sock)
        {
                super.add(sock);//添加套接字
        }
        void remove(Socket sock)
        {
                super.remove(sock);//删除套接字
        }
   //向所有客户机传送消息,同步化方法。
        synchronized void sendToAll(String msg)
        {
                PrintWriter writer=null; //输出流
                Socket sock;  //套接字
                for(int i=0;i<size();i++)  //执行循环
                {
                        sock=(Socket)elementAt(i);//获取第i个套接字
                        try
                        {        //获取第i个套接字输出流
                                writer=new PrintWriter(sock.getOutputStream(),true);
                        }catch(Exception ie){}
//使用第i各套接字输出流,输出消息
                        if(writer!=null) writer.println(msg);
                }
        }

        //向所有客户机发送当前聊天人数
        synchronized void sendClientInfo()
        {
                String info="当前聊天人数:"+size();
                System.out.println(info);
                sendToAll(info);
        }
}

 

知识点:消息广播者类名为Bmanager,他继承了Vector类
class Bmanager extends Vector
{
Bmanager(){}
void add(Socket socket)
{
//添加套接字
}
void remove(Socket socket)
{
//删除套接字
}
synchronized void sendToAll(String msg)
{‘
//使用套接字的输出流,输出消息
}
synchronized void sendClientInfo()
{
//使用套接字的输出流,输出当前聊天人数
}
}

客户端代码:Client5.mxml

 

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" fontSize="12" creationComplete="initApp()" width="369" height="326">
<mx:Script>
        <![CDATA[
                import flash.net.Socket; //导入类包
                import flash.utils.ByteArray;//ByteArray在读取数据时使用
                private var socket:Socket=new Socket();//定义socket
                internal function initApp():void
                {
                        socket.connect("127.0.0.1",8888);//执行连接
                        //监听连接成功事件
                        socket.addEventListener(Event.CONNECT,funConnect);
                        //监听关闭事件
                        socket.addEventListener(Event.CLOSE,funClose);
                        //监听服务器新信息
                        socket.addEventListener(ProgressEvent.SOCKET_DATA,funSocket);
                }
                internal function funConnect(event:Event):void
                {
                        myText.text+="连接已建立 \n";
                }
                internal function funClose(event:Event):void
                {
                        myText.text+="连接已关闭 \n";
                }
                internal function sendMessage(msg:String):void //发送数据到服务器
                {
                        //新建一个ByteArray来存放数据
                        var message:ByteArray=new ByteArray();
                        //写入数据,使用writeUTFBytes以utf8格式传数据,避免中文乱码
                        message.writeUTFBytes(msg+"\n");
                        //写入socket的缓冲区
                        socket.writeBytes(message);
//调用flush方法发送信息
                        socket.flush();
                        //清空消息框
                        myInput.text="";
                }
                //接受服务器信息
                internal function funSocket(event:ProgressEvent):void
                {
                        var msg:String="";
                //循环读取数据,socket的bytesAvailable对象存放了服务器传来的所有数据
                        while(socket.bytesAvailable)
                        {
                                //强制使用utf8格式,避免中文乱码
                                msg+=socket.readMultiByte(socket.bytesAvailable,"utf8");
                                //使用\n换行符号把信息切开
                                var arr:Array=msg.split('\n');
                                for(var i:int=0;i<arr.length;i++)
                                {
                                        if(arr[i].length>1)
                                        {
                                                //正则表达式,回车符
                                                var myPattern:RegExp=/\r/;
                                                //删除回车符
                                                arr[i]=arr[i].replace(myPattern,'');
                                                //在聊天框中输出
                                                myText.text+=arr[i]+"\n";
                                        }
                                }
                                myText.verticalScrollPosition = myText.maxVerticalScrollPosition;//滚动到最下面
                        }
                               
                }
        ]]>
</mx:Script>
        <mx:TextArea x="10" y="42" width="344" height="247" id="myText"/>
        <mx:TextInput x="10" y="297" width="270" id="myInput"/>
        <mx:Button x="288" y="298" label="发送" id="myBtn" click="sendMessage(myName.text+':'+myInput.text)"/>
        <mx:TextInput x="10" y="10" width="344" text="名字" id="myName"/>
       
</mx:Application>
3

评论Comments

日志分类
首页[193]
flash As[107]
有的没的[59]
数码照片[4]
自由世界[19]
blender[4]