目的:做一个简单的聊天室,用来实现消息广播。
服务端:
服务端代码: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);
}
}
imp
imp
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>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" fontSize="12" creationComplete="initApp()" width="369" height="326">
<mx:Script>
<![CDATA[
imp
imp
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_DA
}
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>