网络聊天室报告.docx
《网络聊天室报告.docx》由会员分享,可在线阅读,更多相关《网络聊天室报告.docx(24页珍藏版)》请在冰豆网上搜索。
网络聊天室报告
目录
1.序言1
1.1背景1
1.2相关技术1
1.2.1JAVA概述1
1.2.2套接字1
1.2.3TCP三次握手2
2.程序设计与实现2
2.1需求分析2
2.2程序结构3
2.2.1多用户在线方案3
2.2.2软件框架3
2.3代码实现3
2.3.1用户登录模块3
2.3.2用户列表模块5
2.3.3文本聊天模块7
2.3.4文件传输模块10
3.测试结果10
3.1测试环境与使用方法10
3.2功能测试10
3.2.1用户登录及用户列表10
3.2.2文本聊天11
3.2.2.1群聊11
3.2.2.2私聊12
3.2.2.3字体设置13
3.2.3文件传输14
4.总结15
参考文献16
1.序言
1.1背景
在网络越来越发达的今天,人们对网络的依赖越来越多,各种网络应用层出不穷,网络编程越来越受大广大程序员的重视。
网络编程的目的就是指直接或间接地通过网络协议与其他计算机进行通讯。
网络编程中有两个主要的问题,一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输。
在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以唯一地确定Internet上的一台主机。
而TCP层则提供面向应用的可靠的或非可靠的数据传输机制,这是网络编程的主要对象,一般不需要关心IP层是如何处理数据的。
目前较为流行的网络编程模型是客户机/服务器(C/S)结构。
即通信双方一方作为服务器等待客户提出请求并予以响应。
客户则在需要服务时向服务器提出申请。
服务器一般作为守护进程始终运行,监听网络端口,一旦有客户请求,就会启动一个服务进程来响应该客户,同时自己继续监听服务端口,使后来的客户也能及时得到服务。
网络聊天是网络编程的典型应用之一,编写网络聊天软件对于学习网络编程无疑有着很大的帮助。
本小组编写本软件,旨在通过软件的编写与实现,来提高对网络编程的理解和掌握。
1.2相关技术
1.2.1JAVA概述
JAVA语言有下面一些特点:
简单、面向对象、分布式、解释执行、鲁棒、安全、体系结构中立、可移植、高性能、多线程以及动态性。
丰富的类库JAVA提供了大量的类以满足网络化、多线程、面向对象系统的需要。
语言包提供的支持包括字符串处理、多线程处理、数学函数处理等,可以用它简单地实现JAVA程序的运行平台。
实用程序包提供的支持包括哈希表、堆栈、可变数组、时间和日期等。
输入输出包用统一的"流"模型来实现所有格式的I/O,包括文件系统、网络、输入低级网络包用于实现Socket编程。
抽象图形用户接口包实现了不同平台的计算机的图形用户接口部件,包括窗口、菜单、滚动条、对话框等,使得JAVA可以移植到不同平台的机器。
网络包支持Internet的TCP/IP协议,提供了与Internet的接口。
它支持URL连接,WWW的即时访问,并且简化了用户/服务器模型的程序设计。
JAVA和C、C++对于变量声明、参数传递、操作符、流控制等使用了相同的传统,使得熟悉C、C++的程序员能很方便地进行编程。
同时,JAVA为了实现其简单、鲁棒、安全等特性,也摒弃了C和C++中许多不合理的内容。
1.2.2套接字
Socket,简称套接字,用于实现网络上客户和服务器之间的连接。
也就是说网络上两个或两个以上双工方式通信的进程之间总有一个连接,这个连接的端点成为套接字,套接字是在比较低的层次上通信的。
具体的说:
一个服务器应用程序一般侦听一个特定的端口等待客户端的连接请求,当一个连接请求到达时,客户端和服武器端建立一个通信连接,在连接过程中,客户端被分配一个本地端口与一个Socket建立连接,客户端通过写Socket来通知服务器,以读Socket中的信息,类似的服务器也获得一个本地端口,它需要一个新的端口号来侦听原始端口上的其他连接请求。
服务器也通过它的本地端口连接一个Socket,通过读写和客户端通信。
Socket程序的工作过程:
1.建立Socket连接:
在通信开始之前由通信双方确认身份,建立一条专用的虚拟连接道。
2.数据通信:
利用虚拟连接通道传送数据信息进行通信。
3.关闭:
通信结束时,再将所建的虚拟连接拆除。
1.2.3TCP三次握手
第一次握手:
原主机发送一个带有本次连接的序号的请求的一个数据帧
第二次握手:
目的主机收到请求后,如果同意连接,则发回一个带有一个本次连接序号和源端机连接序列号的确认。
第三此握手:
源端机收到含有两次初始序列号的应答后,再向目的主机发送一个带有两次连接的序列号的确认。
具体过程如下:
2.程序设计与实现
2.1需求分析
做为一个局域网内的即时聊天程序,除了基本的聊天功能,文件传输也是经常用到的功能。
本软件需具有以下几个功能:
1.用户登录
设立一个服务器,实现多用户即时通讯;用户在登录的同时需输入一些个性化的信息,以便于各用户之前的识别。
2.文本聊天
聊天室功能,即所谓的群聊,聊天内容所有人可见;保密聊天功能,即所谓的私聊,聊天内容仅聊天双方可见;用户可对字体进行设置。
3.文件转输
多线程,收发可同时进行。
2.2程序结构
2.2.1多用户在线方案
采用客户机/服务器(C/S)结构。
即通信双方一方作为服务器等待客户提出请求并予以响应。
客户则在需要服务时向服务器提出申请。
服务器一般作为守护进程始终运行,监听网络端口,一旦有客户请求,就会启动一个服务进程来响应该客户,同时自己继续监听服务端口,使后来的客户也能及时得到服务。
2.2.2软件框架
2.3代码实现
开发环境:
WindowsXPProfessionalSP3+JDK1.6.0_18+NetBeansIDE6.8
2.3.1用户登录模块
只列出程序界面以及与服务器端通讯部分的代码:
客户端:
classConnectextendsJFrameimplementsActionListener,ItemListener,KeyListener
{
…………………………………………………………………………………………………………………………………
publicvoidlink()throwsException
{//连接服务器
hostName=hostText.getText().trim();
port=Integer.parseInt(portText.getText());
client=newSocket(hostName,port);//创建一个流套接字并将其连接到指定IP地址的指定端口号。
in=newBufferedReader(newInputStreamReader(client.getInputStream()));
out=newPrintWriter(client.getOutputStream());
out.println(nameText.getText()+"&"+sex);
out.flush();
}
……………………………………………………………………………………………………………………………………
服务器端:
publicstaticvoidaddConnection(Sockets,ClientProccp)
{
if(connections==null)
{
connections=newVector();
}
connections.addElement(s);
if(clients==null)
{
clients=newVector();
}
clients.addElement(cp);
}
publicstaticvoiddeleteConnection(Sockets,ClientProccp)
throwsIOException
{
if(connections!
=null)
{
connections.removeElement(s);
s.close();
}
if(clients!
=null)
{
clients.removeElement(cp);
}
}
publicstaticVectorgetClients()
{
returnclients;
}
2.3.2用户列表模块
只列出程序界面以及与服务器端通讯部分的代码:
客户端:
publicvoidvalueChanged(ListSelectionEvente)
{//监听下拉列表的显示内容
if(e.getSource()==peopleList)
{
try
{
Stringselect=(String)peopleList.getSelectedValue();
if(select!
=null)
{//确保选择非空
String[]userInfo=select.split("〖");
Stringname=userInfo[0].trim();//提取名字
if(!
name.equals(chf.myName))
{//不能添加自己
intcount=chf.perponsComboBox.getItemCount();
for(inti=0;i{
chf.perponsComboBox.setSelectedIndex(i);//选择第i项
StringstrName=(String)chf.perponsComboBox
.getSelectedItem();
if(name.equals(strName))
{//如果已经在列表中,就复合框中选中,所以要确保没有重名
return;
}
}
//如果没有添加,就会执行下面语句添加
chf.perponsComboBox.addItem(name);
}
}
}catch(Exceptionee)
{
System.out.println("发生错误在valueChanged"+ee);
}
}
}
publicvoidactionPerformed(ActionEvente)
{
if(e.getSource()==refurbishButton)
{//如果监听到要刷新列表
try
{
listModel.clear();//清空列表
chf.out.println("refurbish");//发送刷新请求到服务器
chf.out.flush();
}catch(Exceptionee)
{
}
}
}
服务器端:
publicStringgetName()
{
returnname;
}
publicStringgetSex()
{
returnsex;
}
publicSocketgetSocket()
{
returns;
}
privatevoidupdateList()
{
//更新用户列表(即发送当前在聊天室的用户到新来的用户列表中)
Vectorcs=ChatServer.getClients();
if(cs!
=null)
{
for(Enumeratione=cs.elements();e.hasMoreElements();)
{
ClientProccp=(ClientProc)e.nextElement();
Stringexist_name=cp.getName();
Stringexit_sex=cp.getSex();
/**
*for(inti=0;i*=((ClientProc)cs.elementAt(i)).getName();Stringexit_sex=
*((ClientProc)cs.elementAt(i)).getSex();
*/
System.out.println("old"+"&"+exist_name+"&"+exit_sex);
out.println("old"+"&"+exist_name+"&"+exit_sex);
out.flush();
}
}
}
2.3.3文本聊天模块
只列出程序界面以及与服务器端通讯部分的代码:
客户端:
if(e.getSource()==sentButton)
{//如果监听到发送信息按钮被点击
try
{
mywords=inMsgField.getText();
if((mywords.trim()).length()!
=0)
{//不能发送空消息也不能都发空格
if(withWho.equals("所有人"))
{
outmsg=mywords;
//发送到服务器
out.println(outmsg);
out.flush();
//显示到我的频道里面
insert(myMsgArea,myName+":
"+mywords);
//myMsgArea.setCaretPosition(myMsgArea.getText().length(
//));
}else
{//对某个人交谈
outmsg="withWho"+"&"+"privateFalse"+"&"
+withWho+"&"+mywords;
if(privateTalkFlag)
{
outmsg="withWho"+"&"+"privateTure"+"&"
+withWho+"&"+mywords;
insert(myMsgArea,"您对『"+withWho+"』说:
"
+mywords);
//myMsgArea.setCaretPosition(myMsgArea.getText().
//length());
}else
{
insert(myMsgArea,myName+"对『"+withWho+"』说:
"
+mywords);
}
//myMsgArea.setCaretPosition(myMsgArea.getText().length(
//));
//发送到服务器
out.println(outmsg);
out.flush();
}
}
}catch(Exceptionee)
{
ee.printStackTrace();
insert(myMsgArea,"与服务器连接中断,请重新登录!
");
//myMsgArea.setCaretPosition(myMsgArea.getText().length());
}finally
{
inMsgField.setText("");//清空输入框
}
}
服务器端:
/****发送信息给所有的人*/
publicstaticvoidsendAll(Strings)
{
if(connections!
=null)
{
for(Enumeratione=connections.elements();//Enumeration过时的接口,
//可以用foreach循环
e.hasMoreElements();)
{
try
{
PrintWriterpw=newPrintWriter(((Socket)e.nextElement())
.getOutputStream());
pw.println(s);
pw.flush();
}catch(IOExceptionex)
{
ex.printStackTrace();
}
}
}
System.out.println(s);
}
/****发送信息给单独一个人*/
publicstaticbooleansendOne(Stringname,Stringmsg)
{
if(clients!
=null)
{
for(Enumeratione=clients.elements();e.hasMoreElements();)
{
ClientProccp=(ClientProc)e.nextElement();
if((cp.getName()).equals(name))
{
try
{
PrintWriterpw=newPrintWriter((cp.getSocket())
.getOutputStream());
pw.println(msg);
pw.flush();
returntrue;//返回值为真,找到了这个人可以进行聊天
}catch(IOExceptionioe)
{
ioe.printStackTrace();
}
}
}
}
returnfalse;//没有找到这个人,应该是此人已经退出了聊天室
}
2.3.4文件传输模块
此部分由同组其他同学完成。
3.测试结果
3.1测试环境及使用方法
WindowsXPProfessionalSP3+JDK1.6.0_18
在局域网内一台主机上运行服务器端,其他机器运行客户端,登录时地址填写为服务器所在主机的IP地址。
3.2功能测试
3.2.1用户登录及用户列表
个性登陆:
登录框中包含个人名称,设置服务器和端口,选择性别。
功能截图:
3.2.2文本聊天
3.2.2.1群聊
群聊天功能:
任意用户直接在编辑区编辑文字后点击发送,所有在线用户均可在群聊天界面看到聊天内容。
功能截图:
郭磊对仝志方公开打招呼
郭磊对所有人打招呼
在三人的聊天窗口中均收到了郭磊发出的两天信息
3.2.2.2私聊
私聊功能:
若在用户显示界面双击某位在线用户并且在聊天室界面最下部勾选“私聊”,则可以进行私聊,只有聊天双方可在悄悄话界面看到自己的聊天内容。
功能截图:
郭磊对仝志方发出私人消息
仝志方在“消消话”中收到了郭磊发出的私人消息
无名氏的聊天窗口中没有看到认何有关郭磊发送私人消息给仝志方的信息
3.2.2.3字体设置
在编辑区录入文字时,可对字体进行设置。
功能截图:
3.2.3文件传输
文件传输功能:
用户在用户显示界面双击要发送到的联系人,勾选“私聊”选框后,把要发送的文件拖拽到“欲发送的文件”区域,点击“发送文件”按钮即可。
若开始或中途想放弃传送则可单击“取消发送”按钮。
用户点击发送后,在悄悄话区域会告知接收者发来文件,若接收者接收则单击“接收文件”按钮,然后设定本地保存位置;若不接收则点击“拒绝接收”按钮。
功能截图:
在点击保存后,会弹出窗口等待用户选择保存路径
4.总结
JAVA网络编程课程设计,让我有很多的收获与体会。
在整个课程设计的过程中,我对JAVA网络编程的相关知识有了进一步的了解和掌握。
此外,在完成设计的过程中,我查阅了不少资料,我的相关知识体系得到了一个系统性的复习、深入和锻炼。
当然,这次课程设计也暴露出了我的一些不足。
整个过程进行得比较吃力,说明我对知识的掌握以及平时的训练还比较欠缺。
应当以此次课程设计为引导,趁热打铁,对相关知识进行进一步的巩固。
参考文献:
[1]BruceEckel.Java编程思想[M].北京:
电子工业出版社,2006
[2]CaySHorstmann,GaryCornell.Java2核心技术[M].北京:
机械工业出版社,2006
[3]陈刚.Eclipse从入门到精通[M].北京:
清华大学出版社,2005
[4]王森.快易通Java程序设计[M].北京:
北京大学出版社,2000
[5]叶至军.由浅入深——Java2自学手册[M].北京:
人民邮电出版社,2004
[6]王森.Java语言程序设计[M].北京:
清华大学出版社,2005
[7]ArtTaylor,RandyLayman,BrianBuege.J2EEJava黑客大曝光:
开发安全的Java应用程序北京:
清华大学出版社,2003