基于JAVA的局域网聊天系统开发

获取项目源文件,技术交流与指导联系Q:1225467431

摘要

随着计算机网络技术的发展,各种各样基于网络的应用也随之诞生,比如基于互联网的信息发布,通信,数据共享等等。局域网的发展也同样迅速。很多政府机构,企业,学校,都是先以一个统一的局域网联结在一起,再分别接入INTERNET.因此基于局域网的即时通信工具,就这样应运而生了。本文利用JAVA的UDP编程以及SWING图形界面编程技术,在WINDOWS平台上实现了具有美观图形界面的局域网聊天软件.

在本实现内将客户端和服务端综合在一个程序之内,用多线程实现不同的并行任务。并模仿国内的QQ进行了人性化的界面设计,使用起来更加简单方便,并且功能十分合理、实用。

通过本局域网聊天软件可以实现一对一、一对多的聊天,可以实现不同用户不同的文字字体、风格、大小、颜色的发送和显示,提供发送表情、文件、好友间的抖动提示以及聊天记录的管理等功能。

关键词:局域网聊天; JAVA网络编程; UDP;多线程

LAN Chat System Development based on JAVA

Abstract

With the development of computer network technology, various kinds of applications based on network were born, such as the release of information,  communication, data sharing based on the Internet and so on. The development of the LAN is also quick. Many government agencies, enterprises, schools, is the first in a unified network linked together, each with access to INTERNET. Thus Instant Communication Tools based on LAN were born. In this paper, by using JAVA UDP programming and SWING graphical interface programming technology, we can get a LAN chat software with beautiful appearance on the WINDOWS platform.

In the implementation, the client and the server were integrated within a program, implemented with multithreading. And imitating the domestic QQ interface humanization design, using more simple and convenient, and the function is very reasonable, practical.

扫描二维码关注公众号,回复: 10547885 查看本文章

Through our LAN chat software can achieve one to one, one to many chat, send different users’ different text font, style, size, color and display, provide the send of expression, file, the shake among friends and chat records management and other functions.

Keyword: LAN ChatJAVA network programmingUDP; multi-thread

目录

摘要 I

Abstract II

第一章 前言 1

第二章 系统可行性分析 2

2.1 成本可行性分析 2

2.2 技术可行性分析 2

第三章 需求分析 3

3.1 功能需求分析 3

3.2性能需求分析 3

3.3 系统主要技术分析 3

3.2.1 JAVA DatagramSocket 3

3.2.2 JAVA MulticastSocket 4

3.2.3 JAVA Swing 5

3.4 系统开发、运行环境分析 5

第四章 系统概要设计 6

4.1 系统功能模块设计 6

4.2 系统数据流图 9

第五章 系统详细设计 10

5.1 详细设计概述 10

5.2 系统详细设计 10

5.2.1登陆界面 10

5.2.2用户主界面 14

5.2.3聊天界面 16

5.2.4辅助工具类 19

第六章 系统实现 21

6.1 总体工程架构的实现 21

6.2 具体功能实现 21

结论 24

参考文献 25

第一章 前言

近年来,随着全球信息化进程的不断发展,网络也在飞速发展。出于高效、快速地处理各种事务的目的,越来越多的企业在其内部使用局域网来进行工作。在内部局域网的帮助下,企业得以简化信息流程,提高信息交换的速度,从而提高工作效率。然而,随着企业规模的扩大,业务量的增加,在局域网上运行的应用越来越多,如知识库、网络会议、数据库应用和数据的同步与备份等,这些应用对局域网的信息吞吐、处理能力的要求也越来越高。这些在企业内部原有局域网设计之初未曾考虑到的新情况的出现使得局域网不堪重负,容易发生信息阻塞,此时,局域网不但不能提高生产效率,反而成为企业发展的瓶颈。    

为了解决上述矛盾,人们提出了许多方法。提升网络带宽及增加服务器的吞吐能力是解决此矛盾的一种方法。然而,从企业运行的成本方面考虑,无论是单纯地提升网络带宽或增加服务器的吞吐能力都不能从根本上解决局域网资源紧张的问题,对旧有局域网的大规模硬件改造反而会增加企业的负担。

我在本文中将讨论一种基于DatagramSocket和MulticastSocket的局域网通信工具的设计与实现方法。基于DatagramSocket和MulticastSocket的局域网通信软件可以为企业原有的局域网提供一种良好,安全,快速的通信机制。它的实现无需对企业原有的局域网硬件进行任何改动,具有实现成本低廉的优点,它的使用能有效地降低局域网通信负荷,提高局域网的使用效率,可以很好地解决企业内部局域网的各种通信需求。  

基于DatagramSocket和MulticastSocket的局域网聊天工具是此类局域网通信软件的具体实例之一,它很好地诠释了DatagramSocket和MulticastSocket通信的原理,并且在企业内部通信、教学、讨论等应用中都具有一定的实用价值。它具有信息收发速度快,保密性好,占用网络带宽资源低,占用服务器吞吐能力低,易于编程实现等优点。 

基于DatagramSocket和MulticastSocket的局域网通信软件应用范围广阔,不但可以处理传统的通信需求,而且也能扩展以适应新型的网络应用,如网络教育,数据影音传输等,拥有广泛的应用前景。

第二章 系统可行性分析

可行性分析是基于客观的、科学的,其在整个系统的设计与实现过程中有非常重要的意义,软件可行性分析的目的是用合适的代价解决足够的问题,其最终结果是对所设想的项目做出实施还是放弃。本局域网聊天系统将从成本和技术可行性进行分析。

2.1 成本可行性分析

因为本软件只做开发学习使用,所以暂且不考虑经济成本及盈利问题。

2.2 技术可行性分析

首先我已经搭建好开发所需要的软硬件平台,并进行了合理而完善的需求分析,做好了充分的前期准备工作,其次因为本程序的平台将基于WINDOWS,将要使用网络通信技术,而WINDOWS有完善成熟的网络通信接口,以及与VC开发环境的严密契合能力,加之相类似的更大规模的INTERNET通信工具产品也已有例在先,所以这个程序的开发可行性在技术上是完全可行的。

第三章  需求分析

3.1 功能需求分析

(1)用户端之间的信息发送,本程序需要实现的最基本的功能;

(2)当有用户下线后,应在所有在线的用户的“在线用户列表”中消掉下线人的信息记录;

(3)在聊天是还应提供一些使用的辅助功能,在本局域网的聊天软件中,提供有字体设置、表情发送、文件发送、窗口抖动、消息记录管理等常用功能,能够满足用户的基本要求。

3.2性能需求分析

首先要求程序要完全可靠,可以应付种种由于系统问题产生的错误,比如初始网络失败,对方突然下线等。要求提前设想到类似的尽可能多的可能发生的事件,做出相应的应对措施,并向用户提交简单易懂清晰明白的提示信息。 

程序要有良好的容错性,当用户进行非法操作时或者系统本身出现问题时要能以最好的方式退出程序,避免发生程序假死现象。 

要求程序对所运行之系统的硬件条件要求尽可能低,运行时内存占用尽可能小,响应速度要尽可能快。并且不发生内存泄漏之类影响系统运行的错误事件。并且要求易于维护及扩展。所以应该采用模块化开发,各个模块之间不要有太多的联系,以免维护困难。

3.3 系统主要技术分析

3.2.1 JAVA DatagramSocket

1.基本概念:

a.DatagramPacketDatagramSocket位于java.net包中

b.DatagramPacket表示存放数据的数据报,DatagramSocket表示接受或发送数据报的套接字

c.由这两个类所有构成的网络链接是基于UDP协议,是一种不可靠的协议。

注:为了解决UDP协议的不可靠问题,在软件的聊天的文件传输功能部分自定义了一套接收数据的规则,使得通过UDP协议传输文件不会出错。

2.使用方法:

DatagramSocket():创建实例。通常用于客户端编程,它并没有特定监听的端口,仅仅使用一个临时的。 
DatagramSocket(int port):创建实例,并固定监听Port端口的报文。 
DatagramSocket(int port, InetAddress localAddr):这是个非常有用的构建器,当一台机器拥有多于一个IP地址的时候,由它创建的实例仅仅接收来自LocalAddr的报文

receive(DatagramPacket d):接收数据报文到d中。receive方法产生一个“阻塞”。 
send(DatagramPacket d):发送报文d到目的地。 
setSoTimeout(int timeout):设置超时时间,单位为毫秒。 
close():关闭DatagramSocket。在应用程序退出的时候,通常会主动释放资源,关闭Socket,但是由于异常地退出可能造成资源无法回收。所以,应该在程序完成时,主动使用此方法关闭Socket,或在捕获到异常抛出后关闭Sock

3.2.2 JAVA MulticastSocket

多播数据报套接字类用于发送和接收 IP 多播包。MulticastSocket 是一种 (UDP) DatagramSocket,它具有加入 Internet 上其他多播主机的“组”的附加功能。

多播组通过 D IP 地址和标准 UDP 端口号指定。D IP 地址在 224.0.0.0  239.255.255.255 的范围内(包括两者)。地址 224.0.0.0 被保留,不应使用。

可以通过首先使用所需端口创建 MulticastSocket,然后调用 joinGroup(InetAddress groupAddr) 方法来加入多播组。将消息发送到多播组时,该主机和端口的所有预定接收者都将接收到消息(在数据包的生存时间范围内,请参阅下文)。套接字不必成为多播组的成员即可向其发送消息。

当套接字预定多播组/端口时,它将接收由该组/端口的其他主机发送的数据报,像该组和端口的所有其他成员一样。套接字通过 leaveGroup(InetAddress addr) 方法放弃组中的成员资格。多个 MulticastSocket 可以同时预定多播组和端口,并且都会接收到组数据报。

同时,不允许 applet 使用多播套接字。

3.2.3 JAVA Swing

Swing一组Java程序元件,它能够创建图象用户接口(GUI)元件,如按钮和滚动条,它们独立于特定操作系统的开窗口系统。Swing元件使用Java Foundation ClassesJFC)。

      互联网基础类(IFC) 是网景公司最初为Java开发的图形库,第一次发布于19961216日。

      199742日,太阳微系统公司 和 网景公司宣称他们要将IFC和其他技术合并形成 Java基础类。作为IFC最初提供组件的附加品, Swing引进了一个机理:在不改变大量的程序代码前提下允许程序中每个组件观感的变化。支持可更换观感技术的引入允许Swing组件在模拟原生组件外观的同时又保持了平台独立的优点。

      Swing 是一个为Java设计的GUI工具包 Swing  JAVA API 的一部分。 Swing 包括了图形用户界面 (GUI) 器件 如:文本框,按钮,分隔窗格和表。

      SWING 提供许多比AWT更好的屏幕显示元素。它们用纯Java写成,所以同Java本身一样可以跨平台运行,这一点不像AWT。 它们是JFC的一部分。 它们支持可更换的观感和主题(各种操作系统默认的特有主题),然而不是真的使用原生平台提供的设备,而是仅仅在表面上模仿它们。这意味着你可以在任意平台上使用JAVA支持的任意观感。 轻量级元件的缺点则是执行速度较慢,优点就是可以在所有平台上采用统一的行为。

3.4 系统开发、运行环境分析

操作系统:Microsoft Windows 7

JDKjdk1.8.0_20-windows

JDK(Java Development Kit)是Sun Microsystems针对Java开发员的产品。自从Java推出以来,JDK已经成为使用最广泛的Java SDK。JDK 是整个Java的核心,包括了Java运行环境,Java工具和Java基础的类库。

开发工具:Eclipse 4.4.0 或更高版本

Eclipse企业级工作平台(Eclipse Java EE IDE for Web Developers,简称Eclipse),利用它我们可以在数据库和JavaEE的开发、发布以及应用程序服务器的整合方面极大的提高工作效率。它是功能丰富的JavaEE集成开发环境,包括了完备的编码、调试、测试和发布功能,完整支持HTML、Struts、JSF、CSS、Javascript、SQL、Hibernate

第四章 系统概要设计

4.1 系统功能模块设计

从模拟用户的角度进行分析,对于一个局域网聊天系统,首先要确定其功能是什么,也就是用户想要系统做什么工作。经过对系统的可行性分析、需求分析、技术分析后,结合调研的情况及用户的使用需求,确定了本系统的功能模块如下图所示。

 

4.1 系统功能模块图

功能模块介绍:

1.用户登陆

用户登陆时使用,提供昵称的输入和用户头像的选择等功能。用户登陆界面 共分为五部分如下图所示:

①提示信息显示区域

②输入用户昵称区域

③选择头像的列表

④头像展示区

⑤登入退出按钮

 

4.2 登陆界面

2.用户主界面

用户主界面是显示所有在线用户的界面,界面分为三块:

①显示本客户端的登入用户的头像和昵称

②自己制作的最小化和关闭的图标,为了符合程序风格,去掉了windows的原有框架,进行了适当的美化

③实时显示局域网聊天的在线用户列表,每一项都会显示一个在线用户的头像和昵称

④滚动显示当前的在线用户数目,当在线用户较多时,可以让用户直观地看到在线的人数

 

4.3 用户主界面

3.聊天界面

聊天界面是用户之间聊天使用的界面,界面共分为六部分:

①显示对象的头像和昵称

②显示聊天记录

③聊天辅助功能栏,从左到右依次为:文字属性、表情、窗口抖动、文件发送和聊天记录管理

④用户输入聊天信息

⑤发送按钮和清屏按钮,清屏按钮用于清除聊天界面的聊天信息

⑥显示对方的放大头像和登陆信息

4.4 聊天界面

4.2 系统数据流图

 

4.5 系统数据流图

第五章 系统详细设计

5.1 详细设计概述

软件详细设计的任务是,是为软件结构图中的每个模块确定所采用的算法和块内数据结构,用某种选定的表达工具给出清晰的描述,表达工具可以自由选择,但工具必须具有描述过程细节的能力,而且能够有利于程序员在编程时便于直接翻译成程序设计语言的源程序。

程序流程图、UML图等都是完成详细设计的工具,选择合适的工具并且正确地使用是十分重要的。

在概要设计阶段,已经确定了软件系统的总体结构,给出了软件系统中各个组成模块的功能和模块间的接口。作为软件设计的第二步,软件详细设计就是在软件概要设计的基础上,考虑如何实现定义的软件系统,直到对系统中的每个模块给出了足够详细的过程描述。在软件详细设计以后,程序员将仍旧根据详细设计的过程编写出实际的程序代码。因此,软件详细设计的结果基本上决定了最终的程序代码质量。

5.2 系统详细设计

5.2.1登陆界面

登陆局域网聊天程序共涉及到三个类:LanTalk类、LoginFrame类、和ComUtil类。

LanTalk类是程序的主程序;

LoginFrame类是程序的登陆界面程序;

ComUtil类是程序的通信类,当用户登陆后,ComUtil类会实例化一个MulticastSocket和一个DatagramSocket,前者用于向固定广播地址发送自己的在线信息和实现在线用户之间的群聊功能,后者用于提供两个用户之间的私聊功能。

登陆局域网聊天软件时需要运行的是LanTalk类,LanTalk类会实例化LoginFrame类初始化登陆界面,而当登陆信息填完确定登陆后,LoginFrame又会初始化ComUtil类提供通信功能,三者的关系和UML图如下所示:

(注:由于受图像大小限制,UML图并没有画出监听器的类图)

5.1 登陆界面UML

登陆界面核心代码:

ComUtil的广播在线信息主代码

public void broadCast(String msg)

{

try

{

//将msg字符串转换字节数组

byte[] buff = msg.getBytes();

//设置发送用的DatagramPacket里的字节数据

outPacket.setData(buff);

//发送数据报

singleSocket.send(outPacket);

}

//捕捉异常

catch (IOException ex)

{

ex.printStackTrace();

if (socket != null)

{

//关闭该Socket对象

socket.close();

}

JOptionPane.showMessageDialog(null,

"发送信息异常,请确认30000端口空闲,且网络连接正常!"

, "网络异常", JOptionPane.ERROR_MESSAGE);

System.exit(1);

}

}

//持续读取MulticastSocket的线程

class ReadBroad extends Thread

{

public void run()

{

while (true)

{

try

{

//读取Socket中的数据,读到的数据放在inPacket所封装的字节数组里。

socket.receive(inPacket);

//打印输出从socket中读取的内容

String msg = new String(inBuff , 0 , inPacket.getLength());

//读到的内容是在线信息

if (msg.startsWith(MyProtocol.PRESENCE)

&& msg.endsWith(MyProtocol.PRESENCE))

{

String userMsg = msg.substring(2 , msg.length() - 2);

String[] userInfo = userMsg.split(MyProtocol.SPLITTER);

UserInfo user = new UserInfo(userInfo[1] , userInfo[0] , userInfo[2],

inPacket.getSocketAddress(), 0);

//控制是否需要添加该用户的旗标

boolean addFlag = true;

ArrayList<Integer> delList = new ArrayList<Integer>();

//遍历系统中已有的所有用户,该循环必须循环完成

for (int i = 1 ; i < lanTalk.getUserNum() ; i++ )

{

UserInfo current = lanTalk.getUser(i);

//将所有用户失去联系的次数加1

current.setLost(current.getLost() + 1);

//如果该信息由指定用户发送过来

if(current.getAddress() == null 

&& current.getName().equals(user.getName())

&& current.getloginTime().equals(user.getloginTime()))

{

current.setAddress(user.getAddress());

current.setLost(0);

addFlag = false;

}

else if (current.equals(user))

{

current.setLost(0);

//设置该用户无需添加

addFlag = false;

}

if (current.getLost() > lanTalk.getUserNum() * 2)

{

delList.add(i);

}

}

//删除delList中的所有索引对应的用户

for (int i = 0; i < delList.size() ; i++)

{

lanTalk.removeUser(delList.get(i));

}

if (addFlag)

{

//添加新用户

lanTalk.addUser(user);

}

}

//读到的内容是公聊信息

else

{

//处理读到的信息

try {

lanTalk.processMsg(inPacket , false);

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

//捕捉异常

catch (IOException ex)

{

ex.printStackTrace();

if (socket != null)

{

//关闭该Socket对象

socket.close();

}

JOptionPane.showMessageDialog(null,

"接收信息异常,请确认30000端口空闲,且网络连接正常!"

, "网络异常", JOptionPane.ERROR_MESSAGE);

System.exit(1);

}

}

}

}

}

5.2.2用户主界面

用户主界面包含三个类,LanTalk类用于显示主界面在线用户列表,UserInfo类是封装用户信息的类,ShowOnline类是用于显示在线用户人数的类。

三者的关系和UML图如下:

 

5.2 用户主界面UML

用户主界面核心代码:

显示在线人数

public ShowOnline(LanTalk lanTalk)

{

this.lanTalk = lanTalk;

this.x = 0;

this.changepx = 1;

timer = new Timer(200,

new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

update();

}

});

timer.start();

}

public void update()

{

repaint();

}

public void paintComponent(Graphics g)

{

super.paintComponent(g);

g.setColor(color);

g.setFont(new Font("华文新魏" , Font.BOLD , 15));

msg = "当前有 " + (lanTalk.getUserNum() - 1) + " 人在线";

FontMetrics fm = g.getFontMetrics();

int stringwidth = fm.stringWidth(msg);

int stringascent = fm.getAscent();

if(changepx == 1 && x + changepx + stringwidth > getWidth())

{

changepx = -1;

x += changepx;

}

else

x += changepx;

if(changepx == -1 && x + changepx < 0)

{

changepx = 1;

x += changepx;

}

else

x += changepx;

g.drawString(msg, x, getHeight() - stringascent / 2);

}

5.2.3聊天界面

聊天界面包含六个类:ChatFrame类、FontJWindow类、PicsJWindow类RecordJWindow类、FileReceiveJPanel类和FileSendJPanel类。

ChatFrame类是构建聊天界面主框架的类,FontJWindow类是用于设置字体格式的类,PicsJWindow类是用于显示表情的类,RecordJWindow类是用于记录用户聊天信息的类,FileReceiveJPanel类和FileSendJPanel类是用于文件发送和接收的类。

(注:由于受图像大小限制,UML图并没有画出监听器的类图)

 

5.3 聊天界面UML1

 

5.4 聊天界面UML2

聊天界面核心代码:

字体设置关键代码

class FontListener implements ActionListener

{

public void actionPerformed(ActionEvent e)

{

if(e.getSource() == jcbFontName)

{

String fontName = (String)jcbFontName.getSelectedItem();

String[] userFont = (owner.getSelf().getFont()).split(MyProtocol.FONT);

Font newFont = new Font(fontName, Integer.parseInt(userFont[1]), Integer.parseInt(userFont[2]));

owner.getSelf().setFont(newFont);

owner.getInputPane().setFont(newFont);

}

else if(e.getSource() == jcbFontSize)

{

int fontSize = (Integer)jcbFontSize.getSelectedItem();

String[] userFont = (owner.getSelf().getFont()).split(MyProtocol.FONT);

Font newFont = new Font(userFont[0], Integer.parseInt(userFont[1]), fontSize);

owner.getSelf().setFont(newFont);

owner.getInputPane().setFont(newFont);

}

else if(e.getSource() == jbBold)

{

String[] userFont = (owner.getSelf().getFont()).split(MyProtocol.FONT);

Font newFont = null;

if(jbBold.getIcon().toString().equals("src/font_image/bold_normal.png"))

{

newFont = new Font(userFont[0], Font.BOLD, Integer.parseInt(userFont[2]));

jbBold.setIcon(new ImageIcon("src/font_image/bold_down.png"));

jbItalic.setIcon(new ImageIcon("src/font_image/italic_normal.png"));

jbPlain.setIcon(new ImageIcon("src/font_image/plain_normal.png"));

}

else

{

newFont = new Font(userFont[0], Font.PLAIN, Integer.parseInt(userFont[2]));

jbBold.setIcon(new ImageIcon("src/font_image/bold_normal.png"));

}

owner.getSelf().setFont(newFont);

owner.getInputPane().setFont(newFont);

}

else if(e.getSource() == jbItalic)

{

String[] userFont = (owner.getSelf().getFont()).split(MyProtocol.FONT);

Font newFont = null;

if(jbItalic.getIcon().toString().equals("src/font_image/italic_normal.png"))

{

newFont = new Font(userFont[0], Font.ITALIC, Integer.parseInt(userFont[2]));

jbBold.setIcon(new ImageIcon("src/font_image/bold_normal.png"));

jbItalic.setIcon(new ImageIcon("src/font_image/italic_down.png"));

jbPlain.setIcon(new ImageIcon("src/font_image/plain_normal.png"));

}

else

{

newFont = new Font(userFont[0], Font.PLAIN, Integer.parseInt(userFont[2]));

jbItalic.setIcon(new ImageIcon("src/font_image/italic_normal.png"));

}

owner.getSelf().setFont(newFont);

owner.getInputPane().setFont(newFont);

}

else if(e.getSource() == jbPlain)

{

String[] userFont = (owner.getSelf().getFont()).split(MyProtocol.FONT);

Font newFont = null;

if(jbPlain.getIcon().toString().equals("src/font_image/plain_normal.png"))

{

newFont = new Font(userFont[0], Font.PLAIN, Integer.parseInt(userFont[2]));

jbBold.setIcon(new ImageIcon("src/font_image/bold_normal.png"));

jbItalic.setIcon(new ImageIcon("src/font_image/italic_normal.png"));

jbPlain.setIcon(new ImageIcon("src/font_image/plain_down.png"));

}

else

{

newFont = new Font(userFont[0], Font.PLAIN, Integer.parseInt(userFont[2]));

jbPlain.setIcon(new ImageIcon("src/font_image/plain_normal.png"));

}

owner.getSelf().setFont(newFont);

owner.getInputPane().setFont(newFont);

}

else if(e.getSource() == jbColor)

{

Color color = JColorChooser.showDialog(getObj(), "请选择一种颜色", owner.getSelf().getColor());

if(color != null)

{

owner.getSelf().setColor(color);

owner.getInputPane().setForeground(color);

}

}

}

}

5.2.4辅助工具类

辅助类包括MyProtocol类和PicsIcon类,其中MyProtocol类用于提供程序需要的一些协议字段,而PicsIcon类则是扩展自ImageIcon类用于封装表情,便于表情的提取。

 

5.5 辅助类UML

MyProtocol类核心代码:

public interface MyProtocol

{

String PRESENCE = "@@";  //在线信息广播

String SPLITTER = "&&";  //登陆信息分割

String FONT = "~~";    //字体分割

String SENDFONT = "$$";      //发送用户的字体设置

String EXP_SPLIT = "!!";     //表情分割

String EXP_DETAIL = "%%";    //表情定位分割

String P_SPLIT = "##";  //发送区域分隔符

String SHAKE = "@#";  //震动信息标志

String FILE = "@&";  //文件标志

String FILE_REFUSE = "NOSEND"; //拒绝接收文件

String FILE_END = "FILE_END"; //文件结束标志

}

第六章 系统实现

6.1 总体工程架构的实现

 

6.1 工程架构图

6.2 具体功能实现

用户界面登陆如下:

 

6.2 用户登陆界面

用户主界面如下:

 

6.3 用户主界面

用户主界面如下:

 

6.4 用户聊天界面

消息记录界面如下,消息记录界面提供消息清除和消息导出功能:

6.5 用户聊天界面

    表情界面和字体设置界面如下:

 

6.6 字体设置界面

 

6.7 表情界面


结论

经过半个月的艰苦奋斗,一个界面美观功能相对齐全的局域网聊天系统终于浮现在了我面前。这段时间可用一句话来形容“痛并快乐着”。痛是因为在完成的过程中遇到了许多让我捶胸顿足的难题;快乐是因为有着老师和同学们的帮助,使得一些关键、重要问题能够得到及时而有效的解决。

虽然所做的设计和我们专业是匹配的,但平时学习课程和所做练习能够综合统一起来的并不多,所以在整个设计、开发过程中,也同时一步步提高着我自己的专业能力水平。

当然在实现过程中总会碰到棘手的问题,但这同时也是锻炼自己意志力的时候。老师和学校也教导我们坚持就是胜利,我也秉着这样的信念一步一个脚印的踏过来。


参考文献

【1】.  编著:张友生等.《软件体系结构》[M]. 2. 北京:清华大学出版社,2006.11

【2】.  编著:Y.Daniel Liang.Java语言程序设计基础篇》[M]. 8. 北京:机械工业出版社,2011.5

【3】.  编著:Y.Daniel Liang.Java语言程序设计进阶篇》[M]. 8. 北京:机械工业出版社,2011.5

【4】.  编著:Martin L.Shoemaker. 译:高猛、朱洁梅.UML实战教程》[M]

【5】.  编著:李刚.《疯狂Java讲义》[M]. 2. 北京:电子工业出版社,2012.1

猜你喜欢

转载自www.cnblogs.com/dejyyhg/p/12650711.html