Flex Socket与Java通信实例说明(转)

这两天一直在flex的Socket ,现在终于懂了很多。由浅到深一步一步深入。慢慢体会实例,虽然实例都是在网上找的,但也经过了我的测试。我比较喜欢注释,也注释了很多。

跟着走你就会懂。。

Flex端 和 Java端, 先运行Java端启动服务。然后在测试Flex。

实例一:

Flex端:

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

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

creationComplete="initApp()" showCloseButton="true" >

<mx:Script>

<![CDATA[

/**

当运行在服务tocmat上面是,安全沙漏箱问题

运行在本地文件上,正常

Why ?

这个问题,我在web上也测试了的,结果成功了。配置好策略文件

*/

private var socket:Socket;

internal function initApp():void{

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

socket.connect("localhost",8080); //连接服务器 , 参数 host:String,prot:int

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 id="myText" x="10" y="10" width="285" height="250" />

</mx:TitleWindow>

 
Java 端:
package f1.f1_005.socket;
 
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
 
public class Server1 {
 
public static void main(String[] args) {
  ServerSocket server = null;
  try {
   //使用指定的端口号创建了一服务器套接字对象。
   server = new ServerSocket(8888);
   System.out.println("服务器套接字已经被创建");
   while(true){
    System.out.println("等待客户机");
    //调用accept()方法来等待客户机的连接请求。 api:倾听一个连接被使这插座,接受它
    Socket socket = server.accept(); 
    System.out.println("已与客户机连接");
   }
  } catch (IOException e) {
   System.out.println(e);
   e.printStackTrace();
  } finally {
   try {
    if(server!=null)
     server.close(); //关闭服务器套接字。如果一直没有客户机器提出连接请求,服务器套接字将会继续等待。
   } catch (IOException e) {
    e.printStackTrace();
   } 
  }
}
 
}
 
-------------------------------------------------------------------------------------------
实例二:
Flex端:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="initApp();"
>
<mx:Script>
  <![CDATA[
  
   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(e:Event):void{
    myText.text+="连接已建立 \n";
   }
   internal function funClose(e:Event):void{
    myText.text+="连接已关闭 \n";
   }
  
   internal function sendMessage(msg:String):void{ //发送数据对应按钮click事件
    var message:ByteArray = new ByteArray(); //新建一个ByteArray存放数据
    //写入数据,writeUTFBytes方法,以utf-8格式传数据避免中文乱码
    // \r 表示:回车符(ACSII:13 或0x0d),就是我们常说的硬回车。 \n 表示:换行(ACSII:10 或0x0a),就是我们常说的软回车。
    message.writeUTFBytes(msg+"\r\n"); // \r\n是输出的HTML代码换行,客户看到的效果没有换行
    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>
 
Java端:
package f1.f1_005.socket;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
 
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 (IOException e) {
   System.out.println(e);
   e.printStackTrace();
  }
 
}
 
void getMessage(){ //读取来自套接字的信息
  try {
   while(true){ //循环
    String msg = reader.readLine();
    if(msg == null){break;}
    System.out.println("客户机:"+msg);
   }
  } catch (IOException e) {
   e.printStackTrace();
  } finally {
   try {
    System.out.println("客户机中断连接");
    if(reader!=null) reader.close();
    if(socket!=null) socket.close();
    reader = null;
    socket = null;
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
}
 
public static void main(String[] args) {
  Server2 s2 = new Server2();
  s2.StartServer();
}
 
}
-------------------------------------------------------------------------------------------
实例三:
Flex 端:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="353" height="336"
creationComplete="initApp();" >
<mx:Script>
  <![CDATA[
   import mx.utils.ObjectUtil;
   /*  ByteArray
    Class public class ByteArray 
    继承 ByteArray -->  Object 
    Implements IDataInput, IDataOutput 
    Subclasses ByteArrayAsset 
 
    属性:
    bytesAvailable : uint  [] 可从字节数组的当前位置到数组末尾读取的数据的字节数。
    defaultObjectEncoding : uint [] 指示用于新 ByteArray 实例的 ByteArray 类的默认对象编码。
    length : uint ByteArray 对象的长度(以字节为单位)。
    position : uint 将文件指针的当前位置(以字节为单位)移动或返回到 ByteArray 对象中。
 
    方法:
    ByteArray() 创建一个表示填充的字节数组的 ByteArray 实例,以便使用此类中的方法和属性来优化数据存储和数据流。
    writeUTF(value:String):void  将 UTF-8 字符串写入字节流。
    writeUTFBytes(value:String):void  将 UTF-8 字符串写入字节流。
    writeByte(value:int):void  在字节流中写入一个字节。
    writeBytes(bytes:ByteArray, offset:uint = 0, length:uint = 0):void  
     将指定字节数组 bytes(起始偏移量为 bytes,从 0 开始的索引)中包含 length 个字节的字节序列写入字节流。
     offset:uint (default = 0) — 从 0 开始的索引,表示在数组中开始写入的位置。
   
   
    
    Socket
    Class public class Socket 
    继承 Socket  EventDispatcher  Object 
    Implements IDataInput, IDataOutput 
    类使 代码可以建立套接字连接并读取和写入原始二进制数据。它与 XMLSocket 类似,但没有指定接收或传输的数据格式。
   
    属性:
    bytesAvailable : uint [] 输入缓冲区中可读取的数据的字节数。
    connected : Boolean  [] 指示此 Socket 对象目前是否已连接。
    objectEncoding : uint 在写入或读取对象时,控制所使用的 AMF 的版本。
   
    方法:
    Socket(host:String = null, port:int = 0) 创建一个 Socket 对象。
    close():void 关闭套接字。 Socket 
    connect(host:String, port:int):void 将套接字连接到指定的主机和端口。 Socket 
    dispatchEvent(event:Event):Boolean 将事件调度到事件流中。 EventDispatcher 
    flush():void 对套接字输出缓冲区中积累的所有数据进行刷新。 
    readByte():int 从套接字读取一个带符号字节。 Socket 
       readBytes(bytes:ByteArray, offset:uint = 0, length:uint = 0):void 从套接字读取 length 参数所指定的数据的字节数。 
    readMultiByte(length:uint, charSet:String):String 使用指定的字符集,从该字节流读取一个多字节字符串。
     readUnsignedByte():uint 从套接字读取一个无符号字节。 Socket 
       readUnsignedInt():uint 从套接字读取一个无符号的 32 位整数。 Socket 
       readUnsignedShort():uint   从套接字读取一个无符号的 16 位整数。 
    readUTF():String   从套接字读取一个 UTF-8 字符串。 Socket 
       readUTFBytes(length:uint):String 从套接字读取 length 参数所指定的 UTF-8 数据的字节数,并返回一个字符串。 
     writeByte(value:int):void  将一个字节写入套接字。 Socket 
       writeBytes(bytes:ByteArray, offset:uint = 0, length:uint = 0):void 从指定的字节数组写入一系列字节。 
     writeMultiByte(value:String, charSet:String):void 使用指定的字符集,从该字节流写入一个多字节字符串。 Socket 
       writeObject(object:*):void 以 AMF 序列化格式将一个对象写入套接字。 Socket 
       writeShort(value:int):void 将一个 16 位整数写入套接字。 Socket 
       writeUnsignedInt(value:uint):void 将一个无符号的 32 位整数写入套接字。 Socket 
       writeUTF(value:String):void 将以下数据写入套接字:一个无符号 16 位整数,它指示了指定 UTF-8 字符串的长度(以字节为单位),后面跟随字符串本身。 Socket 
       writeUTFBytes(value:String):void 将一个 UTF-8 字符串写入套接字。 
 
    事件: Event.XX
    close 在服务器关闭套接字连接时调度。 Socket 
       connect 在建立网络连接后调度。 Socket 
       deactivate Flash Player 或 AIR 应用程序失去操作系统焦点并变为非活动状态时调度。 EventDispatcher 
       ioError 在出现输入/输出错误并导致发送或加载操作失败时调度。 Socket 
       securityError 若对 Socket.connect() 的调用尝试连接到调用方安全沙箱外部的服务器或端口号低于 1024 的端口,则进行调度。 Socket 
       socketData 在套接字接收到数据后调度。 
 
    */
   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(e:Event):void{
    myText.text+="连接已建立 \n";
   }
   internal function funClose(e:Event):void{
    myText.text+="连接已关闭 \n";
   }
  
   private 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(e: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滚动到最下面
                    myText.verticalScrollPosition = myText.maxVerticalScrollPosition;
    }
   }
  
  
  ]]>
</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 端:
package f1.f1_005.socket;
 
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
import java.util.Vector;
 
/**
知识点:套接字管理器(Vector)会将于客户机连接的套接字添加到其列表中,在客户机断开连接后,在将相应的套接自从列表中删除,从中可以看出,客户机连接数与列表中添加套接字数目是一致的。
Vector sManager=new Vector();
sManager.add(socket);  // 向列表添加套接字
sManager.remove(socket);   //从列表移除套接字
sManager.size();  //获取客户机连接数
*/
public class Server3 {
 
private ServerSocket server;
//Vector 类提供了实现可增长数组的功能,随着更多元素加入其中,数组变的更大。
Vector sManager = new Vector(); //管理套接字的Vector
Random rnd = new Random(); //创建随机数的发生器
 
public Server3(){}
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 (IOException e) {
   e.printStackTrace();
  }
}
 
public static void main(String[] args) {
  Server3 server=new Server3();
        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 (IOException e) {
    e.printStackTrace();
   } 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 (IOException e) {
     e.printStackTrace();
    }
   }
  
  }
}
 
}
 
 
-------------------------------------------------------------------------------------------
实例四:
Flex 端:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="initApp();" width="369" height="326">
<mx:Script>
  <![CDATA[
   private var socket:Socket = new Socket();
  
   internal function initApp():void
   {
    socket.connect("192.168.0.56",8888);//执行连接 //localhost==127.0.0.1
                //监听连接成功事件
                socket.addEventListener(Event.CONNECT,funConnect);
                //监听关闭事件
                socket.addEventListener(Event.CLOSE,funClose);
                //监听服务器新信息
                socket.addEventListener(ProgressEvent.SOCKET_DATA,funSocket);
   }
   internal function funConnect(e:Event):void
   {
    myText.text+="连接已建立 \n";
   }
   internal function funClose(e: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(e:Event):void
   {
    var msg:String="";
             //循环读取数据,socket的bytesAvailable对象存放了服务器传来的所有数据
             while(socket.bytesAvailable)
             {
              //强制使用utf8格式,避免中文乱码
              msg += socket.readMultiByte(socket.bytesAvailable,"utf8"); //UTF-8
              //使用\n换行符号把信息切开
              var arr:Array = msg.split("\n");
              for(var i:int=0;i<arr.length;i++)
              {
               if(arr[i].length > 0){
                //正则表达式,回车符
                var myPattern:RegExp=/\r/;
                //删除回车符
                arr[i] = arr[i].replace(myPattern,"");
                //在聊天框中输出
                myText.text+=arr[i]+"\n";
               }
              }
              myText.horizontalScrollPosition = myText.maxVerticalScrollPosition; //滚动到最下面
             }
   
   }
  
  ]]>
</mx:Script>
<mx:TextInput x="10" y="10" width="344" text="名字" id="myName"/>
<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:Application>
 
Java 端:
package f1.f1_005.socket;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;
 
public class Server4 {
 
private ServerSocket server;
private BManager bMan=new BManager();  //消息广播
 
public Server4() {}
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 (IOException e) {
   System.out.println(e);
   e.printStackTrace();
  }
 
}
 
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"));//utf8UTF-8
    //PrintWriter 的第二个参数:autoFlush - A boolean; if true, the println, printf, or format methods will flush the output buffer
    writer = new PrintWriter(socket.getOutputStream(),true);
    String msg;
    //从输出流获取信息
    while((msg=reader.readLine()) != null){
     System.out.println(msg);
                    //向所有客户机传送信息
     bMan.sendToAll(msg);
    }
   } catch (IOException e) {
    e.printStackTrace();
   } 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 (IOException e) {
     e.printStackTrace();
    }
   }
  }
 
 
}
 
public static void main(String[] args) {
  Server4 server=new Server4();
        server.startServer();
}
 
}
 
//消息广播者类,继承Vector类
class BManager extends Vector{ //消息广播者类,继承Vector类
BManager (){}//构造函数
 
void add(Socket socket) {
  super.add(socket);  //添加套接字
}
 
void remove(Socket socket) {
  super.remove(socket); //删除套接字
}
 
//向所有客户机传送消息,同步化方法。
synchronized void sendToAll(String msg) {
  PrintWriter writer = null; //输出流
  Socket socket;
  for (int i = 0; i < size(); i++) {
   socket = (Socket)elementAt(i);
   try {
    //获取第i个套接字输出流
    writer = new PrintWriter(socket.getOutputStream(),true);  //就是因为掉了个ture ,客服端就显示不了数据
   } catch (IOException e) {
    e.printStackTrace();
   }
   //使用第i各套接字输出流,输出消息
   if(writer!=null)  writer.println(msg);
  }
}
 
//向所有客户机发送当前聊天人数
synchronized void sendClientInfo(){
  String info = "当前聊天人数:"+size();
  System.out.println(info);
        sendToAll(info);
}
}
 
-------------------------------------------------------------------------------------------
实例五:
Flex 端:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" fontSize="12" 
creationComplete="initApp()" width="547" height="326" >
<mx:Script>
<![CDATA[
  import mx.controls.Alert;
  import com.flex.f018.MyLogin;
  import flash.net.Socket;
  import flash.utils.ByteArray;
  import mx.managers.PopUpManager;
  import flash.events.MouseEvent;
 
  private var strPD:String="22--";//协议头判断
  private var socket:Socket=new Socket();
  private var win:MyLogin=new MyLogin();
  internal function initApp():void
  {
   win.width=240;
   win.height=94;
   win.x=153;
   win.y=116;
   PopUpManager.addPopUp(win,this,true);
   win.myBtn.addEventListener(MouseEvent.CLICK,funBtn);
   //socket.connect("127.0.0.1",8888);
   //socket.addEventListener(ProgressEvent.SOCKET_DATA,funSocket);
  }
  internal function funChoose(event:MouseEvent):void
  {
   var item:Object=myList.selectedItem;
   strPD="33--"+item+"--";
  }
  internal function funBtn(event:MouseEvent):void
  {
   myName.text=win.txtName.text;
   PopUpManager.removePopUp(win);
   socket.connect("127.0.0.1",8888);
   socket.addEventListener(Event.CONNECT,funConnect);
   //监听关闭事件
   socket.addEventListener(Event.CLOSE,funClose);
   socket.addEventListener(ProgressEvent.SOCKET_DATA,funSocket);
   myList.addEventListener(MouseEvent.CLICK,funChoose);
   sendMessage("11"+myName.text);
 
  }
 
  internal function funConnect(event:Event):void
  {
   trace("[log] funConnect:连接已建立");
   myText.text+="连接已建立 \n";
   //sendMessage("11"+myName.text);
  }
  internal function funClose(e:Event):void
  {
   trace("[log] funClose:连接已关闭");
   myText.text+="连接已关闭 \n";
  }
  internal function sendMessage(msg:String):void
  {
   trace("[log] sendMessage :" + msg);
   var message:ByteArray=new ByteArray();
   message.writeUTFBytes(msg+"\n");
   socket.writeBytes(message);
   socket.flush();
   myInput.text="";
  }
  internal function funSocket(event:ProgressEvent):void
  {
   trace("[log] funSocket ");
   var msg:String="";
   var pd:String=""; //协议判断字符
   var intCD:int=0;
   while(socket.bytesAvailable)
   {
   
    msg=socket.readMultiByte(socket.bytesAvailable,"utf8");
    trace("[log] funSocket msg:"+msg);
    pd=msg.substring(0,2);
    intCD=msg.length;//获取字符串长度  
    if(pd=="11") // 11--UserName
    { // 11开头表示更新用户列表
    
     msg=msg.substring(4,intCD);
     var myPattern2:RegExp=/\r\n/;//清除回车和换行符
     //var myPattern3:RegExp=/\n/;
     msg=msg.replace(myPattern2,'');
     //msg=msg.replace(myPattern3,'');
     var arrList:Array=msg.split("--");
     arrList.unshift("所有人");
     trace("[log] 11 arrList : " +arrList);
     myList.dataProvider=arrList;
    
    }else if(pd=="22") // 22UserNamed登录了
    {
     msg=msg.substring(2,intCD);
     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;//滚动到最下面
    }else if(pd=="33")
    {
    }
    else if(pd=="44") // 44当前在线认识:Size人
    {
     msg=msg.substring(2,intCD);
     labCount.text=msg;
    }
    else
    {}
   }
   
  }
]]>
</mx:Script>
<mx:TextArea x="10" y="10" width="344" height="279" id="myText"/>
<mx:TextInput x="103" y="297" width="357" id="myInput"/>
<mx:Button x="468" y="298" label="发送" id="myBtn" click="sendMessage(strPD+myName.text+'--'+myInput.text)"/>
<mx:Label x="10" y="299" width="85" textAlign="right" id="myName" fontWeight="bold" color="#ffffff"/>
<mx:List x="367" y="42" height="247" id="myList" width="170"></mx:List>
<mx:Label x="367" y="13" width="170" id="labCount"/>
 
</mx:Application>
 
Java 端:
package f1.f1_005.socket;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
 
/*
* 自定义的协议 
* 收到消息: 11开头表示新加入了聊天用户;22开头表示公聊;33开头表示私聊
* 发送消息:11开头表示更新用户列表;22开头表示发送到屏幕上;44发送在线人数
*/
public class Server5 {
 
private ServerSocket server;
private BManager5 bMan = new BManager5();  //消息广播者
//Map接口的HashMap类,元素拥有固定key值,key值不重复,这里用来存放在线用户
Map<Socket, String> clientList = new HashMap<Socket, String>();
public Server5(){} //构造函数
public void startServer(){  //启动服务器
  try {
   server = new ServerSocket(8888); //创建服务器套接字
   System.out.println("服务器套接字建立完毕");
   while(true)
   {
    Socket socket = server.accept(); //若客户机提出请求,使用socket进行连接
    //String strIP = socket.getInetAddress().toString();//登陆者的ip
    new Chat_Thread(socket).start(); //启动线程
    bMan.add(socket); //添加套接字
    bMan.sendClientInfo(); //使用套接字输出当前聊天人数
    //funList(clientList);
    //bMan.sendToAll(strIP+"/加入聊天室");
   }
  } catch (IOException e) {
   System.out.println(e);
   e.printStackTrace();
  }
 
}
 
class Chat_Thread extends Thread{  //与客户机进行通讯的线程类
  private Socket socket; //x1
  private BufferedReader reader; //套接字输入流;
  private PrintWriter writer; //套接字输出流
 
  Chat_Thread(Socket socket){
   this.socket = socket; //this.socket就是x1处的socket
  }
 
  public void run(){
   try {
    reader=new BufferedReader(new InputStreamReader(socket.getInputStream(),"utf8"));
    //PrintWriter 的第二个参数:autoFlush - A boolean; if true, the println, printf, or format methods will flush the output buffer
    writer=new PrintWriter(socket.getOutputStream(),true);
    String msg; //msg获取消息
    // while 这样写,在关闭浏览器的时候,会进入finally  
    while((msg=reader.readLine())!=null) //while(true){
    {
//     if((msg=reader.readLine())!=null){
      System.out.println(msg); //服务器屏幕输出消息
      String str = msg.substring(0,2); //截取前两个个字符
      int a=Integer.parseInt(str); //强制转换成int
      String[] arrMsg=msg.split("--"); //将获取的消息以"--"符号为标志分解成数组
      switch(a){
       case 11: //当消息以11开头的时候,将登陆者的信息储存到hashmap之中,并向客户端发送新的在线列表
        String strName = msg.substring(2);  //获取登陆者名字,消息格式“11eko”
        System.out.println(strName+"登陆了"); //服务器屏幕输出谁登陆了
        bMan.sendToAll("22"+strName+"登陆了"); //广播谁登陆了
        clientList.put(this.socket,strName); //加入到HashMap中
        funList(clientList); //广播在线列表
        break;
       case 22: //当消息以22开头的时候,表示公聊,内容为“22--eko--内容”
        System.out.println("公聊");
        //构造消息,arrMsg[0]=消息头,arrMsg[1]消息发送者,arrMsg[2]消息内容
        msg=arrMsg[0]+arrMsg[1]+"说:"+arrMsg[2];
        bMan.sendToAll(msg);
        break;
       case 33: //消息以33开头时候,内容为“33--sandal--eko--内容”
        //arrMsg[1]为说话对象,arrMsg[2]为说话人,arrMsg[3]为消息内容
        if(arrMsg[1].equals("所有人"))//当说话对象为"所有人"的时候
        {
         //构造消息"22eko说:内容"
         msg="22"+arrMsg[2]+"说:"+arrMsg[3];
         //向所有人发送消息
         bMan.sendToAll(msg);
        }else //其他情况就是向具体的某个人发送消息了
        {
         Socket socketOne=new Socket();
         System.out.println("私聊");
         Set set = clientList.keySet(); //使用keySet方法获取所有key值
         Iterator it = set.iterator(); //使用Iterator(迭代器)来遍历数据
         while (it.hasNext()) { //返回是否还有没被访问过的对象
          Object ok=it.next(); //返回下一个没被访问过的对象
          Object ov=clientList.get(ok); //get方法返回拥有key的元素
          if(ov.equals(arrMsg[1])) //如果在client中找到"消息发给谁"的时候,发给对方??????
          {
           socketOne=(Socket)ok; //强制转换成key值类型;
           bMan.sendToONE(socketOne,"22(悄悄话)"+arrMsg[2]+"对你说:"+arrMsg[3]);
          }else if(ov.equals(arrMsg[2])) //如果在client中找到"发消息的人"的时候,发给他自己???????
          {
           socketOne=(Socket)ok;
           bMan.sendToONE(socketOne,"22(悄悄话)你对"+arrMsg[1]+"说:"+arrMsg[3]);
          }
         }
        }
        break;
      }
//     }
    }
   } catch (IOException e) {
    e.printStackTrace();
   } finally {
    try {
     if(clientList.containsKey(socket))
     {
      bMan.sendToAll("22"+clientList.get(socket)+"离开了...");//广播消息,谁离开了
      clientList.remove(socket); //删除socket
      funList(clientList); //广播在线列表
     }
     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) {}
   }
  }
 
  void funList(Map clientList) // 广播在线列表???????б?
  {
   String strList = ""; //在线列表
   Set set = clientList.keySet(); //使用keySet方法获取所有key值
   System.out.println(set);
   Iterator it = set.iterator(); //使用Iterator(迭代器)来遍历数据
   System.out.println(it);
   while (it.hasNext()) { //把用户名称发给在线所有客户端 
    strList+="--";
    strList+=clientList.get(it.next());
   }
   bMan.sendToAll("11"+strList);
  }
}
 
public static void main(String[] args){
  Server5 server = new Server5();
  server.startServer();
}
}
 
class BManager5 extends Vector
{
BManager5(){}
void add(Socket socket){ 
  super.add(socket);
}
 
void remove(Socket socket)
{
  super.remove(socket);
}
 
synchronized void sendToAll(String msg){ //给所有人广播函数
  PrintWriter writer = null ;
  Socket socket;
  for (int i = 0; i < size(); i++) { //执行循环
   socket = (Socket)elementAt(i); //获取第i个套接字
   try {
    //获取第i个套接字输出流
    writer = new PrintWriter(socket.getOutputStream(),true);
   } catch (IOException e) { }
   System.out.println(msg);
   //使用第i各套接字输出流,输出消息
   if(writer!=null)
    writer.println(msg);
  }
}
 
synchronized void sendToONE(Socket socket,String msg){ //私聊函数
  PrintWriter writer=null;
  Socket sock;
  for(int i=0;i<size();i++)
  {
   sock = (Socket)elementAt(i);
   if(sock == socket){ //与给所有人广播函数类似,仅加入了判断,只有当socket管理器中的socket等于传入的socket的时候才发送消息
    try
    {
     writer=new PrintWriter(sock.getOutputStream(),true);
    }catch(Exception ie){}
    if(writer!=null)writer.println(msg);
   }
  }
}
 
synchronized void sendClientInfo(){
  int a = size();
  String msg ="44当前在线人数:" +a+"人";
  sendToAll(msg);
}
 
}

Flex Socket与Java通信实例说明(转)的更多相关文章

  1. Socket、RPC通信实例,简单版本,仅供查阅

    TCP/IP Socket 如果使用TCP协议来传递数据,客户端和服务器端需要分别经过以下步骤: server: 创建socket对象 - bind(绑定socket到指定地址和端口) - liste ...

  2. 安卓App和java通信实例

    服务器:放在电脑上运行的java文件 import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.I ...

  3. c++ socket C/S通信实例

    具体的实例连接: 客户端项目连接:http://pan.baidu.com/s/1c2MndTI 服务端项目连接:http://pan.baidu.com/s/1i4DFkFV 用vs2013打开,服 ...

  4. Flex通信-与Java实现Socket通信实例

    Flex通信-与Java实现Socket通信实例  转自:http://blessht.iteye.com/blog/1136888 博客分类: Flex 环境准备 [服务器端] JDK1.6,“ja ...

  5. Flex通信-Java服务端通信实例

    转自:http://blessht.iteye.com/blog/1132934Flex与Java通信的方式有很多种,比较常用的有以下方式: WebService:一种跨语言的在线服务,只要用特定语言 ...

  6. Java Socket 通信实例 - 转载

    基于Tcp协议的简单Socket通信实例(JAVA)   好久没写博客了,前段时间忙于做项目,耽误了些时间,今天开始继续写起~ 今天来讲下关于Socket通信的简单应用,关于什么是Socket以及一些 ...

  7. 基于Tcp协议的简单Socket通信实例(JAVA)

    好久没写博客了,前段时间忙于做项目,耽误了些时间,今天开始继续写起~ 今天来讲下关于Socket通信的简单应用,关于什么是Socket以及一些网络编程的基础,这里就不提了,只记录最简单易懂实用的东西. ...

  8. Java Socket通信实例

    一.简单的客户端与服务器一对一连接: Socket通信的步骤: 1.创建ServerSocket和Socket 2.打开连接到Scket的输入/输出流 3.按照协议对Socket进行读/写操作 4.关 ...

  9. UDP协议网络Socket编程(java实现C/S通信案例)

    我的博客园:https://www.cnblogs.com/chenzhenhong/p/13825286.html 我的CSDN博客:https://blog.csdn.net/Charzous/a ...

随机推荐

  1. 多线程的CAS

    CAS Compare And Swap (Compare And Exchange) / 自旋 / 自旋锁 / 无锁 独占锁:独占锁是一种悲观锁,synchronized就是一种独占锁,会导致其它所 ...

  2. Maven+JSP+Servlet+JDBC+Mysql实现的dbExper宾馆管理系统

    本文存在视频版本,请知悉 项目简介 项目来源于:https://github.com/mafulong/databaseExper-hotelMaster 这次分享的也是毕设或课程设计选择一样很多的宾 ...

  3. F版本SpringCloud 2—什么是SpringCloud?SpringCloud版本选择

    引言:搭建微服务架构就像是买电脑,使用SpringCloud就是在买品牌机. 前言 昂,美好的天气里,不想直接说技术,给小伙伴萌看看傍晚的天空吧. -- 能找到天上的北极星吗? 上一篇文章中,通过一个 ...

  4. 【限时免费】AppBoxCore - 细粒度权限管理框架(EFCore+RazorPages+async/await)!

    目录 前言 全新AppBoxCore RazorPages 和 TagHelpers 技术架构 页面处理器和数据库操作的异步调用 Authorize特性和自定义权限验证过滤器 Authorize登录授 ...

  5. vue one one

    目录 Vue 渐进式 JavaScript 框架 一.走进Vue 1.what -- 什么是Vue 2.why -- 为什么要学习Vue 3.special -- 特点 4.how -- 如何使用Vu ...

  6. Prism 源码解读2-View的加载和控制

    介绍 上一篇介绍了Region,这一篇跟Region息息相关,讲一下Region中View的加载方式及控制. 4.ViewDiscovery 在创建好Region后需要将View添加到Region中. ...

  7. javascript正则表达式入门先了解这些

    前言 此内容由学习<JavaScript正则表达式迷你书(1.1版)>整理而来(于2020年3月30日看完).此外还参考了MDN上关于Regex和String的相关内容,还有ECMAScr ...

  8. 走近源码:Redis如何清除过期key

    "叮--",美好的周六就这么被一阵钉钉消息吵醒了. 业务组的同学告诉我说很多用户的帐号今天被强制下线.我们的帐号系统正常的逻辑是用户登录一次后,token的有效期可以维持一天的时间 ...

  9. 谷歌2019 学术指标发榜:CVPR首次进入Top 10,何恺明论文引用最高!

    [导读]今天,谷歌发布了2019最新版学术指标,对收录的会议和期刊的影响力进行排名.AI类的多个顶会进入榜单Top 100,CVPR更是进入前10,而何恺明的"深度残差网络"单篇引 ...

  10. 【Pytest01】全网最全最新的Pytest框架快速入门

    一.Pytest简介pytest是一个非常成熟的全功能的Python测试框架,主要有一下几个特点:1.简单灵活,容易上手,支持参数化2.能够支持简单的单元测试和复杂的功能测试,还可以用来做seleni ...