JAVA聊天程序实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
网络聊天程序实验报告
组长:xxx PB09210xxx
其他组员:无
实验内容
用面向对象程序设计方法编写一个网络聊天程序。
程序的功能是允许处在网络上不同结点的多个用户进行文字聊天。
最基本的要求是实现一对一的聊天,即最多只允许两个人在线。
也可以实现多人同时聊天,即在线的任何一个用户输入的文字,其他的人都能立即收到。
建议采用 Socket通讯方式。
实验实现
(一)概要设计:
GAGA聊天程序实现结构图:
注: 图中粗箭头表示信息传递
图解:在客户端着一端:
每一个客户端登录时候,先向服务器发送一个登录名的信息,向服务器注册这个客户端,然后进入群聊窗口,可以直接在群聊窗口中发送群聊的信息,也可以点击在线用户,打开私聊窗口,向相应用户私聊。
群聊,私聊的消息发送给服务器,服务器再把这些消息广播给所有客户端,每个客户端对接受的消息进行识别:要是群聊消息则放到群聊窗口里面;要是私聊信息,检查是不是给自己的私聊信息,要是给自己的,显示到相应私聊窗口上,要是没有相应私聊窗口则创建那个私聊窗口 ;要是不是自己的私聊消息则无视这个消息
在服务器这一端:
每一个客户端与服务器建立连接时候,就为它建立一个CreatServerThread的线程类,用来专门处理这个客户端。
服务器每当接收到消息后就使用Broadcast线程类进行广播,直到消息列表里面的消息发送完为止。
Broadcast是通过查找CreatServerThread线程类的数组,找到每个CreatServerThread线程类,也就找到每个客户端,再逐个发送消息
(二)详细设计:实验实现代码结构
客户端:(每种颜色代表一个类)
package Client;
// 主类message_frame,用来创建message_frame_to类
public class message_frame
{
public static void main(String args[])
{ // 主函数,创建message_frame_to类,调用其构造函数
message_frame_to m=new message_frame_to() ;
}
}// 主类message_frame结束
//类message_frame_to,用于创建客户端群聊窗口,与服务器连接,接发消息
class message_frame_to extends KeyAdapter implements ActionListener
{
public message_frame_to()
{ //构造函数,调用其他函数
Frame() ; // 建立主框架
Text() ; // 建立文本域
Label() ; // 建立标签域
Button() ; // 建立按钮域
online_users() ; // 建立在线用户列表
Dlog D=new Dlog() ; // 建立登陆界面
Client() ; // 连接服务器函数
}
// 建立主框架函数
public static void Frame()
{ }
// 文本域函数
public static void Text()
{ }
// 标签域函数
public static void Label()
{ }
// 按钮函数
public void Button()
{ }
// 按钮监听函数
public void actionPerformed(ActionEvent e)
{ }
// 输入框键盘监听函数,支持CTRL+ENTER快捷键发送消息
public void keyReleased(KeyEvent e)
{ }
// 在线列表函数
public void online_users()
{ }
//服务器建立连接与接收数据函数
public int Client()
{ }
// 群聊信息发送函数
public void send()
{ }
// 延迟函数,用来解决需要延迟执行问题
public static void deley(int ms)
{ }
// 抖屏函数
public void shake()
{ }
}//类message_frame_to结束
//私聊窗口类(线程派生类),每点击一个用户进行私聊时候,就创建一个对应的私聊窗口class frame extends Thread implements ActionListener
{
// 构造函数
public frame(String s)
{
send_name = s;
start() ;
}// 构造函数结束
// run函数,用来构造私聊窗口
public void run()
{ }
// 私聊窗口按钮监听执行器函数
public void actionPerformed(ActionEvent e)
{ }
//私聊消息发送函数
public void send_one()
{ }
// 私聊窗口信息显示函数
public void write(String inn)
{ }
} // 私聊窗口类结束
// 登录界面类,用来构造登录界面
class Dlog extends Frame implements ActionListener {
// 构造函数,创建登录窗口界面
public Dlog()
{ }
// 登录窗口按钮监听执行器函数
public void actionPerformed(ActionEvent e)
{ }
} // 登录界面类结束
// 音乐播放类,可以播放wav格式音乐
class PlayWav
{
// 构造函数
public PlayWav(String soun)
{ }
// 播放函数
public void play()
{ }
} //音乐播放类结束
服务器:(Server为最大类,内部包含两个子类以用不同颜色表明)package Server;
// 主类Server,是整个服务器的类
public class Server extends ServerSocket implements ActionListener
{
//主函数
public static void main(String[] args) throws IOException
{
new Server(); // 调用Server构造函数
}
// Sever函数,用来监听客户端连接
public Server() throws IOException
{ }
// 服务器的界面设计window函数
public void window()
{ }
//服务器GUI上按钮监听执行器函数
public void actionPerformed(ActionEvent e)
{ }
// 广播类(线程派生类),用来广播消息
class Broadcast extends Thread
{
public Broadcast()
{
start();
}
// run函数,广播消息
public void run()
{ }
}// 广播类结束
// 客户端线程类,每个对应一个客户端
class CreateServerThread extends Thread
{
// 构造函数
public CreateServerThread(Socket s) throws IOException
{ }
// 负责接收客户端发来的消息
public void run()
{ }
public void sendMessage(String msg)
{ //发送消息函数,保证发送给这个线程对应的客户端}
}//线程类CreateServerThread结束
} // 主类Server结束
程序运行与使用说明
(1)打开服务器
运行Server.java,输入密码0911001,按下start按钮,文本域会出现红色的"The Server is working"字符串,表示服务器已经开始工作,要是密码输入不正确会提示"The password is wrong",重新输入正确的密码才能打开服务器,具体截图如下:
(2)登入客户端
运行message_frame.java,首先会跳出登录界面,输入用户名,点击sure 按钮登录:
登录之后就会进入主聊天窗口,它可以支持群聊,可以看到主窗口分为:输入框Input Area ,信息框Message Area ,当前客户端用户名User , 在线用户名列表Online User ,发送按钮Send ,信息框清屏按钮Clear ,抖屏按钮Shake
群聊:在输入框中输入“你们好,我是卡卡”,按CTRL+ENTER键直接发送(也可以按Send按钮发送)
继续群聊:
私聊:比如现在“卡卡”找“劳尔”私聊,可以直接点击主窗口在线列表里面的“劳尔”的名字,会弹出私聊窗口
在私聊窗口输入信息,点击发送即可和“劳尔”私聊,此时劳尔也会跳出一个对“卡卡”的私聊窗口
“劳尔”也可以对“卡卡”进行私聊
然后在用户退出时候会有在线列表更新,例如“罗比尼奥”退出:
注:在用户登入,退出时候都会有提示音提醒在线的所有用户,在用户有消息到来时候会有消息提示音
软件特色:
GAGA聊天软件,支持群聊,私聊;支持CTRL+ENTER快捷键发送(群聊);支持清屏,抖屏功能;界面清新;服务器管理便捷;使用方便等许多优点
实验总结:
本次的上机作业,收获颇大,以前对面向对象语言只是只懂语法,没有接受太多的编程
训练,这个实验代码量较大,很好的训练的面向对象编程方式的能力,也自己摸索了很多过去没有去看得东西,比如Java的音乐播放,socket聊天这些之前不太了解的东西另外在GUI设计上面也是花了很多功夫,界面布局,各种功能器件的使用诸如此类的东西,总之,通过这次实验学习了很多新东西,也锻炼了很多老知识
代码:
/* 客户端程序:message_frame.java
* 创建者:xxx PB09210xxx
* 创建时间:2011年11月26日
* 联系方式:xxx
* 版本信息:version 2.0
* */
package Client;
import java.awt.*;
import javax.swing.ImageIcon;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import .*;
import java.io.*;
import java.util.*;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
import java.io.File;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
// 主类message_frame
public class message_frame
{
public static void main(String args[])
{ // 主函数,创建message_frame_to类,调用其构造函数
message_frame_to m=new message_frame_to() ;
}
}// 主类message_frame结束
//*************************************************************************************
************************************************************************************** ************
//************************************************************** 类message_frame_to,用于创建客户端窗口,与服务器连接,接发消息********************************************
class message_frame_to extends KeyAdapter implements ActionListener
{
static JFrame f=new JFrame("GAGA 2.0") ;
static ImageIcon icon=new ImageIcon("C:\\scan5.jpg") ; // 聊天窗口皮肤背景static public JLabel panel = new JLabel(icon) ;
public static JTextArea text_input=new JTextArea() ;
public static TextArea text_message= new TextArea() ;
public static Label label_4= new Label("User : ") ;
Button b= new Button("Send") ;
Button bc=new Button("Clear") ;
Button bl=new Button("Shake") ;
public static DefaultListModel listModel = new DefaultListModel();
public static JList User_List= new JList(listModel); // 显示用户列表,支持私聊public static String UserName= new String(" ") ; // 当前客户端登陆账户public static Socket socket;
public static BufferedReader in;
public static PrintWriter out;
public static ArrayList<frame> frame_Threader = new ArrayList<frame>(); // 私聊窗口列表
public static Calendar now ;
// 构造函数,调用其他所有函数
public message_frame_to()
{
Frame() ; // 建立主框架
Text() ; // 建立文本域
Label() ; // 建立标签域
Button() ; // 建立按钮域
online_users() ; // 建立在线用户列表
Dlog D=new Dlog() ; // 建立登陆界面
Client() ; // 连接服务器函数
}//构造函数结束
// 建立主框架函数
public static void Frame()
{
f.setLayout(null) ;
f.setBounds(300,200,600,500) ;
.
f.setBackground(Color.gray) ;
f.setResizable(false) ;
f.setVisible(false) ;
panel.setBounds(0, 0, 600, 500) ;
f.add(panel) ;
f.addWindowListener
(new WindowAdapter()
{public void windowClosing(WindowEvent e) // 当点击关闭按钮时候,退出客户端
{
out.println("#");
System.exit(0);
}
}
) ;
} // 主框架函数结束
// 文本域函数
public static void Text()
{
text_input.setBounds(10,400,400,100) ;
text_input.setBackground(Color.white) ;
. text_input.setVisible(true) ;
text_input.setFont(new Font("宋体",Font.BOLD,22));
text_input.setForeground(Color.blue);
text_message.setBounds(10,70,400,300) ;
text_message.setBackground(Color.white) ;
text_message.setVisible(true) ;
text_message.setFont(new Font("宋体",Font.BOLD,20));
text_message.setForeground(Color.blue);
text_message.setEditable(false) ;
text_message.selectAll() ;
panel.add(text_input) ;
panel.add(text_message) ;
} // 文本域函数结束
// 标签域函数
public static void Label()
{
Label label_1= new Label("Input Area") ;
Label label_2= new Label("Message Area") ;
Label label_3= new Label("Online User") ;
label_1.setBounds(10, 370, 360, 30) ;
label_1.setBackground(Color.gray) ;
label_1.setVisible(true) ;
label_1.setFont(new Font("黑体",Font.BOLD , 20)) ; label_1.setForeground(Color.black) ;
label_2.setBounds(10, 40, 400, 30) ;
label_2.setBackground(Color.gray) ;
label_2.setVisible(true) ;
label_2.setFont(new Font("黑体",Font.BOLD , 16)) ; label_2.setForeground(Color.black) ;
label_3.setBounds(450, 85, 120, 30);
label_3.setBackground(Color.gray) ;
label_3.setVisible(true) ;
label_3.setFont(new Font("黑体",Font.BOLD , 16)) ; label_3.setForeground(Color.black) ;
label_4.setBounds(450, 40, 120, 30);
label_4.setBackground(Color.gray) ;
label_4.setVisible(true) ;
label_4.setFont(new Font("黑体",Font.BOLD , 12)) ; label_4.setForeground(Color.black) ;
panel.add(label_1) ;
panel.add(label_2) ;
panel.add(label_3) ;
panel.add(label_4) ;
}//标签域函数结束
// 按钮函数
public void Button()
{
b.setBounds(450, 440,100, 30) ;
b.setBackground(Color.LIGHT_GRAY) ;
b.setVisible(true) ;
b.setFont(new Font("隶书",Font.BOLD , 20)) ;
b.setForeground(Color.black);
panel.add(b) ;
b.addActionListener(this) ;
bc.setBounds(450, 400,100, 30) ;
bc.setBackground(Color.LIGHT_GRAY) ;
bc.setVisible(true) ;
bc.setFont(new Font("隶书",Font.BOLD , 20)) ;
bc.setForeground(Color.black);
panel.add(bc) ;
bc.addActionListener(this) ;
bl.setBounds(370, 370, 40, 30) ;
bl.setBackground(Color.LIGHT_GRAY) ;
bl.setVisible(true) ;
bl.setFont(new Font("隶书",Font.BOLD , 10)) ;
bl.setForeground(Color.black);
panel.add(bl) ;
bl.addActionListener(this) ;
text_input.addKeyListener(this);
} // 按钮函数结束
// 按钮监听函数
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==b)
{
send();
text_input.setText("") ;
}
if(e.getSource()==bc)
text_message.setText("") ;
if(e.getSource()==bl)
shake() ;
} // 按钮监听函数
// 输入框键盘监听函数,支持CTRL+ENTER快捷键发送消息
public void keyReleased(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ENTER && e.isControlDown())
{
send();
text_input.setText("") ;
}
} // 输入框键盘监听函数结束
// 在线列表函数
public void online_users()
{
User_List.setBounds(450,120,100,200) ;
User_List.setBackground(Color.white) ;
User_List.setVisible(true) ;
panel.add(User_List) ;
User_List.addListSelectionListener
(new ListSelectionListener()
{ // 监听在线列表,用户点击列表上一个用户时候,跳出窗口,进行私聊
public void valueChanged(ListSelectionEvent e)
{
String s = User_List.getSelectedValue().toString() ;
new frame(s) ; // 建立私聊窗口
}
}
);
} // 在线列表函数结束
//服务器建立连接与接收数据函数
public int Client()
{
try
{
socket = new Socket("127.0.0.1", 10000); // 与服务器建立连接
in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(),true);
String inn ;
while(true) // 一直保持监听服务器是否发送消息过来
{
if(!socket.isConnected()) // 检查是否与服务器断开
{
text_message.setText("服务器已经断开") ;
break ;
}
inn=in.readLine() ; // 读取服务器发送过来的消息
String old = message_frame_to.text_message.getText() ;
if(inn.charAt(0)=='!') // “!“表现当前有用户登录或者下线,准备更新在线列表
{
message_frame_to.listModel.removeAllElements() ;
PlayWav login_music= new PlayWav("C:\\yue1.wav") ; // 用户上下线提示音乐
login_music.play() ;
continue ;
}
if(inn.charAt(0)=='@') // ”@“表示当前接收到的是在线列表,更新在线列表
{
message_frame_to.listModel.addElement(inn) ;
continue ;
}
if(inn.charAt(0)=='%') // ”%“表示当前接收的信息是私聊信息,要不是发
给自己的信息则无视
{
if(!inn.substring(1).equals("@"+UserName)) // 检查是否是发给自己的私聊信息
{
inn = in.readLine();
inn = in.readLine();
continue ;
}
inn = in.readLine();
String name = inn ;
if(name.equals("@"+UserName)) // 检查是不是自己发送的私聊信息
{
inn=in.readLine() ;
continue ;
}
int j = 0 ;
if(frame_Threader.isEmpty()) // 检查是否有私聊窗口,没有则新建
{
String s = name ;
new frame(s) ;
deley(10000) ;
}
else
{ // 在存在私聊窗口情形下,检测私聊窗口是否匹配
System.out.println(frame_Threader.get(j).send_name);
while(j < frame_Threader.size()&&!frame_Threader.get(j).send_name.equals(name))
{
j++;
}
if(j==frame_Threader.size()) // 不匹配,新建私聊窗口
{
String s = name ;
new frame(s) ;
deley(10000) ;
}
}
// 将接收的信息显示到私聊窗口上
inn=in.readLine() ;
frame fram = frame_Threader.get(j) ;
fram.write(inn.substring(1)) ;
PlayWav msg_music= new PlayWav("C:\\yue2.wav") ; // 消息提示声音
msg_music.play() ;
continue ;
}
// 以上条件都不满足就是群聊消息,将接收的消息显示到群聊窗口上
now = Calendar.getInstance();
String str = now.getTime().toString() ;
message_frame_to.text_message.setText(old+str+"
"+"\n"+inn.substring(1)+"\n") ;
PlayWav msg_music= new PlayWav("C:\\yue2.wav") ; // 消息提示声音msg_music.play() ;
} // while循环结束
}
catch (IOException e)
{}
return 1 ;
}//服务器建立连接与接收数据函数结束
// 群聊信息发送函数
public void send()
{
if(!socket.isConnected())
{
text_message.setText("服务器已经断开") ;
return ;
}
String line = message_frame_to.text_input.getText();
out.println("&"+UserName+":"+" "+line);
}// 群聊信息发送函数结束
// 延迟函数,用来解决需要延迟执行问题
public static void deley(int ms)
{
int killtime ;
for(int i = 0 ; i < 10000 ; i++)
for(int j = 0 ; j < ms ; j++)
{
killtime = 0;
killtime++;
}
} // 延迟函数结束
// 抖屏函数
public void shake()
{
f.setBounds(260, 160, 600, 500) ;
deley(10000) ;
f.setBounds(260, 240, 600, 500) ;
deley(10000) ;
f.setBounds(340, 240, 600, 500) ;
deley(10000) ;
f.setBounds(340, 240, 600, 500) ;
deley(10000) ;
f.setBounds(300, 200, 600, 500) ;
} // 抖屏函数结束
}// 类message_frame_to结束
//
************************************************************************************** ************************************************************************************** *******
//************************************************************* 私聊窗口类(线程派生类),每点击一个用户进行私聊时候,就创建一个对应的私聊窗口****************************
class frame extends Thread implements ActionListener
{
static ImageIcon icon=new ImageIcon("C:\\scan5.jpg") ;
public static JLabel panel = new JLabel(icon) ;
public static JFrame f = new JFrame() ;
public static JTextArea text_input= new JTextArea() ;
public static TextArea text_message= new TextArea() ;
Button b= new Button("Send") ;
public static String UserName= new String(" ") ; // 当前客户端的用户名
public static Socket socket;
public static String send_name ; // 当前私聊的用户名
public static int send_num ;
public static Calendar now ;
public static boolean tag = true;
String old = new String() ;
// 构造函数
public frame(String s)
{
send_name = s;
start() ;
}// 构造函数结束
public void run()
{
f.setTitle("@"+message_frame_erName+" to "+send_name) ; // 设置私聊窗口标题
message_frame_to.frame_Threader.add(this) ;
f.setLayout(null) ;
f.setBounds(200,100,600,500) ;
f.setBackground(Color.gray) ;
f.setResizable(false) ;
panel.setBounds(0, 0, 600, 500) ;
f.addWindowListener
(new WindowAdapter()
{public void windowClosing(WindowEvent e) // 私聊窗口关闭
{
f.setVisible(false) ;
message_frame_to.frame_Threader.remove(this) ;
tag = false;
}
}
) ;
text_input.setBounds(10,400,400,100) ;
text_input.setBackground(Color.white) ;
text_input.setVisible(true) ;
text_input.setFont(new Font("宋体",Font.BOLD,22)); text_input.setForeground(Color.blue);
text_message.setBounds(10,70,400,300) ;
text_message.setBackground(Color.white) ;
text_message.setVisible(true) ;
text_message.setFont(new Font("宋体",Font.BOLD,20)); text_message.setForeground(Color.blue);
text_message.setEditable(false) ;
text_message.selectAll() ;
panel.add(text_input) ;
panel.add(text_message) ;
Label label_1= new Label("Input Area") ;
Label label_2= new Label("Message Area") ;
label_1.setBounds(10, 370, 400, 30) ;
label_1.setBackground(Color.gray) ;
label_1.setVisible(true) ;
label_1.setFont(new Font("黑体",Font.BOLD , 20)) ; label_1.setForeground(Color.black) ;
label_2.setBounds(10, 40, 400, 30) ;
label_2.setBackground(Color.gray) ;
label_2.setVisible(true) ;
label_2.setFont(new Font("黑体",Font.BOLD , 16)) ; label_2.setForeground(Color.black) ;
panel.add(label_1) ;
panel.add(label_2) ;
b.setBounds(450, 440,100, 30) ;
b.setBackground(Color.LIGHT_GRAY) ;
b.setVisible(true) ;
b.setFont(new Font("隶书",Font.BOLD , 20)) ;
b.setForeground(Color.black);
b.addActionListener(this) ;
panel.add(b) ;
f.add(panel) ;
f.setVisible(true) ;
UserName = message_frame_erName ; String inn ;
while(true) // 死循环,用来保持私聊窗口的活性
{ }
} // run函数结束
// 私聊窗口按钮监听执行器函数
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==b) // 点击发送消息
{
send_one();
text_input.setText("") ;
}
} // 私聊窗口按钮监听函数结束
//私聊消息发送函数
public void send_one()
{
now = Calendar.getInstance();
String str = now.getTime().toString() ;
String line = text_input.getText();
message_frame_to.out.println("%"+send_name);
message_frame_to.out.println("@"+UserName);
message_frame_to.out.println("&"+UserName+":"+" "+line);
old = text_message.getText() ;
text_message.setText(old+str+" "+"\n"+UserName+":"+" "+line+"\n") ;
} // 私聊消息发送函数结束
// 私聊窗口信息显示函数
public void write(String inn)
{
now = Calendar.getInstance();
String str = now.getTime().toString() ;
String ol = text_message.getText() ;
text_message.setText(ol+str+" "+"\n"+inn+"\n") ;
}// 私聊窗口信息显示函数结束
} // 私聊窗口类结束
//************************************************************************************* ************************************************************************************** *********************
//************************************************************************************* ****** 登录界面类************************************************************************************** class Dlog extends Frame implements ActionListener
{
Frame D=new Frame("Wellcome To GAGA Chatroom") ;
TextArea t=new TextArea() ;
Button sure= new Button("Sure") ;
Label user_name= new Label("User Name ") ;
static ImageIcon icon=new ImageIcon("C:\\scan5.0.jpg") ;
static public JLabel p = new JLabel(icon) ;
// 构造函数,创建登录窗口界面
public Dlog()
{
D.setLayout(null) ;
D.setBackground(Color.gray) ;
D.setBounds(400, 260, 450, 300) ;
t.setBackground(Color.white) ;
t.setBounds(100, 100, 150, 50) ;
D.add(t) ;
sure.setBounds(260, 100, 70, 30) ;
sure.setBackground(Color.lightGray) ;
sure.addActionListener(this) ;
D.add(sure) ;
user_name.setBounds(100, 70, 100, 24) ;
user_name.setBackground(Color.gray) ;
D.add(user_name) ;
p.setBounds(0, 0, 450, 300);
D.add(p) ;
D.setVisible(true) ;
}// 构造函数结束
// 登录窗口按钮监听执行器函数
public void actionPerformed(ActionEvent e)
{
message_frame_erName=t.getText() ;
message_frame_to.out.println("@"+message_frame_erName);
D.setVisible(false) ;
message_frame_bel_4.setText("User:"+"
"+message_frame_erName);
message_frame_to.f.setVisible(true) ;
PlayWav login_music= new PlayWav("C:\\yue1.wav") ;
login_music.play() ;
}// 登录窗口俺就监听执行器函数
}// 登录类结束
//************************************************************************************* ************************************************************************************** ******
//***************************************************************************** 音乐播放类,支持wav格式********************************************************************
class PlayWav
{
private static AudioInputStream ais=null ;
private AudioFormat af=null;
private dli=null;
private SourceDataLine sdl=null;
private final String source ;
// 构造函数
public PlayWav(String soun)
{
source= soun ;
try{
ais=AudioSystem.getAudioInputStream(new File(source));
af=ais.getFormat();
dli=new (SourceDataLine.class,af);
sdl=(SourceDataLine)AudioSystem.getLine(dli);
}catch(Exception ex){
System.err.println(ex);
}
} // 构造函数结束
// 播放函数
public void play()
{
byte[] buff=new byte[102400];
int len=0;
try{
sdl.open(af,102400);
sdl.start();
while((len=ais.read(buff))>0)
{
sdl.write(buff,0,len);
}
ais.close();
sdl.drain();
sdl.close();
}catch(Exception ex)
{
System.err.println(ex);
}
} // 播放函数结束
} //音乐播放类结束
/* 服务器程序:Server.java
* 创建者:XXX PB09210XXX
* 创建时间:2011年11月26日
* 联系方式:xxx
* 版本信息:version 2.0
* */
package Server;
import java.io.*;
import .*;
import java.util.*;
import java.awt.*;
import javax.swing.ImageIcon;
import java.awt.event.*;
import javax.swing.*;
// 主类Server
public class Server extends ServerSocket implements ActionListener
{
private static final int SERVER_PORT = 10000; // 服务器端口号
private static ArrayList<String> User_List = new ArrayList<String>(); // 存放当前连接服务器的用户列表
private static ArrayList<CreateServerThread> Threader = new ArrayList<CreateServerThread>(); // 存放客户端列表,每个元素对应一个客户端private static LinkedList<String> Message_Array = new LinkedList<String>(); // 消息列表,存放等待发送的消息
private static int Thread_Counter = 0;
private static boolean isClear = true;
static Frame f=new Frame("Server 2.0") ;
static ImageIcon icon=new ImageIcon("C:\\scan2.jpg") ;
static public JLabel panel = new JLabel(icon) ;
static public Button bs= new Button("Start") ;
static public Button bc=new Button("Cease") ;
public static JPasswordField password_input=new JPasswordField () ; public static TextArea status_output=new TextArea() ;
public static Label password = new Label("Password") ;
public static int tag=0 ;
//主函数
public static void main(String[] args) throws IOException
{
new Server(); // 调用Server函数
}
// Sever函数,用来监听客户端连接
public Server() throws IOException
{
window() ; // 建立服务器的图形界面
while(true) // 等待使用者输入正确的密码,开始服务器
{
if(tag==1)
{
status_output.setText("The sever is working") ;
break ;
}
}
new Broadcast() ; // 创建广播类(线程),用来发送消息
ServerSocket ss= new ServerSocket(SERVER_PORT) ; // 开启服务器端口
try
{
while(true) // 不断的监听是否有客户端请求连接
{
Socket socket = ss.accept(); // 一旦有客户端连接,为这个客户端创建一个CreateServerThread类(线程),以便管理
new CreateServerThread(socket); // 可以通过找到这个类找到对应的客户端}
}
catch (IOException e) {}
finally
{
close();
}
} // Server函数结束
// 服务器的界面设计window函数
public void window()
{
f.setLayout(null) ;
f.setBounds(300,200,600,500) ;
f.setBackground(Color.gray) ;
f.setResizable(false) ;
f.setVisible(true) ;
panel.setBounds(0, 0, 600, 500) ;
f.add(panel) ;
f.addWindowListener // 监听整个窗口,点击关闭键后直接结束服务器程序
(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
. }
) ;
bs.setBounds(450, 440,100, 30) ;
bs.setBackground(Color.LIGHT_GRAY) ;
bs.setVisible(true) ;
f.add(bs) ;
bs.addActionListener(this) ;
bc.setBounds(450, 400,100, 30) ;
bc.setBackground(Color.LIGHT_GRAY) ;
bc.setVisible(true) ;
bc.addActionListener(this) ;
password_input.setBounds(90,360,100,35) ;// 距离00,x y 以及x y password_input.setBackground(Color.white) ;
password_input.setVisible(true) ;
panel.add(password_input) ;
password.setBounds(10, 360, 60, 30) ;
password.setBackground(Color.gray) ;
password.setVisible(true) ;
panel.add(password) ;
status_output.setBounds(10,400,260,50 );
status_output.setBackground(Color.white) ;
status_output.setVisible(true) ;
status_output.setFont(new Font("宋体",Font.BOLD,20));
status_output.setEditable(false) ;
status_output.setForeground(Color.red);
panel.add(status_output) ;
}//window函数结束
//服务器GUI上按钮监听执行器函数
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==bs) // 当按下start按钮后先检测使用者是否输入正确的密码,若是密码正确,服务器开始工作
{
String key =password_input.getText() ;
if(key.equals(""))
status_output.setText("Please input password ") ;
else
if(key.equals("0911001"))
tag=1 ;
else
status_output.setText("The password is wrong ") ;
}
if(e.getSource()==bc) // 关闭服务器按钮
{
tag=0 ;
}
}// 监听函数结束
//********************************************************广播类(线程派生类)********************************************************
// 用于发所有建立连接的客户端发送消息
class Broadcast extends Thread
{
public Broadcast()
{
start();
}
public void run()
{
while(true)
{
if (!isClear)
{// 当isClear为假,说明消息队列里面放有没有发送的消息,广播这些消息
String tmp = (String)Message_Array.getFirst(); // 得到消息队列的队列头部的消息
for (int i = 0; i < Threader.size(); i++)
{ // 对于Threader数组里所有元素广播这条消息,因为一个Threader对应一个CreateServerThread进程类,也就对应一个客户端
// 对所有连接到服务器的客户端广播这个消息
CreateServerThread client = (CreateServerThread)Threader.get(i);
client.sendMessage(tmp);
}
Message_Array.removeFirst(); //移除广播掉的这个消息
isClear = Message_Array.size() > 0 ? false : true; // 判断消息队列里还有没有消息,以供继续广播
}
}
}
}
//广播类结束
//******************************************************** 客户端类。