java聊天小程序课程设计.docx
《java聊天小程序课程设计.docx》由会员分享,可在线阅读,更多相关《java聊天小程序课程设计.docx(24页珍藏版)》请在冰豆网上搜索。
java聊天小程序课程设计
Java语言程序设计
课程设计
题目聊天小程序(socket编程+多线程)
学院商学院
专业信息管理与信息系统
班级信息111
学号8
学生姓名张语轩
指导教师余法红
编写日期
一、需求分析
当今主流的聊天工具有QQ,UC,MSNMessenger等,国内最热门的当属QQ,腾讯QQ(OICQ)是由深圳市腾讯计算机系统公司开发的,基于Internet的即时聊天工具。
您可以使用QQ和好友用户进行交流,信息即时发送,即时回复,收发及时、功能全面。
此外QQ还具有BP机网上寻呼、聊天室、传输文件、语音邮件、手机短讯服务等功能,QQ不仅仅是虚拟的网络寻呼机,更可与传统的无线寻呼网、GSM移动电话的短消息系统互联,目前QQ和全国多家寻呼台、移动通信公司有业务合作。
是国内不可多得的中文网络寻呼机。
QQ支持显示朋友在线信息、即时传送信息、即时交谈、即时发送文件和网址。
QQ可以在Win95/98/NT/2000操作系统下运行,是十分灵活的网络寻呼工具。
它会自动检查您是否已联网,如果您的电脑已连入Internet,可以搜索网友、显示在线网友,可以根据QQ号、昵称、姓名、email地址等关键词来查找,找到后可加入到通讯录中。
当您的通讯录中的网友在线时,QQ中朋友的头像就会显示在线,根据提示就可以发送信息,如果对方登记了寻呼机或开通了GSM手机短消息,即使离线了,您也可及时将信息传递给您的好友。
虽然以上这些软件是免费的,并且功能越来越强大。
但是它们的唯一的不足就是必须要联网或者下载到它们的服务端,要不然是没法脱离Intenet使用的。
为了能在一个没有连接到Intenet的局域网使用聊天工具,那就必须要有服务器端。
本系统就是包括服务器端与客户端,可以在局域网聊天的一个工具。
二、系统概述
我们实现的是局域网中的聊天功能,运行服务程序后,服务器创建成功,然后使服务器对某一个设定的端口处于监听状态,当有客户端请求建立连接时,服务器就可接受请求,建立连接!
这样服务器和客户端就可相互发送消息,实现聊天功能!
系统的功能要求:
A.服务器端主要功能如下:
1.在特定端口上进行侦听,等待客户端连接。
2.用户可以配置服务器端的侦听端口,默认端口为8888。
3.向已经连接到服务器端的用户发送系统消息。
4.统计在线人数。
5.当停止服务时,断开所有的用户连接。
B.客户端的主要功能如下:
1.连接到已经开启聊天服务的服务器端。
2.用户可以配置要连接的服务器端的IP地址和端口号。
3.用户可以配置连接后显示的用户名。
4.当服务器端开启的话,用户可以随时登录和注销。
5.用户可以向所有人或某一个人发送消息。
三、系统运行环境
本程序基于java和Eclipse开发环境,可以在一般的装有windows系统的主机上运行。
Eclipse是一个开放源代码的软件开发项目,专注于为高度集成的工具开发提供一个全功能的、具有商业品质的工业平台。
它主要由Eclipse项目、Eclipse工具项目和Eclipse技术项目三个项目组成,具体包括四个部分组成——EclipsePlatform、JDT、CDT和PDE。
JDT支持Java开发、CDT支持C开发、PDE用来支持插件开发,EclipsePlatform则是一个开放的可扩展IDE,提供了一个通用的开发平台。
它提供建造块和构造并运行集成软件开发工具的基础。
四、功能需求描述
本系统针对局域网进行联机聊天。
聊天室分为服务器端和客户端两部分,服务器端程序主要负责侦听客户端发来的信息,客户端需要登陆到服务器端才可以实现正常的聊天功能。
本系统主要实现如下功能:
其界面主要采用了java.awt包,java.swing包以及java.util包等。
程序实现了聊天室的基本功能,其中有:
1、启动服务器。
2、进入客户端界面。
3、登录聊天室。
4、发送信息(实现按回车键发送消息)。
5、关闭服务器。
服务器:
✧在特定端口上进行侦听,等待客户端连接。
✧向已经连接到服务器端的用户发送系统消息。
✧当停止服务时,断开所有的用户连接。
✧系统运行稳定、安全可靠。
✧一台主机只能启动一个服务器。
客户端:
✧连接到已经开启聊天服务的服务器端。
✧当服务器端开启后,用户可以发表聊天信息。
✧用户可以向所有人或某一个人发送消息。
✧系统运行稳定、安全可靠。
五、总体设计
聊天系统的设计跟普通网站设计有着许多不同的地方,普通网站设计所考虑的因素,例如,普通网站需要对布局进入大量美化以及动画设计等等,而聊天室只要提供满足访客双方直接实时聊天即可。
因此,在设计聊天系统的过程中,必须要考虑好以下几个设计要点:
在Internet上的聊天程序一般都是以服务器提供服务端连接响应,使用者通过客户端程序登录到服务器,就可以与登录在同一服务器上的用户交谈,这是一个面向连接的通信过程。
因此,程序要在TCP/IP环境下,实现服务器端和客户端两部分程序。
1.首先通过继承JFrame类构造服务器界面。
2.设计客户端程序使其能够完成正常的通信功能
3.设计侦听程序,使其显示登录的ip地址端口号,以及用户昵称,通过侦听按钮可以调用客户端程序,实现聊天功能。
六、系统模块结构图
主要功能框架如下图所示:
七、程序模块设计(程序代码设计与分析、运行结果)
代码:
(1)ActionProcess.java
packagechat;
import.*;
publicclassActionProcessimplementsRunnable{
privateChatClientclient;
Stringname="";
Stringsendtoname="";
StringsendtoID;
Stringfilename="";
Stringfilepath="";
publicActionProcess(ChatClientclient){
this.client=client;
}
publicvoidaction(ActionEvente)throwsException{
if(e.getSource()==client.connection)
{
try
{
else
{
Stringaddr=JOptionPane.showInputDialog("请输入服务器IP:
");
InetAddressaddress=InetAddress.getByName(addr);
InetSocketAddresssocketAddress=newInetSocketAddress(address,5555);
client.thread=newThread(this);
}
}
catch(IOExceptionee){}
}
if(e.getSource()==client.listen)
{
try
{
filesendServerfilesendserver=newfilesendServer();
filesendserver.filereceive();
}
catch(Exceptionee){
ee.printStackTrace();
}
}
if(e.getSource()==client.filesend){
try{
filesendClientfilesendclient=newfilesendClient();
filesendclient.filesend();
}catch(Exceptionee){}
}
if(e.getSource()==client.exit)
{
try{
}catch(IOExceptione1){
e1.printStackTrace();
}
System.exit(0);
}
if(em.equals("表情")){
em="";
}else{
em+="着";
}
if(e.getSource()==client.sendtoall)
{
if(s!
=null)
{
try
{
}
catch(IOExceptione1){}
}
}
}
if(e.getSource()==client.sendtoone)
{
sendtoID=JOptionPane.showInputDialog("请输入对方ID:
");
sendtoname=JOptionPane.showInputDialog("请输入对方姓名:
");
if(s!
=null)
{
try
{
}
catch(IOExceptione1){}
}
}
}
}
publicvoidrun()
{
Strings=null;
while(true)
{
try
{
}
catch(IOExceptione)
{
try
{
}
catch(Exceptionep){}
break;
}
}
}
}
(2)Clicent.java
packagechat;
importjava.awt.*;
importjava.io.*;
import.*;
importjavax.swing.*;
publicclassClient{
publicstaticvoidmain(Stringargs[])
{
newChatClient();
}
}
classChatClientextendsFrameimplementsActionListener,Runnable{
publicButtonlisten,connection,sendtoall,sendtoone,exit,filesend;
publicJComboBoxemote;
publicTextFieldinputName,inputContent;
publicTextAreachatResult;
publicSocketsocket=null;
publicDataInputStreamin=null;
publicDataOutputStreamout=null;
publicThreadthread;
ChatClient()
{
socket=newSocket();
Boxbox1=Box.createHorizontalBox();
listen=newButton("作为服务器监听");
connection=newButton("连接服务器");
filesend=newButton("发送文件");
exit=newButton("退出");
sendtoall=newButton("群聊");
sendtoone=newButton("私聊");
listen.setEnabled(false);
filesend.setEnabled(false);
sendtoall.setEnabled(false);
sendtoone.setEnabled(false);
inputName=newTextField(6);
inputName.setBackground(newColor(162,231,250));
inputContent=newTextField(22);
inputContent.setBackground(newColor(162,231,250));
chatResult=newTextArea("",17,20,TextArea.SCROLLBARS_VERTICAL_ONLY);
chatResult.setBackground(newColor(162,231,250));
JLabeljlname=newJLabel("输入昵称");
box1.add(jlname);
box1.add(inputName);
box1.add(listen);
box1.add(connection);
box1.add(filesend);
box1.add(exit);
Boxbox2=Box.createHorizontalBox();
emote=newJComboBox();
emote.setModel(newDefaultComboBoxModel(newString[]{"表情","微笑","甜笑","惊喜","嘻嘻","扮酷","嘿嘿","傻笑","好奇","媚眼","鬼脸","陶醉","害羞","生气","嚷嚷","发怒","伤心","高明","菜鸟","问号","狂笑","大哭","示爱","呻吟","想想"}));
emote.setEnabled(false);
JLabeljlintput=newJLabel("输入聊天内容");
box2.add(jlintput);
box2.add(inputContent);
box2.add(emote);
box2.add(sendtoall);
box2.add(sendtoone);
listen.addActionListener(this);
connection.addActionListener(this);
filesend.addActionListener(this);
exit.addActionListener(this);
sendtoall.addActionListener(this);
sendtoone.addActionListener(this);
Boxbox3=Box.createHorizontalBox();
box3.add(chatResult);
thread=newThread(this);
Boxbox0=Box.createVerticalBox();
box0.add(Box.createVerticalStrut(10));
box0.add(box1);
box0.add(Box.createVerticalStrut(10));
box0.add(box3);
box0.add(Box.createVerticalStrut(10));
box0.add(box2);
box0.add(Box.createVerticalStrut(10));
add(box0);
setBounds(10,30,500,400);
setBackground(newColor(80,212,248));
setVisible(true);
validate();
addWindowListener(newWindowAdapter(){
publicvoidwindowClosing(WindowEvente){
System.exit(0);
try{
socket.close();
}catch(IOExceptione1){
e1.printStackTrace();
}
}
});
}
publicvoidactionPerformed(ActionEvente){
ActionProcessactionProcess=newActionProcess(this);
try{
actionProcess.action(e);
}catch(Exceptione1){
e1.printStackTrace();
}
}
publicvoidrun()
{
Strings=null;
while(true){
try
{
s=in.readUTF();
chatResult.append("\n"+s);
}
catch(IOExceptione)
{
chatResult.setText("与服务器断开连接");
try
{
socket.close();
}catch(Exceptionep){}
break;
}
}
}
}
(3)ChatServer.java
packagechat;
import.*;
importjava.io.*;
importjava.util.*;
publicclassChatServer
{
publicstaticvoidmain(String[]args)throwsException{
ServerSocketsvSocket=null;
Vectorthreads=newVector();
try{
svSocket=newServerSocket(5555);
}catch(Exceptionex){
return;
}
try{
intnid=0;
while(true){
Socketsocket=svSocket.accept();
ServerThreadst=newServerThread(socket,threads);
st.setID(nid++);
threads.add(st);
newThread(st).start();
for(inti=0;iServerThreadtemp=(ServerThread)threads.elementAt(i);
}
}
}catch(Exceptionex){
}
}
}
classServerThreadimplementsRunnable{
privateVectorthreads;
privateSocketsocket=null;
privateDataInputStreamin=null;
privateDataOutputStreamout=null;
privateintnid;
publicServerThread(Socketsocket,Vectorthreads){
this.socket=socket;
this.threads=threads;
try{
in=newDataInputStream(socket.getInputStream());
out=newDataOutputStream(socket.getOutputStream());
}
catch(Exceptionex){
}
}
publicvoidrun(){
try{
while(true){
Stringreceive=in.readUTF();
if(receive==null)
return;
if(receive.contains("黯然下线了")){
for(inti=0;iServerThreadst=(ServerThread)threads.elementAt(i);
st.write("***"+receive+"***");
}
}
elseif(receive.contains("上线了")){
for(inti=0;iServerThreadst=(ServerThread)threads.elementAt(i);
st.write("<"+getID()+">:
"+receive);
}
}
elseif(receive.contains("监听中")){
for(inti=0;iServerThreadst=(ServerThread)threads.elementAt(i);
st.write("***"+receive+"***");
}
}
elseif(receive.contains("说")){
if(receive.contains("大家")){
for(inti=0;iServerThreadst=(ServerThread)threads.elementAt(i);
st.write("<"+getID()+">:
"+receive);
}
}
else{
inttemp=receive.indexOf("<");
inttemp1=receive.indexOf(">");
StringtempS=receive.substring(temp+1,temp1);
inti=Integer.parseInt(tempS);
ServerThreadst=(ServerThread)threads.elementAt(i);
st.write("<"+getID()+">:
"+receive);
st=(ServerThread)threads.elementAt(getID());
st.write("<"+getID()+">:
"+receive);
}
}
else{
ServerThreadst=(ServerThread)threads.elementAt(getID());
st.write("***"+receive+"***");
}
}
}catch(Exceptionex){
threads.removeElement(this);
ex.printStackTrace();
}
try{
socket.close();
}catch(Exceptionex){
ex.printStackTrace();
}
}
publicvoidwrite(Stringmsg){
synchronized(out){
try{
out.writeUTF(msg);
}catch(Exceptionex){
}
}
}
publicintgetID(){
returnthis.nid;
}
publicvoidsetID(i