(四)一个简单的聊天室
目的:做一个简单的聊天室,用来实现消息广播。
服务端代码: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+="连接已建立 ";
- }
- internal function funClose(event:Event):void
- {
- myText.text+="连接已关闭 ";
- }
- internal function sendMessage(msg:String):void //发送数据到服务器
- {
- //新建一个ByteArray来存放数据
- var message:ByteArray=new ByteArray();
- //写入数据,使用writeUTFBytes以utf8格式传数据,避免中文乱码
- message.writeUTFBytes(msg+" ");
- //写入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");
- //使用换行符号把信息切开
- var arr:Array=msg.split(' ');
- for(var i:int=0;i<arr.length;i++)
- {
- if(arr[i].length>1)
- {
- //正则表达式,回车符
- var myPattern:RegExp=/ /;
- //删除回车符
- arr[i]=arr[i].replace(myPattern,'');
- //在聊天框中输出
- myText.text+=arr[i]+" ";
- }
- }
- 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>