版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
.PAGE.>简易聊天工具总体设计报告班级:网络工程10-1班:**:08103609指导教师:目录一、引言111.2课题现状11.3开发平台介绍1二、需求分析22.1编写目标22.2可行性分析22.3分析需求2功能需求分析2数据需求分析2性能需求分析3系统运行需求3:3效劳器端模块3客户端模块32.5数据流图4顶层数据流图4一层数据流图4二层数据流图5三、概要设计667效劳器端模块7.1用户上下线识别及显示模块7.2信息识别转发模块7客户端模块7.1用户注册模块7.2用户登陆模块7.3用户密码修改模块73.3两大模块工作流程89数据逻辑设计9数据字典9四、详细设计与编码实现1010效劳器界面设计10效劳器程序类11效劳器端连接用户的线程设计12效劳器端线程的管理1313界面包的设计〔view包〕14.1用户登录界面14.2用户好友列表界面15.3用户聊天界面18模块包的设计〔model包〕19.1客户端连接效劳器类19.2客户检查使用者类20用户端工具包的设计〔tools包〕21.1客户端连接效劳器线程类21.2管理客户端连接效劳器线程类22.3管理用户的聊天界面的类23.4管理好友列表、黑名单界面类2323User类23包的种类定义类24传输包定义类24五、运行测试26262628六、完毕语29参考文献30..>一、引言随着计算机科学技术的飞速开展,网络越来越深刻的改变着人们生活方方面面。各种基于网络的应用技术在人们的政治、经济、生活等的各个方面都发挥着重要的作用。例如QQ,MSN等基于Internet的即时聊天工具。这些工具通过网络这个新兴的媒介进展信息交流相比其他传统媒介具有数据量大,实时性强,操作简单,本钱低廉等优点。不仅如此即时聊工具还具备许多传统媒介不具备的强大功能,它们能传送文字、声音、影像和文档,而且能更加人性化的显示联络人的名单和通信状态。因而它们在现实生活中受到了广泛的欢迎,这是有目共睹的。目前基于Internet的即时聊天工具已经做的非常完美,然而基于局域网的即时聊天工具却不如人意。而在高等教育方面,网络展现出不可替代的作用。为了适应现代信息化,教学局域网就应运而生。而教学局域网内的即时通信能力则显得尤为重要。所以对于学校和公司内部网络等机构,局域网即时聊天的应用还是相当重要的。一个好的局域网通信软件将对学校和公司的运作产生积极的影响。1.2课题现状基于局域网的即时通信软件的核心技术其实与基于Internet的即时通信软件的设计技术是一样的,只是规模较小。基于Internet的通信工具一般是采用UDP或TCP协议来实现的,开发技术已经非常成熟。比方QQ、MSN等等,它们都是基于Internet的即时通信软件,它们不仅实现了即时聊天、文件传输等功能,而且还能够实现网络即时视频、语音聊天功能。它们的功能正在不断扩大,使其更加人性化,满足人们更多的需求。这类软件其实都是在下层协议的根底之上,通过网络通信接口进展设计的软件产品。在局域网内,这类软件的设计比在Internet中设计更为简单。因为Internet是网络的网络,构造更为复杂,碰到的状况比在局域网中要多。而局域网中事情就简单的多了,所以局域网聊天工具在实现即时通信时就相对容易些了。1.3开发平台介绍这次课题设计主要用Java语言,所以就选择相应的开发平台和工作、测试环境为MyEclipse。MyEclipse是一个十分优秀的用于开发Java,J2EE的Eclipse插件集合,MyEclipse的功能非常强大,支持也十分广泛,尤其是对各种开源产品的支持十分不错。MyEclipse目前支持JavaServlet,AJA*,JSP,JSF,Struts,Spring,Hibernate,EJB3,JDBC数据库链接工具等多项功能。可以说MyEclipse几乎囊括了目前所有主流开源产品的专属eclipse开发工具。二、需求分析聊天工具大多数由客户端程序和效劳器程序外加效劳器端,本程序采用客服机/效劳器架构模式,也就是通常所简称的C/S模式。通过Java提供的Socket类来连接客户机和效劳器并使客户机与效劳器之间相互通信。由于聊天是多点对多点的而Java提供的多线程功能,用多线程可完成多点对多点的聊天。主要有两个应用程序,分别为效劳器程序和客户端程序。效劳器应用程序主要用于消息转发,以及向所有用户发送系统消息等;客户端应用程序主要用于客户聊天记录的显示和信息输入。采用Client/Server〔C/S〕体系构造,即客户机/效劳器体系构造。聊天效劳器专门用于监控用户状态和转发消息,客户端负责接收消息的用户序列和消息文本发送到效劳器。该聊天系统实现私聊,一对多聊,用户登陆,退出聊天系统等功能。2.2可行性分析经济可行性:由于本系统的主要背景是课程设计,不注重直接的经济效益和其后的开展方向,只在注重自身水平和能力的提高,对自身的经济要求也不高,只要有一台能运行Java软件的电脑便可,所以不用考虑到经济问题。技术可行性:使用Java作为系统开发的开发环境,它提供完善的指令控制语句、类与对象的支持及丰富的数据类型,给开发高性能系统提供的保障为开发满足客户要求的系统,保证了代码的模块化要求,而代码模块化的提高,非常有利于以后对新系统的扩展与修改。运行可行性:本系统为一个小型的局域网聊天系统,所消耗的资源非常的小,现在一般的电脑无论是硬件还是软件都能够满足条件,因此,本系统在运行上是可行的。综上所述,本系统的设计与开发在技术上和硬件设备上的条件都是满足的,因此,它在技术上是可行的功能需求分析程序要实现的功能:程序启动之后要能够知道局域网内哪些用户在线,并可以与之通信;一旦*个网内用户上线或离线,需要立即更新信息,并通知所有在线用户;当双击用户列表中*个列表项时,要能够弹出信息发送框,并可以编辑要发送的信息,然后发送。数据需求分析对于局域网内的用户需要具体的数据信息来表示,效劳器则需要一个保存所有用户信息数据表,其根本内容应包括用户ID,用户名,密码,状态,及IP地址。性能需求分析实用性:为局域网聊天提供方便,有效进展作业管理。操作简单:本系统应该适用于不同水平的使用者,包括事业单位和企业单位,同时系统不应太复杂和烦琐,因此要求系统的操作尽可能简单易行。技术先进:产品的系统设计和开发应紧跟着整个计算机开展潮流,采用当时最先进的设计思想,利用最新的开发技术和开发工具。使系统能够无论在功能设计上,还是在技术实现上,都处于同行业的领先地位。安装使用简便:效劳器端的安装简洁明了,客户机无需再装任何软件就可以直接注册登陆聊天。适应性:应该能广泛应用于不同类型的企事业单位。系统采用模块化设计,用户可以根据自己的实际情况自行组合,使系统在不同的硬件环境下都能得以应用。代码可读性好:文中的代码将尽可能简洁,易懂。系统运行需求运行环境:Windows9*、2000、*p、2003,Linu* 必要环境:JDK1.5以上 硬件环境:CPU400MHz以上,内存64MB以上2.4本系统的主要功能局部组成:效劳器端模块:效劳器启动,进展监听功能:转发用户传播的信息效劳器自动更新用户状态信息客户端模块:登陆效劳器列出当前在线用户信息;聊天好友的的选择;发言:对输入的数据进展发送;离开状态;2.5数据流图顶层数据流图聊天用户聊天用户聊天用户简易聊天系统顶层数据流图一层数据流图聊天用户聊天用户聊天用户客户端效劳器端写聊天信息返回返回读取反响/转发存储提交用户信息数据库一层数据流图二层数据流图用户用户用户登录用户发送信息客户端效劳器端用户注册处理用户退出聊天内容用户得到信息数据聊天信息监控效劳器日志处理保存保存系统二层数据流图三、概要设计信息识别转发模块用户上下线识别显示模块用户端效劳器端简易聊天工具用户登陆模块用户注册模块用户密码修改模块用户聊天模块群聊模块单聊模块信息识别转发模块用户上下线识别显示模块用户端效劳器端简易聊天工具用户登陆模块用户注册模块用户密码修改模块用户聊天模块群聊模块单聊模块效劳器端模块.1用户上下线识别及显示模块功能:效劳器开启使用设定的端口进展监听,识别并显示用户上下线信息。目标:当有用户请求登陆时,效劳器通过套接字获取用户端的IP地址以及用户名和对应密码,识别是否一致,从而显示用户在线信息,当用户下线时,断开连接,显示用户下线信息。根本实现用户状态与信息显示一致。.2信息识别转发模块功能:效劳器将用户发送的信息接收、分析、存储并转发到目标用户。目标:效劳器定义一个用z于存储要求请求连接用户的端口号以及该端口客户发送的信息的数组,该数组效劳器、客户端共享,效劳器将发送端的根本信息存储,目的段可以读取该信息,从而实现信息转发。客户端模块.1用户注册模块功能:实现用户账号的注册目标:通过用户端的一个线程与效劳器数据库连接,用户输入创立的用户名、密码,假设通过合法性检测,则将该用户注册的信息写入后台数据库.2用户登陆模块功能:实现用户登陆。目标:用户输入用户名、密码并点击登陆,效劳器端接收用户端登陆请求,存储请求信息,并进展检验,如果通过合法性检测则进入聊天主界面。〔1〕群聊模块功能:能够进展类似于聊的聊天功能。目标:客户端点击"发送信息〞按钮,该客户端的ip地址、端口号以及信息内容一起打包写入效劳器的存储数组,客户端通过线程可以读取该数组中的内容,从而实现群聊。(2) 单聊模块功能:能够进展点对点的聊天方式。目标:客户端用户点击"开场私聊〞按钮,输入对方的昵称以及ip地址,从而该用户开启端口用于监听,同时定义输入、输出流文件,客户端延迟片刻,然后与该端口取得连接。当任意一方点击"发送信息〞按钮时,和群聊同一机理,通过读取共享文件内容实现私聊。.3用户密码修改模块功能:用户能够修改自己账号的密码。目标:用户输入用户名、旧密码、新密码,效劳器端接收用户端密码修改请求,存储修改信息,并进展检验,假设通过合法性检测,则把修改后的信息重新写入后台数据库。启动效劳器启动效劳器输入效劳器IP显示用户停顿监听等待开场监听输入端口号用户连接请求是否设置系统公告退出系统保存修改记录聊天记录显示在线人数YesNo启动客户端窗口启动客户端窗口输入qq号码输入密码登录验证成功进入客户端聊天室发布公开消息悄悄话发布隐蔽消息选择聊天对象选择断开连接退出系统NoYes客户端工作流程图效劳器端工作流程图数据逻辑设计组成〔用户qq,状态,好友,分组〕用户qq〔qq号码,昵称,密码,性别,年龄,好友名字,分组名称〕
状态〔qq号码,是否在线,ip地址,端口〕
好友〔好友qq号码,好友名字,所在分组名字〕
分组〔分组ID,分组名称,所属qq号码〕数据字典名称取值类型长度描述位置QQ号码Int5-8唯一标示用户,不可为空用户qq表,状态表昵称Char8用户昵称用户qq表密码Char6-16用户身份鉴定,不可为空用户qq表性别Char2用户性别,可空用户qq表年龄Smallint0-99用户年龄,可空用户qq表好友名字Char8好友昵称用户qq表,好友表分组名称Char8分组名字用户qq表,分组表是否在线Int1记录当前用户状态,不可为空状态表Ip地址Int32当前登录IP地址状态表端口Int4登录端口号状态表好友qq号码Int5-8唯一标示好友,不可为空好友表所在分组名字Char8所在分组名字,不可为空好友表所属qq号码Int5-8所属用户,不可为空分组表四、详细设计与编码实现设计中我在效劳器端建立了四个包,分别是com.qq.server.view包,.qq.server.tools包,.qq.server.model包以及公用.qqmon包;根据包的名称就很容易理解各个包中所包含的类的功能。View包主要是存放效劳器界面设计类的,model包中包含的是效劳器各个模块设计类,tools包中包含的是效劳器工作时所要用的工具设计类,最后commo包中包含的是效劳器端和客户端所需共同使用的内容设计类。其实还有一个包com.qq.server.db包,是用来放置管理用户中号和密码的数据库设计类,但是最终没有设计,只是偷懒的将用户是账号和密码在客户和效劳器连接的程序代码中进展固化了。效劳器界面设计效劳器界面设计类的类名为MyServerFrame,是存放在view包中,主要是实现效劳器端的控制界面,其可以实现启动效劳器、关闭效劳器、管理和监控效劳器等功能。通过java界面设计语句设计出效劳器界面的布局:整体只是由一个JPanel放在中间,JPanel主要是有两个JButton按钮组合而成,分别为启动和关闭按钮,至于效劳器界面的监视管理功能在此没有进展设计,以后会在加以补充。此效劳器界面涉及的变量如下JPaneljpl;JButtonjbt1,jbt2;其中对jbt1做了一个监听,当点击这个按钮时就会执行MyQqServer类中的代码,从而完成效劳器开启功能。publicMyServerFrame(){ jpl=newJPanel(); jbt1=newJButton("启动效劳器"); jbt1.addActionListener(this);对jbt1的监听 jbt2=newJButton("关闭效劳器"); jpl.add(jbt1); jpl.add(jbt2); this.add(jpl,"Center"); this.setSize(500,400); this.setDefaultCloseOperation(JFrame.E*IT_ON_CLOSE); this.setVisible(true);} publicvoidactionPerformed(ActionEvente){ if(e.getSource()==jbt1)如果点击了jbt1 { newMyQqServer();跳转到MyQqServer继续执行程序 }}效劳器程序类效劳器程序类类名为MyQqServer,存放在model包中,它是真正的聊天工具效劳器程序,其目的是在9999端口监听等待、监听是客户端否有客户发起连接,承受客户端发来的连接请求并且检查客户输入信息的合法性,当用户名和密码对应且正确时,返回登陆成功的信息包,效劳器为用户单开一个线程,让线程与该客户端保持通讯,启动客户端与效劳器间的线程,并通知其其他在线的好友; try{//在端口号为9999处监听 System.out.printf("我是效劳器,在9999端口监听"); ServerSocketss=newServerSocket(9999);//阻塞,等待连接 while(true) { Sockets=ss.accept();定义套接字承受//承受客服端发来的信息是以对象流的方式 ObjectInputStreamois=newObjectInputStream(s.getInputStream());Useru=(User)ois.readObject();Messagem=newMessage(); ObjectOutputStreamoos=newObjectOutputStream(s.getOutputStream()); if(u.getPassword().equals("123456")) {//返回一个登陆成功包 m.setMesType("1"); oos.writeObject(m);//里就单开一个线程,让该线程与该客户端保持通讯SerConClientThreadscct=newSerConClientThread(s); MangeClientThread.addClientThread(u.getUserid(),scct);//启动与该客户端通信的线程 scct.start();//并通知其他在线用户 scct.notifyother(u.getUserid()); }else{ m.setMesType("2"); oos.writeObject(m);//关闭链接 s.close(); }在设计这个程序是要注意,效劳器承受用户的信息别且进展检验但是不能以以字节读的方式承受读取,因为以字节读取时遇到空格符或转行符会出现错误,如账号1234密码123122中间有空格,则效劳器就不能正确识别,为改进这种读取方式,我们将效劳器端和客端的io流用User对象的方式传播,传输和读取的都是对象的相应函数,则就不会出出现上述情况,除此之外,客户端的发送和效劳器端的监听都需要将内容序列化〔只是加上一个java命令,让java内部实现〕。importsun.nio.ch.ServerSocketAdaptor;序列化:就是可以让一个对象可以在网络上或文件上传输,事实上就是把它序列了,是他不乱效劳器端连接用户的线程设计效劳器和客户的通信线程SerConClientThread存放在model包中,它的设计主要就是为了实现在线用户一对多的聊天,这样就不会发生套接字争抢的现象,因为每一个在线用户都开启了相应的一个线程用来存放其特定的套接字信息。其组要功能:得到所有在线人的线程取出在线人的Id//得到所有在线的人的线程 HashMaphm=MangeClientThread.hm;Iteratorit=hm.keySet().iterator();定义一个HashMap用来存放所有用户线程 while(it.hasNe*t()) { Messagem=newMessage(); m.setCon(iam); m.setMesType(MessageType.message_ret_onlinefriend);}判断用户发送的信息类型,如果是一般信息,则获取承受设的通信线程别且一会将其转发出去//对从客户端取得的消息进展类型判断然后做出相应处理 if(m.getMesType().equals()) {//取得承受人的通信线程一会转发 SerConClientThreadsc=MangeClientThread.getCLientThread(m.getGetter());ObjectOutputStreamoos=newObjectOutputStream(sc.s.getOutputStream());oos.writeObject(m);}如果是请求所有在线好友的信息,则给该用户返回效劳器端的在线好友elseif(m.getMesType().equals()) {//把在效劳器断的好友给该客户端返回 Stringres=MangeClientThread.getAllOnlineUserid(); Messagem2=newMessage(); m2.setMesType(MessageType.message_ret_onlinefriend); m2.setCon(res); m2.setGetter(m.getSender());ObjectOutputStreamoos=newObjectOutputStream(s.getOutputStream()); oos.writeObject(m2); }效劳器端线程的管理效劳器端线程的管理类ManageClientThread从命名上看就知道其主要作用就是管理用户的线程,将这些线程同一的放在一个建立好的哈希表中publicclassMangeClientThread{ publicstaticHashMaphm=newHashMap<String,SerConClientThread>(); //向hm中添加一个客户端通信线程 publicstaticvoidaddClientThread(Stringuid,SerConClientThreadct) {hm.put(uid,ct);这里加的就是用户的id以及其对应线程}这个类还有两个函数一个是getCLientThread函数,主要就是返回在效劳器端有线程的用户的id,在效劳器转发用户普通信息前就会先调用该函数获得承受者的id,对应于的情况1。publicstaticSerConClientThreadgetCLientThread(Stringuid){return(SerConClientThread)hm.get(uid);返回效劳器端由线程的用户的id}还有一个函数getAllOnlineUserid,其作用就是为了返回所有在线用的情况,效劳器接到用户更新在线好友的命令后会调用,对应于的情况2。//返回当前在线的人的情况publicstaticStringgetAllOnlineUserid(){//使用迭代器完成Iteratorit=hm.keySet().iterator();Stringres="";while(it.hasNe*t()){res+=it.ne*t().toString()+"";}returnres;}我在客户端同样建立了四个包,分别是com.qq.client.view包,.qq.client.tools包,.qq.client.model包以及公用.qqmon包;与效劳器端一样,各个类根据功能目的会被放在不同的包中。View包主要是存放客户端多个界面设计类的,在其中我总共设计了三个界面类:用户登录界面类QQClientLogin、用户好友列表界面类Qqfrienlist、用户聊天界面类Qqchat。model包中包含的是用户端各个模块设计类,用户与效劳器连接的实现类和用户客户端使用信息类都在其中。tools包中包含的是用户端工作时所要用的工具设计类,用户连接效劳器的线程类和各个管理类都在其中。最后commo包中的类与效劳器的commo包中的内容是一样的,因为里面都是效劳器端和客户端所需共同使用的内容,所以要保持其一致性。在设计编码实现时,刚开场设计的界面编码类是独立的,但是到后面就会将各个界面类嵌套连接起来,除此之外还会应时定义生成其他的类,所以说各个类之间都是相互联系的,绝非有独立的类存在。界面包的设计〔view包〕.1用户登录界面客户端用户登录界面设计类的类名为QQClientLogin,是存放在view包中,主要是实现用户登录界面,其可以实现输入用户账号、密码进展登录功能。通过java界面设计语句设计出效劳器界面的布局:整体只是由三个局部组合而成,分别是将一个JLabel放在北部。一个JPanel放在中间,中间的JPanel是由两个JLabel、两个JButton、一个JTe*tField、一个JPasswordField、两个JCheckBo*按钮组成,并且将这个JPanel设计成3*3的网格布局。最后是南边也是一个JPanel,由两个JButton组成的一个流布局构造。这个界面中主要设计的按钮是"登录〞按钮,因为要将其监听。此用户登录界面涉及的变量如下北部需要的变量JLabeljbl1;中部需要的变量JPaneljp1;JLabeljp1_jbl1,jp1_jbl2;JButtonjp1_jb1,jp1_jb2;JTe*tFieldjp1_jtf;JPasswordFieldjp1_jpf;JCheckBo*jp1_jb*1,jp1_jb*2;南部需要的组件JPaneljp2;JButtonjp2_jb1,jp2_jb2;当用户点对于登录按钮的监听jp2_jb1=newJButton("登陆");//响应用户点击jp2_jb1.addActionListener(this);监听当监听点击了用户登录按钮时,会自动跳转执行监听函数publicvoidactionPerformed(ActionEvente){//如果用户点击登录 if(e.getSource()==jp2_jb1){ QqClientUserqqclientuser=newQqClientUser();到QqClientUser类中执行 Useru=newUser();新建一个User对象 u.setUserid(jp1_jtf.getTe*t().trim());获得User对象的用户账号,是输入框中jp1_jtf中输入的账号 u.setPassword(newString(jp1_jpf.getPassword()));获得User对象的用户密码,就是输入框中jp1_jpf中输入的内容if(qqclientuser.checkUser(u)){ //发送一个要求返回在线好友的请求包try{ //把创立好友列表的语句提前否则不能成功 Qqfrienlistqqlist=newQqfrienlist(u.getUserid()); ManageQqFriendList.addQqfrienlist(u.getUserid(),qqlist); ObjectOutputStreamoos=newObjectOutputStream(ManagerClientServerThread.getClientConServerThread(u.getUserid()).getS().getOutputStream());在这个类中,还提前参加了一个获取好友在线情况的函数,由于在用户登录时,用户要知道哦自己的好友在线的情况,所以就会向效劳器发送一个申请好友在线情况的申请,同时会在效劳器返回一个在线好友的数据流后在切换到好友列表界面。//做一个message Messagem=newMessage(); m.setMesType(MessageType.message_get_onlinefriend);//指明我要的是这个qq号的好友情况m.setSender(u.getUserid());就是这个发送请求的好友 oos.writeObject(m); }catch(E*ceptione2){ //TODO:handlee*ception e2.printStackTrace(); }.2用户好友列表界面客户端用户好友界面设计类的类名为Qqfrienlist,是存放在view包中,主要是实现用户好友界面的显示,其可以该用户的所有好友以及好友的状态,在线的头像就会使彩色,不在线的图像就会是保持灰色。通过java界面设计语句设计出好友列表界面的布局是一个BordeLayo布局,在这个BordeLayo布局中在进展好友列表和陌生人列表的设计。这两个列表设计是一样的,就以好友列表界面举例来说;整个界面是一个BordeLayo布局,在这个整体布局中,又分为三局部:最上方是一个只含有一个"好友列表〞JButton的JPanel,最下方是含有两个JButton的JPanel,最主要的是中间的布局,它是一个JScrollPanel布局,是可以上下滚动的。此用户好友列表界面涉及的变量如下JPaneljphy1,jphy2,jphy3;JButtonjphy_jb1,jphy_jb2,jphy_jb3;JScrollPanejsp1;JLabel[]list;JScrollPanel布局的主要实现jphy2=newJPanel(newGridLayout(20,1,4,4));//给jphy2初始化20个好友 list=newJLabel[20]; for(inti=0;i<list.length;i++) {list[i]=newJLabel(i+1+"",newImageIcon("image/mm.jpg"),JLabel.LEFT); list[i].setEnabled(false); if(list[i].getTe*t().equals(ownerid)) { list[i].setEnabled(true); } list[i].addMouseListener(this); jphy2.add(list[i]); }jsp1=newJScrollPane(jphy2);定义变量jsp1为JScrollPane型变量陌生人界面的设计方法和原理和用户列表是一样的,只是有一点点变化,但是要想显示用户的陌生人列表则需要点击用户的"陌生人〞按钮进展一个监听,主要代码实现:jphy_jb2=newJButton("陌生人");jphy_jb2.addActionListener(this);这个监听是在好友列表界面中实现的,因为只有在好友列表中点击"陌生人〞按钮,界面才会切换到陌生人列表界面,同样理由,如果要继续增加列表界面的数量,则在每一个列表中的JButton"陌生人〞这个变量下都要进展一个监听。所以最终设列表界面数位n则*一个界面的按钮监听数就为n-1,即除了自己界面,其他的界面都要有连接到此界面的监听。监听的执行函数如下:用if函数,点击什么按钮就切换到相应界面publicvoidactionPerformed(ActionEvente){//点击陌生人按钮,就会显示陌生人卡片 if(e.getSource()==jphy_jb2)点击陌生人按钮 { c1.show(this.getContentPane(),"2");显示陌生人卡片 }//点击好友列表按钮,就会显示好友列表卡片 elseif(e.getSource()==jpmo_jb1)点击好友列表按钮 { c1.show(this.getContentPane(),"1");显示好友列表卡片 } }从上面函数中我们可以看见跳转各个卡片时,使用的是数字"1〞"2〞进展的,按照总界面设计时的分界面上下顺序以及编码定义实现这些界面的顺序,将这些界面的变量进展定义:this.add(jphy1,"1");好友列表定义"1〞 this.add(jpmo1,"2");陌生人列表定义"2〞这样使用时想切换哪个界面就没有必要过多的使用所定义的变量,从而会在一定的程度上防止了调用时的错误的发生。除了在设计界面是所要使用到行动监听ActionListener,还要使用一种监听就是鼠标监听MouseListener,使用过群众聊天工具QQ的用户都知道,当用户登录成功后显示好友列表界面时移动或点击鼠标就会出现相应的现象,所以这里就需要进展鼠标监听,主要监听实现的功能有:在好友列表中,当鼠标移动到*一个好友上时,此好友头像变红,鼠标移走,头像恢复原样publicvoidmouseEntered(MouseEvente){//鼠标放在好友头像上,头像灰变红JLabelj1=(JLabel)e.getSource();j1.setForeground();}publicvoidmouseE*ited(MouseEvente){//鼠标移走,头像恢复原样JLabelj1=(JLabel)e.getSource();j1.setForeground();}2.当鼠标移动到*个好友头像上,并且双击其头像,就会出现与该好友聊天的聊天界面,聊天界面的设计下面会详细阐述,监听双击的响应函数如下:publicvoidmouseClicked(MouseEvente){//响应用户双击的事件,并获得好友if(e.getClickCount()==2)鼠标双击{JLabelj2=(JLabel)e.getSource();j2是一个新的JLabel用来得到新的聊天界面资源StringfrienNo=j2.getTe*t();Qqchatqqchat=newQqchat(this.owner,frienNo);新建一个qqchat函数调用执行Qqchat//把聊天界面参加到管理类 ManageQqChat.addQqchat(this.owner+""+frienNo,qqchat);} }在这个响应中有调用QqChat类,也有调用ManageQqChat类,这些类的功能在后面会一一介绍.3用户聊天界面用户聊天界面类的类名为QqChat,顾名思义,这个类就是用来定义关于用户聊天的一切功能实现函数的类,在这个类中,主要实现的是用户聊天界面的设计,还有就是聊天工具中比较重要的聊天信息的发送,在上面介绍效劳器端的详细设计时,就提到在效劳器和客户的通信线程类SerConClientThread中实现一个功能就是效劳器承受到用户的发送过来的包并且进展判断,根据不同的包执行不同的代码,实现不同的功能,那是效劳器独有也是必须具备是转发功能,但是前提是效劳器必须有包承受,那样才能判断。这里QqChat中第二个功能就是向效劳器发送信息包,以便效劳器接收判断并且转发。1.首先实现用户聊天界面的设计,这个设计很简单,这是有根本的文本输入和显示框架,还有一个发送按钮。所使用的变量定义如下:JTe*tAreajta;这是文本显示域用来显示对方发来的聊天信息JTe*tFieldjtf;这是聊天文本的输入框JButtonjbt;发送按钮JPaneljpl;底部的布局为一个JPanel布局那些根本的定义的编码在这你就不在这里过多的阐述,布局的设计如下:this.add(jta,"Center");文本显示域放置在中间 this.add(jpl,"South");JPanel在最底部,包括输入框和发送按钮 this.setTitle(ownerid+"正在和"+frien+"聊天");为聊天界面命名 this.setIconImage(newImageIcon("image/qq.gif").getImage());为聊天界面设置一个小小的头像图片 this.setSize(400,300);设置聊天界面大小2.用户与*好友聊天时,在输入框中输入聊天内容,并且点击发送按钮将其发送给效劳器,让其转发;还有就是承受效劳器转发过来的聊天好友信息数据流后在聊天界面显示域显示。先写一个函数,让其实现显示聊天信息显示功能publicvoidshowMessage(Messagem) { Stringinfo=m.getSender()+"对"+m.getGetter()+"说"+m.getCon()+"\r\n";this.jta.append(info);显示所承受的信息 }聊天信息显示函数写好后在实现聊天信息的发送,首先要与往常一样,在刚开场的发送按钮处进展一个监听,当用户点击发送按钮时发送输入的信息jbt=newJButton("发送");定义发送按钮 jbt.addActionListener(this);对发送按钮进展监听响应发送按钮的监听,当用户点击了发送按钮时,就将用户在输入框中输入的内容进展打包发送。首先新建一个Message,并且声明这个Message发送的是什么包,而后在定义这个Message发送包的具体内容if(e.getSource()==jbt)如果用户点击了发送按钮 { Messagem=newMessage();新建一个Messagem.setMesType(MessageType.message_comm_mes);定义声明这个Message发送的包的类型为message_comm_mes包m.setSender(this.ownerid);定义这个发送包的发送者的id为本人的idm.setGetter(this.frienid);定义这个包的承受者id为此时聊天好友的idm.setCon(jtf.getTe*t());定义发送包的内容为聊天输入框的信息文本m.setSendTime(newjava.util.Date().toString());发送时间就是本机时间这里只是在监听到用户点击了发送按钮时第一时间所做的事情,就是定义好将要发送的包,承受者、发送者、时间、内容等必要的组件都已将定义并且已经封装在这个发送包Message中了,现在剩下的就是将这个包发送到效劳器端了。//发送给效劳器 try{ObjectOutputStreamoos=newObjectOutputStream (ManagerClientServerThread.getClientConServerThread(ownerid).getS().getOutputStream()); oos.writeObject(m);}这里的重点局部就是双斜杠加粗的局部,这个局部是一个合成语句,一步到位的,来将其拆分逐个解释,首先ObjectOutputStreamoos=newObjectOutputStream是定义一个新的对象输出流名为oos,其中oos要调用函数将Message包发送出去,所调用的函数是ManagerClientServerThread类中的函数getClientConServerThread,调用这个函数的目的就是为了得到客户连接效劳器端的线程名就是本机的用户的id,用来进展指定发送。至上为止就已经将界面包viwe中的三个界面类用户登录界面类QQClientLogin、用户好友列表界面类Qqfrienlist、用户聊天界面类Qqchat的设计进展了具体的解释。下面就具体介绍model包中的类的详细设计和具体用途。模块包的设计〔model包〕.1客户端连接效劳器类这个类放在model包中就可以看出来它的重要性,客户端连接效劳器类QqClientlianjie顾名思义就是用与c/s软件中连接局部的重中之重,c/s软件就是包括两个组成局部:客户端、效劳器,而他们的只有在连接的根底上才能进一步设计增加其他的功能,这个类就相当于中间枢纽。类QqClientlianjie它的主要功能就是为了实现客户端与效劳器连接;要实现这个总根本上是分这几步来实现的:首先先通过软件使用的端口向效劳器发送io流,先实现与效劳器断的连接publicbooleanSendLoginInfoToServer(Objecto){ booleanb=false; try{ s=newSocket("",9999);这就是效劳器断的ip地址〔这里效劳器就是本机〕和软件在本机所使用的端口号 ObjectOutputStreamoos=newObjectOutputStream(s.getOutputStream());oos.writeObject(o);这里就是向效劳器输出一个对象流 ObjectInputStreamois=newObjectInputStream(s.getInputStream());Messagems=(Message)ois.readObject();这里是将效劳器返回的对象刘进展判断并且根据不同的结果做出相应的反映这里首先说明一下客户向效劳器发送的包并非随意发送的,这个发送的信息包是将已经在用户翻开登录界面,将用户名和密码输入并且点击了登录按钮后就开场定义封装,其中包括的就是客户id和密码,这个包在上面介绍用户登录界面设计中已经详细说明了。对效劳器端返回的数据包进展判断并作出相应的回应,如果效劳器返回的信息包的为"1〞,则就是说明用户输入的信息合法,用户登录成功,相应的就要看一个线程让用户和效劳器保持连接。 if(ms.getMesType().equals("1"))如果返回的是"1〞〔登录成功〕 {//就创立一个该qq号效劳器端保持通讯连接的线程 ClientConServerThreadccst=newClientConServerThread(s);//启动该通讯线程 ccst.start(); ManagerClientServerThread.addClientConServerThread(((User)o).getUserid(),ccst);这里调用到管理线程类的函数addClientConServerThread b=true;将b的值改为true }这个public函数一开场就是设定的类型为boolean,所以只有两种结果,就是登陆成功或者失败,成功就执行上面一个函数,开一个线程,不成功就返回提示用户账号或者密码输入错误。.2客户检查使用者类这个类其实是为了减少QqClientlianjie中代码的冗余,还有就是方便其他的类中*个步骤要为了与效劳器连接而调用连接函数时,从类名上就可以缺的调用的函数,进一步减少了设计者编码时的错误率。这个类中只有一个函数checkUser(Useru),而他的变量就是一个User对象,这个函数的作用就是调用QqClientlianjie中的函数SendLoginInfoToServerpublicbooleancheckUser(Useru){ returnnewQqClientlianjie().SendLoginInfoToServer(u);//返回一个新的SendLoginInfoToServer函数也就是间接使用这个函数}需要强调的是这样做到目的不是多余的,而恰恰是为到达减少多余的编码的目的,如果在SendLoginInfoToServer中直接定义一个User函数的话,会让看代码的人难以理解,而这样外部定义调用就会使思路更加清晰。用户端工具包的设计〔tools包〕这个包里主要包含的是一些管理功能的类,它们根本上可以看成是用户端实现其功能时所使用的工具。.1客户端连接效劳器线程类这个类解释起来名字看起来很长,其实很容易理解,就是每一个用户连接效劳器时的线程设计类,所以这个类的主要功能都是与用户的线程有关的。这个类的主要线程就是每时每刻检测是否从效劳器有数据包发过来,没有就什么也不做,如果有的话就要作出相应的动作,也就是选判断从效劳器发过来的数据包是什么类型的,然后再做出相应的反响。下面来进展分布的介绍:先不停的读取从效劳器端发来的信息while(true){不停的检测try{ObjectInputStreamois=newObjectInputStream(s.getInputStream());新建输入流Messagem=(Message)ois.readObject();新建一个Message包用来读取发来的信息System.out.println("读取从效劳器发来的消息"+m.getSender()+"给"+m.getGetter()+"说"+m.getCon());这是一个输出语句如果是普通的信息包就显示if(m.getMesType().equals(MessageType.message_comm_mes))普通信息包{//把效劳器获得消息,显示到该显示的聊天界面Qqchatqqchat=ManageQqChat.getQqchat(m.getGetter()+""+m.getSender());//显示就直接调用Qqchat中的showMessage函数qqchat.showMessage(m);}如果是返回在线好友包就更新用户的好友列表elseif(m.getMesType().equals(MessageType.message_ret_onlinefriend))在线好友包{ Stringcon=m.getCon();提取信息 Stringfriends[]=con.split("");用数组存放在线好友名单 Stringgetter=m.getGetter();提取承受者//修改相应的好友列表Qqfrienlistqqfrienlist=ManageQqFriendList.getQqfrienlist(getter);//更新在线好友 if(qqfrienlist!=null)如果好友列表部位空{看在线者中是否有其好友,逐个对应更新 qqfrienlist.updateFriend(m); }}在这个类的最后还有一个构造函数,其作用就是初始化新对象的数据成员,因为上面设置的套接字变量s是私有的,受保护,所以写了一个构造函数。 publicClientConServerThread(Sockets) {this.s=s;初始化新对象的数据成员 }.2管理客户端连接效劳器线程类这个类名为ManagerClientServerThread,显而易见是与上面的客户端连接效劳器线程类rClientServerThread是有关联的,它的主要功能如名字一样,就是为了管理用户连接效劳器后所生成的线程的。类里很简单的只定义了一个哈希表,用来存放用户线程,还有就是定义两了个函数:ManagerClientServerThread和getClientConServerThread。下面分别介绍这两个函数的功能:1.ManagerClientServerThread函数的定义其实就是为了把创立好的用户线程放入到哈希表中 publicstaticvoidaddClientConServerThread(Stringqqid,ClientConServerThreadccst){hm.put(qqid,ccst);把创立好的用户线程放入到哈希表中}2.getClientConServerThread函数就是为了可以通过qqid取得该用户的线程,简单方便。 publicstaticClientConServerThreadgetClientConServerThread(Stringqqid) { return(ClientConServerThread)hm.get(qqid);返回的就是对应用户的线程}这就是管理用户线程类的两大功能,简单实用同时又必不可少.3管理用户的聊天界面的类ManageQqChat类要实现的功能也很简单,首先也是建立了一个哈希表用来存放聊天界面,哈希表是静态的不随函数的变化而变化,类的主要功能就是将用户聊天界面在这个哈希表中参加或者取出,从而到达管理的目的。publicclassManageQqChat{//新建的哈希表用来存放用户聊天界面 privatestaticHashMaphm=newHashMap<String,Qqchat>();//当用户在好友列表中双击了*好友想与其聊天时,将用户聊天界面参加 publicstaticvoidaddQqchat(StringloginIdAndFriendId,Qqchatqqchat) {hm.put(loginIdAndFriendId,qqchat);参加 }//当用户关闭与*个好友的聊天界面是,将这个聊天界面从哈希表中取出 publicstaticQqchatgetQqchat(StringloginIdAndFriendId) {return(Qqchat)hm.get(loginIdAndFriendId);取出 }ManageQqChat类的功能就是简单的管理聊天界面的,也是简单实用又必不可少。.4管理好友列表、黑名单界面类与上面的两个管理类一样,这个类也是为了实现管理的功能,但是它是为了管理好友列表、黑名单的;如果后期还想在好友界面中参加一些卡片的话,如家人卡片、同学卡片,则它们的管理也是要放在这个类里来实现。与管理聊天界面类一样,这个类首先也是建立了一个哈希表用来存放好友列表界面,哈希表是静态的不随函数的变化而变化,类的主要功能就是将用户好友列表在这个哈希表中参加,还有就是得到*用户好友列表这两个根本功能。publicclassManageQqFriendList{//新建的哈希表用来存放用户好友列表privatestaticHashMaphm=newHashMap<String,Qqfrienlist>();//当用户在好友在线时,将这个好友参加好友列表中 publicstaticvoidaddQqfrienlist(Stringqqid,Qqfrienlistqqfrienlist) {hm.put(qqid,qqfrienlist);参加}//通过变量qqid来取得相应用户的好友列表情况 publicstaticQqfrienlistgetQqfrienlist(Stringqqid) {return(Qqfrienlist)hm.get(qqid);获得取出 }ManageQqFriendList类的功能就是简单的管理用户的好友列表的,用户获取它时就可以直接的知道自己好友的在线情况。在效劳器端与用户端中,可以轻易的发现有一个同名的包com.qqmon包,没有将其在效劳器端或用户端中独立介绍是因为这个包里的类它们的定义完全一样,它们是效劳器和客户都要共同使用的数据对象,所以单独介绍。User类这个类中其实就是定义了一个对象user,这个对象就是用户的公共代表,它里面包括使用者的账号id和密码publicclassUserimplementsjava.io.Serializable{ privateStringuserid;用户id privateStringpassword;用户密码//设置用户账号函数 publicStringgetUserid(){ returnuserid; }//设置用户密码函数 publicvoidsetUserid(Stringuserid){ this.userid=userid; }//取得用户账号函数 publicStringgetPassword(){ returnpassword; }//取得用户密码函数 publicvoidsetPassword(Stringpassword){ this.password=password; }}这就是将使用者的根本信息封装在一个对象中,这样效劳器和客户使用时直调用这个User包就行了包的种类定义类QQ在设计时客户与效劳器之间传输的不同的包大概有50多种,在这里我设计
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年电力电缆作业特种作业操作证考试题库
- 2025年园艺技术岗历年真题及答案
- 健康养老服务业政策研究报告
- 新密备案批复可行性分析研究报告
- 信息化环境下语文教学的有效性研究报告
- 汽车行业一体化压铸专题研究报告总结
- 2027届上海市长宁区西延安中学数学七上期末教学质量检测模拟试题含解析
- 保险经纪人执业资格考试保险产品与市场专项训练题库
- 江苏省泰州市靖江市实验学校2027届七年级数学第一学期期末达标检测模拟试题含解析
- 2026年辽宁省凌海市高三数学下册期末考试模拟考试卷完整答案
- 新版2026年部编版新教材道德与法治五年级上册全套单元、期中、期末检测题(共6份有答案)合集
- 2026年重庆市安全员A证考试模拟题及答案详解
- 2026-2027学年人教版八年级上册数学第一次月考重难点突破学情自测卷(含答案)
- 2026年公卫执业医师《医学微生物学》试题及答案
- 《美术手工创作方法》全套教学课件
- 人教版数学六年级上册第二单元测试卷(含解析)
- 雨课堂在线学堂《大学生国家安全教育》作业单元考核答案
- 铁路货车轮轴组装检修及管理规则
- 《概念验证服务规范》
- 酶工程与发酵工程创新创业项目商业计划书
- CJ/T 414-2012城市轨道交通钢铝复合导电轨技术要求
评论
0/150
提交评论