完成时间:20##年6月—20##年7月
计算机科学系制
说 明
一、课程设计写作框架(仅供参考)
摘 要
目 录
正 文
1、 基本设计任务及要求、所用仪器设备;
2、 总体设计方案及主要设计原理;
3、 实现技术及源程序代码;
4、 测试及分析;
5、 结束语(心得体会、改进方向)。
参考文献
二、写作要求:
课程设计写作要求论点明确、论据充分、说明透彻,语言准确恰当,书面整洁,字迹工整。
课程设计的篇幅本科一般为4000字左右,专科一般为3000字左右。
课程设计任务书及成绩评定
摘 要
通过此项目实训——JAVA聊天室的设计,实践、总结、回顾了网络编程思想以及编程方法,并通过编写程序来掌握Java语言编程技巧,将学习到的知识融会贯通,同时提高调试程序的能力,养成良好的编程习惯,并增强对程序设计整体思路的把握,理论与时间相结合。
本文的主要工作集中在:该课程基于C/S模式,客户机向服务器发聊天请求,服务器应答并能显示客户机发过来的信息。当用户聊天时,将当前用户名、聊天对象、聊天,内容、聊天语气和是否私聊进行封装,然后与服务器建立Socket连接,再用对象输出流包装Socket的输出流将聊天信息对象发送给服务器端。
当用户发送聊天信息时,服务端将会收到客户端用Socket传输过来的聊天信息对象,然后将其强制转换为Chat对象,接收用户的聊天信息是由多线程技术实现的,因为客户端必须时时关注更新服务器上是否有最新消息,当每次用户接收到聊天信息后将会开始分析聊天信息然后将适合自己的信息人性化地显示在聊天信息界面上。
关键字:java;QQ聊天室,eclipse
JAVA 聊天室课程设计
前言:
随着计算机网络日新月异的发展,人们的交流方式越来越多,传统的交流方式,如:信件、电报、电话等已经难以满足人们的交流要求,在互联网上即时的和好友取得联系,已经成为当今社会人们主流的联系方式。因此,两台计算机之间进行即时通讯、发送文件等交流方式已经成为必然潮流。因此出现了QQ等聊天工具,然而QQ等聊天工具虽然方便、实用,但是,娱乐功能太多,有很多吸引人的娱乐功能,从一定程度上来说,是一种娱乐工具,不能作为用于即时通讯、文件共享的专用工具。目前,用于实现单一的即时通讯、文件共享的软件实在太少,而且,它们中大部分都是绝对的C/S模式,对远程服务器有非常大的依赖性,没有彻底实现点对点的交流。为此,我们决定开发一个专用于实现两台计算机之间即时通讯、文件共享的软件,以方便两台计算机之间信息的交流。本软件属于点对点连接的,在连接并通信时,尤其是近程的即时通讯,彻底的脱离了远程的服务器,避免了和远程服务器连接时过多的浪费网络资源。并且避免了服务器忙或与服务器无法连接时,浪费过多时间用于和服务器建立连接!因此,这个软件是极具适应性和实用性的即时通讯软件.
一、课程设计的目的
进一步培养学生面向对象程序设计的思想,加深对面向对象程序设计四大特性的理解,针对JAVA语言中的重点和难点内容进行训练,独立完成有一定工作量的程序设计任务,同时强调好的程序设计风格。
二、系统分析与设计
系统可以采用任何一种流行的,Java支持的数据库,本系统采用了Microsoft公司的Access作为后台数据库。通过对现在流行的一些Icq的参考,建立数据库,名为chart,数据库共建立一个表,表中基本信息包括编号,uername,password。
(1)用户的基本信息表(表名userlilst)
序号 字段名 含义 数据类型 NULL
1 编号 用户的编号 int
2 username 用户名 文本
3 password 用户的密码 文本
其中编号字段为自动增加。
◆ 服务器端程序如下:
服务器与客户间通过套接口Socket(TCP)连接。在java中使用套接口相当简单,Java API为处理套接口的通信提供了一个类java.net.Socket.,使得编写网络应用程序相对容易.服务器采用多线程以满足多用户的请求,通过JDBC与后台数据库连接,并通过创建一个ServerSocket对象来监听来自客户的连接请求,默认端口为8888,然后无限循环调用accept()方法接受客户程序的连接。
主要代码如下:
public static int port=8888;
ServerSocket server;
Socket client=null;
BufferedReader cin=null;
PrintWriter cout=null;
Thread chartThread=null;
JButton runButton=new JButton("运行");
JButton stopButton=new JButton("停止");
JButton exitButton=new JButton("退出");
JButton messageButton=new JButton("发送消息");
JTextField serMessage=new JTextField("",25);
JPanel p1=new JPanel();
JPanel p2=new JPanel();
JScrollPane messageScrollPane;
JTextArea message=new JTextArea();
boolean isRunning=false;
public Server(){
super("网络聊天服务器");
p1.add(runButton);
p1.add(stopButton);
p1.add(exitButton);
runButton.addActionListener(this);
stopButton.addActionListener(this);
exitButton.addActionListener(this);
messageButton.addActionListener(this);
p2.add(serMessage);
p2.add(messageButton);
messageScrollPane=new JScrollPane(message,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
this.getContentPane().add(p1,"North");
this.getContentPane().add(p2,"South");
this.getContentPane().add(messageScrollPane,"Center");
this.setSize(400,300);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);}
public void actionPerformed(ActionEvent e)
{if(e.getSource()==runButton){
chartThread=new Thread(this);
chartThread.start();
runButton.setVisible(false);
message.append("服务器启动"+"\n");
}else if (e.getSource()==stopButton)
{
chartThread=null;
runButton.setVisible(true);
if(cout!=null) cout.println("stop");
try{
if(server!=null)
server.close();
}catch(Exception exp){}
message.append("服务器停止"+"\n");
}else if(e.getSource()==exitButton)
{
chartThread=null;
if(cout!=null) cout.println("exit");
System.exit(0);
}else if (e.getSource()==messageButton)
{
if(chartThread!=null)
{
sendMessage(serMessage.getText());
message.append("发送:"+serMessage.getText()+"\n");
}
}
}
public void run()
{
try{
server=new ServerSocket(port);
while(chartThread!=null)
{
client=server.accept() ;
cin=new BufferedReader(new InputStreamReader(client.getInputStream()));
cout=new PrintWriter(client.getOutputStream(),true);
String username;
String password;
username=cin.readLine();
password=cin.readLine();
if(userOK(username,password))
{
message.append("客户:"+username+"进入\n");
cout.println("ok");
String aline;
while((aline=cin.readLine() )!=null&&chartThread!=null)
{
if(aline.equals("exit"))
{
message.append("客户:"+username+"已退出!\n");
break;
}else message.append(username+"说:"+aline+"\n");
}
}else cout.println("error");
}
cin.close() ;
cout.close() ;
client.close() ;
server.close();
}
catch(Exception e)
{
System.out.println(e);
}
}
public boolean userOK(String username,String password)
{
boolean ok=false;
try {
//①加载驱动程序
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
}
catch (ClassNotFoundException e) {
//驱动程序加载不成功,打印错误信息并退出
System.out.println("Can not find driver " );
System.exit( -1);
}
Connection con;
try {
//②获得jdbc 连接
con = DriverManager.getConnection("jdbc:odbc:TrioMotors", "user", "");
//③创建Statement对象
Statement stmt = con.createStatement();
//④得到查询结果集
String sql = "select * from userlist where username='"
+ username + "'";
ResultSet rs = stmt.executeQuery(sql);
//列印结果集
while(rs.next())
{
String ps = rs.getString("password");
if (ps.equals(password)) {
//验证通过
ok=true;
}
}
//⑤关闭数据库连接
rs.close();
stmt.close();
con.close();
}
catch (SQLException sqe) {
sqe.printStackTrace();
}
return ok;
}
public void sendMessage(String message)
{
cout.println(message);
}
public static void main(String args[])
{
Server my=new Server();
}
}
◆ 客户端程序如下 :
客户通过Socket(InetAddress,port)建立与服务器的连接。服务器与客户都通过构造BufferedReader,PrintWriter来建立输入输出流,然后双方通过该输入输出流来相互传递信息,一旦收到客户方的连接请求,服务器accept()方法返回一个新建的Socket对象。客户端然后向服务器发送消息,比如登录,服务器收到来自客户的请求后,针对不同的消息处理请求, 虽然UDP不可靠但是对于icq可靠性并不太重要,而且UDP快速,所以客户间发送信息通过UDP。用户登录时通过类DatagramPacket和DatagramSocket创建UDP包括其本地接受端口以及发送端口。
主要代码如下:
public class Client extends JFrame implements ActionListener,Runnable
{
public static int port=8888;
ServerSocket server;
Socket client;
BufferedReader cin;
PrintWriter cout;
private JLabel userlabel=new JLabel("用户名");;
private JLabel passwordlabel=new JLabel("密码");
private JTextField username=new JTextField(10);
private JPasswordField password=new JPasswordField(10);
private JButton loginButton=new JButton("登录");
private JButton exitButton=new JButton("退出");
private JPanel p1=new JPanel();
JButton messageButton=new JButton("发送消息");
JTextField clientMessage=new JTextField("",25);
JPanel p2=new JPanel();
JScrollPane messageScrollPane;
JTextArea message=new JTextArea();
Thread chart=null;
public Client()
{
super("网络聊天客户端");
p1.add(userlabel);
p1.add(username);
p1.add(passwordlabel);
p1.add(password);
p1.add(loginButton);
p1.add(exitButton);
loginButton.addActionListener(this);
exitButton.addActionListener(this);
this.getContentPane().add(p1,"North");
p2.add(clientMessage);
p2.add(messageButton);
messageButton.addActionListener(this);
messageScrollPane=new JScrollPane(message,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
this.getContentPane().add(p2,"South");
this.getContentPane().add(messageScrollPane,"Center");
this.setSize(500,300);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e){
if(e.getSource()==loginButton){
String pword=new String(password.getPassword());
if(loginServer(username.getText(),pword))
{
chart=new Thread(this);
chart.start();
}else{
JOptionPane.showMessageDialog(null,"user name or password error!");
}
}else if(e.getSource()==exitButton)
{
cout.println("exit");
chart=null;
}
if (e.getSource()==messageButton)
{
sendMessage(clientMessage.getText());
message.append("发送:"+clientMessage.getText()+"\n");
}
}
public boolean loginServer(String username,String password)
{
try{
client=new Socket("localhost",8888);
cin=new BufferedReader(new InputStreamReader(client.getInputStream()));
cout=new PrintWriter(client.getOutputStream(),true);
cout.println(username);
cout.println(password);
String readLine=cin.readLine();
if(readLine.equals("ok"))
{
message.append("连接到服务器!\n");
return true;
}
}catch(Exception e)
{
}
return false;
}
public void run()
{
String aline;
try{
while(chart!=null&&(aline=cin.readLine() )!=null)
{
if(aline.equals("exit")||aline.equals("stop"))
{
message.append("服务器已断开!重新登录!\n");
break;
}else message.append("服务器说:"+aline+"\n");
Thread.sleep(200);
}
cin.close() ;
cout.close() ;
client.close() ;
}
catch(Exception e){}
}
public void sendMessage(String mes)
{
cout.println(mes);
}
public static void main(String args[])
{
Client my=new Client();
my.setVisible(true);}
三、界面设计图
图1.1 :服务器端页面
图1.2 :程序运行界面
图1.3 :注册页面
图1.4 :登陆页面
图1.5:网友1页面
图1.6:网友2页面
图1.7:网络涂鸦板颜色面板
图1.8:聊天记录面板
图1.9:数据库页面
四、运行调试与分析讨论
- 服务器端:(Windows平台)首先应有java环境jdk,建议采用jdk1.5。然后安装Access数据库,建立数据库chart,并且建立表userlist。然后在控制面板中的ODBC数据源中设置用户DSN数据源TrioMotors 建立与数据库的连接。然后运行程序即可。
- 客户端:只要有有java环境jdk就可以建议jdk1.5。然后运行程序及可。
总结
该课程设计对于进一步培养面向对象程序设计的思想有很大的帮助,同时加深了对面向对象程序设计四大特性的理解,由于能力有限,还存在着许多不足之处。如:
◆ 写代码切勿急躁。这个程序是对我掌握知识熟练度的巨大挑战。写代码过程中经常出现到处报错的情况,常常要花好长时间寻找错误。有时只是单纯的语法错误就会困惑好久。
◆ 考虑问题要全面,要有整体意识。因为之前写的程序都是单纯的具有一项功能,各部分几件的配合不是很关键,而之一程序包含聊天涂鸦等花样,如果协调不好,就会顾此失彼。
◆ 同学们之间的互相的帮助也对软件的完成起了很大作用。编写这些代码需要很多方面的知识,一个人要想全面掌握有些困难。当我山穷水尽得时候常找同学过来帮忙调试。
◆ 实践要比理论难得多。有一个好想法,如果不去实践,永远不知道它正不正确。而这个过程中会遇到各种各样的问题,我也在不断提出与解决问题过程中得到提高。
这些都是需要完善的地方,该系统离实际使用也还有一定的距离,需要我木们不断地进行补充和完善。在这次论文设计中学会了同学之间的相互帮助,增强合作意识,同时要感谢王琳琳老师的帮助和支持,感谢枣庄学校给我们提供良好的上机环境。