收获于途中......

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

服务端:

服务端代码: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" />
        <mx:TextInput x="10" y="297" width="270" />
        <mx:Button x="288" y="298" label="发送" click="sendMessage(myName.text+':'+myInput.text)"/>
        <mx:TextInput x="10" y="10" width="344" text="名字" />
</mx:Application>
posted on 2010-01-04 17:26  秋意正浓  阅读(1226)  评论(0编辑  收藏  举报