网络编程BBS聊天程序实验报告.docx
- 文档编号:24241726
- 上传时间:2023-05-25
- 格式:DOCX
- 页数:19
- 大小:219.93KB
网络编程BBS聊天程序实验报告.docx
《网络编程BBS聊天程序实验报告.docx》由会员分享,可在线阅读,更多相关《网络编程BBS聊天程序实验报告.docx(19页珍藏版)》请在冰豆网上搜索。
网络编程BBS聊天程序实验报告
网络编程技术
大作业
项目开发人
开发人班级
开发人学号
开发人专业
软件工程
项目名称
多线程并发服务器-聊天室
成绩
(70%)
修改履历
修改编号
日期
修改人
版本号
修改内容
1
2010-4-26
1.0
2
3
目录
1文档概述5
1.1文档目的和范围5
1.2术语/缩略语5
1.3参考文档5
2系统概述5
2.1项目说明5
2.2需求分析5
2.3可行性或难点分析6
3通信协议设计6
3.1通信流程6
3.2数据格式6
3.3会话举例6
4系统设计说明6
4.1模块整体结构图6
4.2使用说明书6
5模块详细说明6
5.1核心通信模块7
5.1.1socket函数的功能7
5.1.2通信时序图7
5.2用户接口模块7
5.3类/接口/函数说明7
6结论7
6.1自我评价或总结7
6.2需要进一步学习的内容7
6.3系统扩展计划7
1文档概述
1.1文档目的和范围
该文档是为开发人员及后期测试人员作为参考的文档,主要记录了从项目说明到项目实现的全过程的记录。
1.2术语/缩略语
序号
术语/缩略语
说明
1
API
应用程序编程接口
2
Socket
网络套接口
1.3参考文档
序号
文档名
作者
时间
版本
1
Java网络高级编程
殷兆麟
2
Java实例精通
李相国
2009.3
第一版
2系统概述
2.1项目说明
该项目是一个BBS聊天程序,分为客户端和服务器两部分。
主要实现一个服务器和多个客户端之间的通讯。
运行环境:
操作系统:
Win7
Java集成开发环境:
Myeclipse
2.2需求分析
该程序实现局域网内的聊天功能,包括服务器端程序和客户端程序两部分。
客户端程序:
可连接到服务器,并将消息发送到服务器端和接受服务器端发送来的信息。
服务器端程序:
负责发送用户列表和转发客户端发送来的信息
2.3可行性或难点分析
与现有聊天工具相比,此聊天系统有很大的局限性,首先,该聊天系统只能实现一些简单的聊天工具的功能(发送文字),暂不支持文件传输及语音聊天等功能。
用户需自己建立聊天室,自己充当服务器,其它用户可进入聊天室。
同时网络环境复杂,如防火墙阻挡等因素,并不能保证在任何情况下都能正常使用。
3通信协议设计
3.1通信流程
服务器端:
(1)创建服务器对象
(2)从服务器端接收客户端请求
(3)创建一个服务线程处理新的连接请求
(4)在服务线程中,从Socket中获得I/O流
(5)关闭I/O流
(6)关闭Socket
客户端:
(1)创建Socket对象
(2)获得输入、输出流
(3)对输入输出流进行读写操作
(4)关闭输入输出流
(5)关闭客户端
3.2数据格式
3.3会话举例
1.服务器等待客户端的连接请求。
2.客户wenying登录。
3.服务器端显示wenying的IP地址,并显示连接成功。
4.客户longqi登录。
5.服务器显示longqi的IP地址,并显示连接成功。
6.发起会话。
7.退出聊天室
4系统设计说明
4.1
模块整体结构图
4.2使用说明书
用户在用户框输入用户名即可登录聊天室,在消息框输入要发送消息,即可发送信息给对方。
用户亦可群发消息。
用户点击退出即可退出聊天室。
用户可同时看到在线人数。
5模块详细说明
5.1核心通信模块
客户端:
classListenClentThreadextendsThread{
Stringname=null;//存储客户端连接后的name信息
BufferedReaderbr=null;//客户端接受服务器数据的输入流
PrintStreamps=null;//实现从客户端发送数据到服务器的打印流
Socketsocket=null;//存储客户端的socket信息
BBSClientparent=null;//存储当前运行的ChatClient实例
booleanrunning=true;
//构造方法
publicListenClentThread(BBSClientp,Stringn,Sockets){
//接受参数
parent=p;
name=n;
socket=s;
try{
//实例化两个数据流
br=newBufferedReader(newInputStreamReader(s
.getInputStream()));
ps=newPrintStream(s.getOutputStream());
}catch(IOExceptione){
System.out.println("Error:
"+e);
parent.disconnect();
}
}
//停止侦听
publicvoidtoStop(){
this.running=false;
}
//线程运行方法
publicvoidrun(){
Stringmsg=null;
while(running){
msg=null;
try{
//读取从服务器传来的信息
msg=br.readLine();
System.out.println("receivemsg:
"+msg);
}catch(IOExceptione){
System.out.println("Error:
"+e);
parent.disconnect();
}
//如果从服务器传来的信息为空则断开此次连接
if(msg==null){
parent.listener=null;
parent.soc=null;
parent.peopleList.removeAll();
running=false;
return;
}
//用StringTokenizer类来实现读取分段字符
StringTokenizerst=newStringTokenizer(msg,Message.SEPERATOR);
//读取信息头即关键字用来识别是何种信息
Stringkeyword=st.nextToken();
if(keyword.equals(Message.PEOPLE_IDENTIFER)){
//如果是PEOPLE则是服务器发来的客户连接信息
//主要用来刷新客户端的用户列表
parent.peopleList.removeAll();
//遍历st取得目前所连接的客户
while(st.hasMoreTokens()){
Stringstr=st.nextToken();
parent.peopleList.add(str);
}
}elseif(keyword.equals(Message.MSG_IDENTIFER)){
//如果关键字是MSG则是服务器传来的聊天信息,
//主要用来刷新客户端聊天信息区将每个客户的聊天内容显示出来
Stringusr=st.nextToken();
parent.chatContentTextArea.append(usr);
parent.chatContentTextArea.append(st.nextToken("\0"));
parent.chatContentTextArea.append("\r\n");
}elseif(keyword.equals(Message.QUIT_IDENTIFER)){
//如果关键字是QUIT则是服务器关闭的信息,切断此次连接
System.out.println("Quit");
try{
running=false;
parent.listener=null;
parent.soc.close();
parent.soc=null;
}catch(IOExceptione){
System.out.println("Error:
"+e);
}finally{
parent.soc=null;
parent.peopleList.removeAll();
}
break;
}
}
}
}
服务器端:
*处理客户端发送的请求的线程
classMessFromClientextendsThread{
Socketsocket;//存储一个连接客户端的socket信息
StringclientName;//存储客户端的连接姓名
StringclientIP;//存储客户端的ip信息
BufferedReaderbr;//用来实现接受从客户端发来的数据流
PrintStreamps;//用来实现向客户端发送信息的打印流
booleanrunning=true;
/**构造方法*/
publicMessFromClient(Sockets){
socket=s;
try{
//初始化输入输出流
br=newBufferedReader(newInputStreamReader(socket
.getInputStream()));
ps=newPrintStream(socket.getOutputStream());
//读取收到的信息,第一条信息是客户端的名字、IP信息
StringclientInfo=br.readLine();
//读取信息,根据消息分隔符解析消息
StringTokenizerstinfo=newStringTokenizer(clientInfo,
Message.SEPERATOR);
Stringhead=stinfo.nextToken();
if(head.equals(Message.CONNECT_IDENTIFER)){
if(stinfo.hasMoreTokens()){
//关键字后的第二段数据是客户名信息
clientName=stinfo.nextToken();
}
if(stinfo.hasMoreTokens()){
//关键字后的第三段数据是客户ip信息
clientIP=stinfo.nextToken();
}
System.out.println(head);//在控制台打印头信息
}
}catch(IOExceptione){
System.out.println("Error:
"+e);
}
}
/**向客户端发送消息*/
publicvoidsend(StringBuffermsg){
ps.println(msg);
ps.flush();
}
//线程运行方法
publicvoidrun(){
while(running){
Stringline=null;
try{
//读取客户端发来的数据流
line=br.readLine();
}catch(IOExceptione){
System.out.println("Error"+e);
BBSServer.disconnect(this);
BBSServer.RefreshRoom();
return;
}
//客户已离开
if(line==null){
BBSServer.disconnect(this);
BBSServer.RefreshRoom();
return;
}
StringTokenizerst=newStringTokenizer(line,Message.SEPERATOR);
Stringkeyword=st.nextToken();
//如果关键字是MSG则是客户端发来的聊天信息
if(keyword.equals(Message.MSG_IDENTIFER)){
StringBuffermsg=newStringBuffer(Message.MSG_IDENTIFER)
.append(Message.SEPERATOR);
msg.append(clientName);
msg.append(st.nextToken("\0"));
//再将某个客户发来的聊天信息发送到每个连接客户的聊天栏中
BBSServer.sendMsgToClients(msg);
}elseif(keyword.equals(Message.QUIT_IDENTIFER)){
//如果关键字是QUIT则是客户端发来断开连接的信息
BBSServer.disconnect(this);//服务器断开与这个客户的连接
//继续监听聊天室并刷新其他客户的聊天人名list
BBSServer.RefreshRoom();
running=false;
}
}
}
5.1.1socket函数的功能
SOCKETsocket(intaf,inttype,intprotocol);
各个参数意义如下:
af指所使用的协议族,通常为PF_INET,表示互联网协议族(TCP/IP协议族)。
type参数指定socket的类型:
SOCK_STREAM或SOCK_DGRAM,Socket接口还定义
了原始Socket(SOCK_RAW),允许程序使用低层协议。
protocol通常赋值为“0”。
Socket()调用返回一个整型socket描述符。
Socket描述符是一个指向内部数据结构的指针,它指向描述符表入口。
调用Socket()函数时,socket执行体将建立一个Socket,实际上“建立一个Socket”意味着为一个Socket数据结构分配了存储空间。
Socket执行体为用户管理描述符表。
两个网络程序之间的一个网络连接包括五种信息:
通信协议、本地协议地址、本地主机端口、远端主机地址和远端协议端口。
Socket数据结构中包括这五种信息。
在建立Socket后就可利用该返回值进行双方的通信
5.1.2通信时序图
5.2用户接口模块
聊天室的客户端程序,GUI界面。
publicclassBBSClientextendsJFrameimplementsActionListener{
//登陆聊天室的名字标签和输入框
JLabelnameLabel=newJLabel();
JTextFieldnameTextField=newJTextField(15);
//连接和断开连接的按钮
JButtonconnectButton=newJButton();
JButtondisConnectButton=newJButton();
JTextAreachatContentTextArea=newJTextArea(9,30);//聊天室内容的文本域
JButtonsendMsgButton=newJButton();//发送消息的按钮
JTextFieldmsgTextField=newJTextField(20);//消息输入框
JLabelmsglabel=newJLabel();
java.awt.ListpeopleList=newjava.awt.List(10);//聊天室用户列表
//初始化图形界面
publicvoidinit(){
this.setTitle("欢迎来到1号聊天室");
//初始化按钮和标签
nameLabel.setText("姓名:
");
connectButton.setText("登录");
connectButton.addActionListener(this);
disConnectButton.setText("退出");
disConnectButton.addActionListener(this);
//设置聊天内容不可编辑
chatContentTextArea.setEditable(false);
sendMsgButton.setText("发送信息");
sendMsgButton.addActionListener(this);
msgTextField.setText("");
//panel1放置输入姓名和连接两个按钮
JPanelpanel1=newJPanel();
panel1.setLayout(newFlowLayout());
panel1.add(nameLabel);
panel1.add(nameTextField);
panel1.add(connectButton);
panel1.add(disConnectButton);
//用于放置聊天信息显示和聊天人员列表
JPanelpanel2=newJPanel();
panel2.setLayout(newFlowLayout());
JScrollPanepane1=newJScrollPane(chatContentTextArea);
pane1.setBorder(newTitledBorder(BorderFactory.createEtchedBorder(
Color.white,newColor(134,134,134)),"聊天内容"));
panel2.add(pane1);
JScrollPanepane2=newJScrollPane(peopleList);
pane2.setBorder(newTitledBorder(BorderFactory.createEtchedBorder(
Color.white,newColor(134,134,134)),"在线用户"));
panel2.add(pane2);
//用于放置发送信息区域
JPanelpanel3=newJPanel();
panel3.setLayout(newFlowLayout());
panel3.add(msglabel);
panel3.add(msgTextField);
panel3.add(sendMsgButton);
//将组件添加到界面
this.getContentPane().setLayout(newBorderLayout());
this.getContentPane().add(panel1,BorderLayout.NORTH);
this.getContentPane().add(panel2,BorderLayout.CENTER);
this.getContentPane().add(panel3,BorderLayout.SOUTH);
this.pack();
try{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SwingUtilities.updateComponentTreeUI(this);
}catch(Exceptione){
e.printStackTrace();
}
}
5.3类/接口/函数说明
服务器端:
退出菜单项事件:
exitActionPerformed
处理窗口关闭事件:
processWindowEvent
刷新聊天室事件:
RefreshRoom
向所有客户端群发消息事件:
sendMsgToClients
处理客户端发送的请求的线程:
MessFromClient
客户端:
关闭聊天室客户端事件:
processWindowEvent
客户端线程类:
ListenClentThread继承自Thread线程类,用来监听服务器端传来的信息
6结论
6.1自我评价或总结
通过这一次大作业,我学到了不少网络编程的知识。
在这课程设计期间我的同学帮助了我,有些东西是我们一起探讨,一起解决方法的。
这次作业,不仅磨砺了我的意志;同时还巩固了以前所学的知识,学到了不少书本上没有的知识;学到了很多java编程知识,并学会了简单的使用NetBeans来开发java程序的一些使用技巧,这次大作业是对我本学期所学的知识的检验,由此我发现了不少的问题。
可以说它给了我一次自我评估的机会。
通过它让我知道了那些方面我还是有欠缺的,促使我花时间弥补。
水平所限,致使程序实现的功能在方法上也许不是很完美,但我以后会多向老师请教,自己也要加强对Java的学习。
努力进一步提高自己的编程水平。
6.2需要进一步学习的内容
此次实验虽使用了部分Socket函数,但是应用并不深入,希望在以后的学习中更加深入了解Socket函数,及其各种函数的使用。
6.3系统扩展计划
在原
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 网络 编程 BBS 聊天 程序 实验 报告