网络编程技术设计说明书.docx
《网络编程技术设计说明书.docx》由会员分享,可在线阅读,更多相关《网络编程技术设计说明书.docx(25页珍藏版)》请在冰豆网上搜索。
网络编程技术设计说明书
网络编程技术
大作业说明书
题目:
图形界面的一对多聊天软件
课程:
网络编程技术
院(部):
计算机科学与技术
专业:
网络工程
班级:
学生姓名:
指导教师:
完成日期:
目录
图形界面的一对多的聊天软件的设计与实现1
一、问题描述1
二、小组成员及任务分配1
三、设计思想1
四、系统结构1
五、程序流程(或模块划分)2
六、源程序8
七、系统测试及操作界面24
结论27
参考文献28
图形界面的一对多的聊天软件的设计与实现
一、问题描述
利用Socket技术,编程实现一个图形界面的一对多的聊天软件。
需求如下:
一、建立聊天室,显示进入聊天室和离开聊天室的客户信息。
二、为每一对进行聊天的客户单独开一个图形界面的聊天窗口。
三、保存客户的聊天记录,并可以在聊天窗口中打开查询这些聊天记录。
二、小组成员及任务分配
本组所有成员在此次软件开发过程中的任务分配情况:
三、设计思想
系统需求分析:
控制端,服务器,客户端,发送消息,聊天记录;
首先启动后出现控制端界面;由控制端产生服务器与客户端;开始聊天;存放与读取聊天记录;结束聊天。
系统设计:
控制端:
显示进入聊天室和离开聊天室的客户信息,生成一对聊天室;
服务器与客户端功能:
输入聊天消息,发送消息,显示聊天消息,查看消息记录,退出;
四、系统结构
控制端:
在构造方法中设计界面、读取哈希表(存放用户对象,首次执行清空哈希表)、启动服务器(阻塞于accept()方法,等待用户连接);在事件监听器中监听启动客户端。
服务器与客户端:
设计界面;两者之间通过数据输入输出流交互信息;存放与读取消息记录采用数据输入输出流与文件输入输出流来实现;退出时告之对方己方已退出聊天室并告之控制台,结束聊天有两种形式:
一是点击退出按钮,二是发送“bye”消息。
五、程序流程(或模块划分)
程序流程图:
控制端:
判断用户是否已经加入聊天室
if(table.containsKey(textf.getText())){
JOptionPane.showMessageDialog(null,"该客户端已经开启,请重新输入客户端名!
");
extf.setText("");
}
服务器在构造方法中启动
启动客户端方法
newThread(newRunnable(){
publicvoidrun(){
Stringstr1=textf.getText();
client1c1=newclient1();
c1.test(str1);}
}).start();
主机接收客户机发来的消息,并将聊天记录存入文件
fos=newFileOutputStream("src/chat/infoCache.txt",true);
dos=newDataOutputStream(fos);
din=newDataInputStream(socket.getInputStream());
while(true){
s2=din.readUTF();
texta.append(clientName+"说:
"+s2+"\n");
dos.writeUTF(clientName+"说:
"+s2);
if(s2.equalsIgnoreCase("bye")){
texta.append("断开连接···"+"\n");
chatRoom.texta.append("\n"+clientName+"离开了聊天室,与"+"主机连接中断");
din.close();
dout.close();
fos.close();
dos.close();
}
}
主机向客户机发送消息,并将聊天记录存入文件
fos=newFileOutputStream("src/chat/infoCache.txt",true);
dos=newDataOutputStream(fos);
texta.append("主机说:
"+s1+"\n");
dos.writeUTF("主机说:
"+s1);
主机读取消息记录:
fis=newFileInputStream("src/chat/infoCache.txt");
dis=newDataInputStream(fis);
Stringstr=dis.readUTF();
while(!
str.equals("")){
te.append("\n"+str);
str=dis.readUTF();
}
客户机接收主机发来的消息,并将聊天记录存入文件
din=newDataInputStream(client.getInputStream());
fos=newFileOutputStream("src/chat/"+clientName+".txt",true);
dos=newDataOutputStream(fos);
while(true){
s2=din.readUTF();
texta1.append("主机说:
"+s2+"\n");
dos.writeUTF("主机说:
"+s2);
f(s2.equalsIgnoreCase("bye")){
texta1.append("断开连接···"+"\n");
chatRoom.texta.append("\n"+"主机离开了聊天室,与"+clientName+"连接中断");
din.close();
dout.close();
}
}
客户机向主机发送消息,并将聊天记录存入文件
s1=textf1.getText().trim();
texta1.append(clientName+"说:
"+s1+"\n");
try{
dout=newDataOutputStream(client.getOutputStream());
fos=newFileOutputStream("src/chat/"+clientName+".txt",true);
dos=newDataOutputStream(fos);
dos.writeUTF(clientName+"说:
"+s1);
dout.writeUTF(s1);
if(s1.equalsIgnoreCase("bye")){
texta1.append("断开连接···"+"\n");
din.close();
dout.close();
}
}
客户机读取消息记录:
fis=newFileInputStream("src/chat/"+clientName+".txt");
dis=newDataInputStream(fis);
Stringstr=dis.readUTF();
while(!
str.equals("")){
te.append("\n"+str);
str=dis.readUTF();
}
六、源程序
1、publicclasschatRoomextendsJFrameimplementsActionListener{
JFramej;
staticServerSocketserver;
DataInputStreamdin;
DataOutputStreamdout;
Strings1,s2,s3;
JTextFieldtextf;
staticJTextAreatexta;
JLabellabel;
JButtonokbtn;
JButtonexbtn;
JScrollPanescroll;
Socketsocket;
StringclientName=null;
clientInfoclient=null;
Hashtabletable=null;
Filefile=newFile("src/chat/clientInfo.txt");
FileInputStreamin1=null;
ObjectInputStreamin2=null;
FileOutputStreamout1=null;
ObjectOutputStreamout2=null;
publicchatRoom(){//构造方法
j=newJFrame("聊天室");
textf=newJTextField(20);
label=newJLabel("输入客户端名");
okbtn=newJButton("加入聊天室");
exbtn=newJButton("退出");
textf.addActionListener(this);
okbtn.addActionListener(this);
exbtn.addActionListener(this);
JPaneljp1=newJPanel();
jp1.add(label);
jp1.add(textf);
jp1.add(okbtn);
jp1.add(exbtn);
j.add(jp1,BorderLayout.SOUTH);
texta=newJTextArea(12,12);
scroll=newJScrollPane(texta);
j.add(scroll);
j.setSize(600,600);
j.setVisible(true);
j.setBackground(Color.blue);
j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
try{//将哈希表从文件读出,并清空哈希表
in1=newFileInputStream(file);
in2=newObjectInputStream(in1);
table=(Hashtable)in2.readObject();
table.clear();
in1.close();
in2.close();
}catch(Exceptionee){
ee.printStackTrace();
System.out.println("创建哈希表出现问题!
");
}
texta.append("服务器正在端口号5500监听客户端的连接请求······");
serverserver2=newserver();//调用服务器的方法
server2.run();
}
publicstaticvoidmain(String[]args){
//TODOAuto-generatedmethodstub
chatRoomcr=newchatRoom();
}
publicvoidactionPerformed(ActionEvente){//监听动作事件,实现触发的动作事件
//TODOAuto-generatedmethodstub
if(e.getSource()==okbtn){
client=newclientInfo();
if(textf.getText()!
=null){
if(table.containsKey(textf.getText())){
JOptionPane.showMessageDialog(null,"该客户端已经开启,请重新输入客户端名!
");
textf.setText("");
}
else{
//client.setStrName(textf.getText());
try{
out1=newFileOutputStream(file);
out2=newObjectOutputStream(out1);
table.put(textf.getText(),client);
out2.writeObject(table);
out2.close();
out1.close();
}catch(Exceptionee){
ee.printStackTrace();
}
newThread(newRunnable(){
publicvoidrun(){
Stringstr1=textf.getText();
client1c1=newclient1();
c1.test(str1);
}
}).start();
texta.append("\n"+textf.getText()+"加入了聊天室");
textf.setText("");
}
}
}
if(e.getSource()==exbtn){
System.exit(0);
}
}
}
2、publicclassserver{
publicvoidrun(){//
ServerSocketserSkt=null;
SocketcsSkt=null;
chatServerserver1;
try{
serSkt=newServerSocket(5500);//在端口号5500实例化一个对象
}catch(IOExceptione){
e.printStackTrace();
}
while(true){
try{
System.out.println("服务器正在5500端口监听客户的连接请求······");
csSkt=serSkt.accept();//等待客户机的连接
server1=newchatServer(csSkt);
newThread(server1).start();//调用服务器类的run方法,接受客户机发送来消息
}catch(IOExceptione){
e.printStackTrace();
}
}
}
}
3、publicclasschatServerextendsJFrameimplementsActionListener,Runnable{
DataInputStreamdin;
DataOutputStreamdout;
Strings1,s2,s3;
JTextFieldtextf;
JTextAreatexta;
JLabellabel;
JButtonokbtn;
JButtonexbtn;
JButtoninfoRecord;
JScrollPanescroll;
JFramej1;
Socketsocket;
StringclientName=null;
FileInputStreamfis;
FileOutputStreamfos;
DataInputStreamdis;
DataOutputStreamdos;
publicchatServer(Sockets)throwsIOException{//构造方法
j1=newJFrame("主机");
textf=newJTextField(20);
label=newJLabel("发送消息");
okbtn=newJButton("发送");
infoRecord=newJButton("消息记录");
exbtn=newJButton("退出");
textf.addActionListener(this);
okbtn.addActionListener(this);
exbtn.addActionListener(this);
infoRecord.addActionListener(this);
JPaneljp2=newJPanel();
jp2.add(label);
jp2.add(textf);
jp2.add(okbtn);
jp2.add(infoRecord);
jp2.add(exbtn);
j1.add(jp2,BorderLayout.SOUTH);
texta=newJTextArea(12,12);
scroll=newJScrollPane(texta);
j1.add(scroll);
j1.setSize(600,600);
j1.setVisible(true);
j1.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
socket=s;
din=newDataInputStream(s.getInputStream());
dout=newDataOutputStream(s.getOutputStream());
clientName=din.readUTF();
System.out.println("同"+clientName+""+socket.getInetAddress().toString()+","+socket.getPort()+"建立连接,开始聊天");
}
publicvoidrun(){//接收客户机发来的消息,并将聊天记录存入文件
try{
fos=newFileOutputStream("src/chat/infoCache.txt",true);
dos=newDataOutputStream(fos);
din=newDataInputStream(socket.getInputStream());
while(true){
s2=din.readUTF();
texta.append(clientName+"说:
"+s2+"\n");
dos.writeUTF(clientName+"说:
"+s2);
if(s2.equalsIgnoreCase("bye")){
texta.append("断开连接···"+"\n");
chatRoom.texta.append("\n"+clientName+"离开了聊天室,与"+"主机连接中断");
din.close();
dout.close();
fos.close();
dos.close();
}
}
}catch(IOExceptione){
//TODOAuto-generatedcatchblock
System.out.println("链接已经断开!
!
!
");
}
}
publicvoidexit(){//断开连接
try{
dout.writeUTF("主机离开了聊天室");
din.close();
dout.close();
dos.close();
fos.close();
chatRoom.texta.append("\n"+"主机离开了聊天室,与"+clientName+"连接中断");
}catch(Exceptione){
}
//System.exit(0);
}
publicvoidactionPerformed(ActionEvente){////动作事件监听器,实现触发的事件
//TODOAuto-generatedmethodstub
if(e.getSource()==okbtn){
s1=textf.getText().trim();
try{
fos=newFileOutputStream("src/chat/infoCache.txt",true);
dos=newDataOutputStream(fos);
texta.append("主机说:
"+s1+"\n");
dos.writeUTF("主机说:
"+s1);
}catch(FileNotFoundExceptione2){
//TODOAuto-generatedcatchblock
e2.printStackTrace();
}catch(IOExceptione1){
}
try{
dout=newDataOutputStream(socket.getOutputStream());
dout.writeUTF(s1);
if(s1.equalsIgnoreCase("bye")){
texta.append("断开连接···"+"\n");
din.close();
dout.close();
}
}catch(Exceptione1){
}
textf.setText("");
textf.requestFocus();
}
if(e.getSource()==infoRecord){
JDialogjd=newJDialog();
jd.setTitle("主机和客户机的消息记录");
JTextAreate=newJTextArea(120,120);
JScrollPaneroll=newJScrollPane(te);
te.setEditable(false);
jd.add(roll);
jd.setSize(600,600);
jd.setVisible(true);
jd.setBackground(Color.blue);
jd.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
try{
fis=newFileInp