Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2161036
  • 博文数量: 556
  • 博客积分: 11457
  • 博客等级: 上将
  • 技术积分: 5973
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-24 22:33
文章分类

全部博文(556)

文章存档

2013年(22)

2012年(74)

2011年(460)

分类: 系统运维

2011-07-11 22:55:16

一个简单的聊天室
 
服务端
开发工具:
eclipse3.6+jdk1.6
  
客户端
开发工具:Flash Builder4  
目的:做一个简单的聊天室,用来实现消息广播。

服务端代码(Server.java)

  1. import java.net.*;
  2. import java.io.*;
  3. import java.util.*;
  4. public class Server {
  5.     private ServerSocket server;
  6.     private BManager bMan=new BManager(); //消息广播者

  7.     public Server(){} //构造函数
  8.     void startServer(){ //启动服务器
  9.         try{
  10.             server=new ServerSocket(8888); //创建服务器套接字
  11.             System.out.println("服务器套接字建立完毕!");
  12.             while(true){
  13.                 Socket socket=server.accept(); //若客户机提出请求,socket连接
  14.                 new Chat_Thread(socket).start(); //启动线程
  15.                 bMan.add(socket); //添加套接字
  16.                 bMan.sendClientInfo(); //使用套接字输出当前聊天人数
  17.             }
  18.         }catch(Exception e){
  19.             System.out.println(e);
  20.         }
  21.     }

  22.     public static void main(String[] args) {
  23.         Server server=new Server();
  24.         server.startServer();
  25.     }
  26. }

  27. class Chat_Thread extends Thread{ //与客户机进行通信的线程类
  28.     Socket socket; //套接字引用变量
  29.     BManager bMan=new BManager();
  30.     private BufferedReader reader; //引用套接字输入流
  31.     private PrintWriter writer; //引用套接字输出流

  32.     Chat_Thread(Socket socket){
  33.         this.socket=socket;
  34.     }

  35.     public void run(){
  36.         try{
  37.             reader=new BufferedReader(new InputStreamReader(socket.getInputStream(),"utf8"));
  38.             writer=new PrintWriter(socket.getOutputStream(),true);
  39.             String msg = null;
  40.             //从输出流获取消息
  41.             while((reader.readLine())!=null)
  42.             {
  43.                 System.out.println(msg);
  44.                 bMan.sendToAll(msg);
  45.             }
  46.         }
  47.         catch(Exception e){
  48.             System.out.println(e);
  49.         }finally{
  50.             try{
  51.                 //从消息广播者中删除socket
  52.                 bMan.remove(socket);
  53.                 if(reader !=null) reader.close();
  54.                 if(writer !=null) writer.close();
  55.                 if(socket !=null) socket.close();
  56.                 reader=null;
  57.                 writer=null;
  58.                 socket=null;
  59.                 System.out.println("客户机离开");
  60.                 //向所有客户机传送当前连接数
  61.                 bMan.sendClientInfo();
  62.             } catch (Exception e) {}
  63.         }
  64.     }
  65. }

  66. //消息广播者类,继承Vector类
  67. class BManager extends Vector{

  68.     BManager(){} //构造函数
  69.     void add(Socket socket){
  70.         super.add(socket); //添加套接字
  71.     }

  72.     void remove(Socket socket){
  73.         super.remove(socket); //删除套接字
  74.     }

  75.     //向所有客户机传送消息,同步化方法
  76.     synchronized void sendToAll(String msg){
  77.         PrintWriter writer=null; //输出流
  78.         Socket socket; //套接字

  79.         for(int i=0;i<size();i++){ //执行循环
  80.             socket=(Socket)elementAt(i); //获取第i个套接字
  81.             try{
  82.                 //获取第i个套接字输出流
  83.                 writer=new PrintWriter(socket.getOutputStream(),true);
  84.             }catch(Exception e){
  85.                 //使用第i个套接字输出流,输出消息
  86.                 if(writer!=null)
  87.                     writer.println(msg);
  88.             }
  89.         }
  90.     }
  91.     //向所有客户机发送当前聊天人数
  92.     synchronized void sendClientInfo(){
  93.         String info="当前聊天人数:"+size();
  94.         System.out.println(info);
  95.     }
  96. }

客户端代码:FlexClient.mxml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <s:Application xmlns:fx=""
  3.              xmlns:s="library://ns.adobe.com/flex/spark"
  4.              xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" creationComplete="initApp()">
  5.     <fx:Declarations>
  6.         
  7.     </fx:Declarations>
  8.     
  9.     <fx:Script>
  10.         <![CDATA[
  11.             
  12.             import flash.net.Socket;
  13.             import flash.utils.ByteArray; //ByteArray在读取数据时使用
  14.             private var socket:Socket=new Socket(); //定义socket
  15.             
  16.             internal function initApp():void
  17.             {
  18.                 socket.connect("127.0.0.1",8888); //执行连接
  19.                 //监听连接成功事件
  20.                 socket.addEventListener(Event.CONNECT,funConnect);
  21.                 //监听关闭事件
  22.                 socket.addEventListener(Event.CLOSE,funClose);
  23.                 //监听服务器新消息
  24.                 socket.addEventListener(ProgressEvent.SOCKET_DATA,funSocket);
  25.             }
  26.             
  27.             
  28.             internal function funConnect(event:Event):void{
  29.                 myText.text="连接已建立...";
  30.                 
  31.             }
  32.             
  33.             internal function funClose(event:Event):void{
  34.                 myText.text="连接已关闭...";
  35.             }
  36.             
  37.             
  38.             internal function sendMessage(msg:String):void{ //发送数据到服务器
  39.                 //新建一个ByteArray来存放数据
  40.                 var message: ByteArray=new ByteArray();
  41.                 //写入数据,使用writeUTFBytes以utf8格式传数据,避免中文乱码
  42.                 message.writeUTFBytes(msg+"n");
  43.                 //写入socket的缓冲区
  44.                 socket.writeBytes(message);
  45.                 //调用flush方法发送信息
  46.                 socket.flush();
  47.                 //清空消息框
  48.                 myInput.text="";
  49.                 
  50.             }
  51.             //接受服务器信息
  52.             internal function funSocket(event:ProgressEvent):void{
  53.                 var msg:String="";
  54.                 //循环读取数据,socket的bytesAvailable对象存放了服务器传来的所有数据
  55.                 while(socket.bytesAvailable)
  56.                 {
  57.                     //强制使用utf8格式,避免中文乱码
  58.                     msg+=socket.readMultiByte(socket.bytesAvailable,"utf8");
  59.                     //使用n换行符号把信息切开
  60.                     var arr:Array=msg.split('n');
  61.                     
  62.                     for(var i:int=0;i<arr.length;i++){
  63.                         //正则表达式,回车符
  64.                         var myPattern:RegExp=/r/;
  65.                         //删除回车符
  66.                         arr[i]=arr[i].replace(myPattern,'');
  67.                         //在聊天框中输出
  68.                         myText.text+=arr[i]+'n';
  69.                     }
  70.                     
  71.                 }
  72.                 myText.verticalScrollPosition=myText.maxVerticalScrollPosition; //滚动到最下面
  73.             }
  74.             
  75.         ]]>
  76.     </fx:Script>
  77.     <mx:TextArea x="10" y="48" width="334" height="250" id="myText"/>
  78.     <s:TextInput x="10" y="18" width="334" id="myName" text="名字"/>
  79.     <s:TextInput x="10" y="297" width="261" height="20" id="myInput"/>
  80.     <s:Button x="270" y="296" label="发送" width="74" id="myBtn" click="sendMessage(myName.text+':'+myInput.text)"/>
  81. </s:Application>

参考资料


 

阅读(3298) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~