一个简单的聊天室
服务端:
开发工具:
eclipse3.6+jdk1.6
客户端:
开发工具:Flash Builder4
目的:做一个简单的聊天室,用来实现消息广播。
服务端代码(Server.java)
- import java.net.*;
- import java.io.*;
- import java.util.*;
- public class Server {
- private ServerSocket server;
- private BManager bMan=new BManager(); //消息广播者
- public Server(){} //构造函数
- 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) {
- Server server=new Server();
- server.startServer();
- }
- }
- class Chat_Thread extends Thread{ //与客户机进行通信的线程类
- Socket socket; //套接字引用变量
- BManager bMan=new BManager();
- 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 = null;
- //从输出流获取消息
- while((reader.readLine())!=null)
- {
- System.out.println(msg);
- bMan.sendToAll(msg);
- }
- }
- catch(Exception e){
- System.out.println(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 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(Exception e){
- //使用第i个套接字输出流,输出消息
- if(writer!=null)
- writer.println(msg);
- }
- }
- }
- //向所有客户机发送当前聊天人数
- synchronized void sendClientInfo(){
- String info="当前聊天人数:"+size();
- System.out.println(info);
- }
- }
客户端代码:FlexClient.mxml
- <?xml version="1.0" encoding="utf-8"?>
- <s:Application xmlns:fx=""
- xmlns:s="library://ns.adobe.com/flex/spark"
- xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" creationComplete="initApp()">
- <fx:Declarations>
-
- </fx:Declarations>
-
- <fx: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+"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++){
- //正则表达式,回车符
- var myPattern:RegExp=/r/;
- //删除回车符
- arr[i]=arr[i].replace(myPattern,'');
- //在聊天框中输出
- myText.text+=arr[i]+'n';
- }
-
- }
- myText.verticalScrollPosition=myText.maxVerticalScrollPosition; //滚动到最下面
- }
-
- ]]>
- </fx:Script>
- <mx:TextArea x="10" y="48" width="334" height="250" id="myText"/>
- <s:TextInput x="10" y="18" width="334" id="myName" text="名字"/>
- <s:TextInput x="10" y="297" width="261" height="20" id="myInput"/>
- <s:Button x="270" y="296" label="发送" width="74" id="myBtn" click="sendMessage(myName.text+':'+myInput.text)"/>
- </s:Application>
参考资料