基于多点广播的设计与实现文档格式.docx
《基于多点广播的设计与实现文档格式.docx》由会员分享,可在线阅读,更多相关《基于多点广播的设计与实现文档格式.docx(20页珍藏版)》请在冰豆网上搜索。
Eclipse
1系统概述
1.1系统开发背景
随着社会发展,Internent的迅速普及,人们对实时通信的要求越来越迫切,需求日益增加,网络聊天已经成为了一大时尚,不少人都有这样的经历。
多客户端/服务器模式是一种能够在基于网络环境的分布处理过程中,使用基于多点广播的设计与实现。
1.2系统开发的目的和意义
该通信模型首先在客户机和服务器之间定义一套通信协议,并创建一个Socket类,利用这个类来建立一条可靠的链接;
然后,客户端/服务器再在这条连接上可靠地传输数据。
客户端发出请求,服务器发出请求,服务器监听来自客户机的请求,并为多个客户端提供相应服务。
多客户/服务模式可靠性高、采用模块化设计所以它的优势很明显。
是现代通信不可或缺的一部分。
2相关技术简介
2.1UDPSocket基础
使用用户数据报协议(UserDatagramProtocol,简称UDP)进行会话必须将信息装配成一定尺寸的小报文,当发送一条信息,接收方能否收到并返回信息永远是不确定的,如果无法收到返回信息,我们就无法确定我们发送的信息是否被接收——它可能在途中丢失,接收者返回的响应信息也可能丢失,另外,接收者也可能忽略我们的信息,因此,UDP被描述为不可靠的、无连接的和面向消息的。
创建UDPsockets非常象创建一个邮箱。
邮箱是使用地址来识别的,但是,我们不需要为每个发送信息的人构造一个新的邮箱,可以在含有发送信息的明信片上写上目的地址,将其放在邮箱中并发送出去。
接收者可能会长久的等待,直到含有信息的明信片到达它的邮箱,而明信片上标识了发送者的返回地址。
2.2IP多点传送的原理
IP 多点传送 MulticastSocket 类IP多点传送(multicastdelivery)是针对点到点的传送和广播传送两种方式而言的,它是指在一定的组内对其成员进行的广播,是一种有限的广播。
组中的某个成员发出的信息,组中的其它所有成员都能收到。
它是UDPSockets的一个分支。
IP多点传送特别适合与高带宽的应用,例如在网络上发送视频和音频。
随着网络带宽的不断提高和网络通讯质量的不断改善,IP多点传送还将广泛地被应用于网上聊天及网上会议,分布式数据存储,联机事务处理,交互式游戏等方面。
另外,多点传送还可以被客户机用于在网络上寻找相应的服务器,客户机发送一个多点传送的请求,任何监听服务器都可以与客户机连接并开始一个事务。
2.3客户机/服务器模式
在TCP/IP网络中两个进程间的相互作用的主机模式是客户机/服务器(Client/Servermodel)。
该模式的建立基于以下两点:
1、非对等作用;
2、通信完全是异步的。
客户机/服务器模式在操作过程中采取的是主动请示方式:
首先服务器方要先启动,并根据请示提供相应服务:
(过程如下)
1、打开一通信通道并告知本地主机,它愿意在某一个公认地址上接收客户请求。
2、等待客户请求到达该端口。
3、接收到重复服务请求,处理该请求并发送应答信号。
4、返回第二步,等待另一客户请求
5、关闭服务器。
客户方:
1、打开一通信通道,并连接到服务器所在主机的特定端口。
2、向服务器发送服务请求报文,等待并接收应答;
继续提出请求……
3、请求结束后关闭通信通道并终止。
2.4基本套接字
为了更好说明套接字编程原理,给出几个基本的套接字:
1、创建套接字——socket()
功能:
使用前创建一个新的套接字
格式:
SOCKETPASCALFARsocket(intaf,inttype,intprocotol);
参数:
af:
通信发生的区域
type:
要建立的套接字类型
procotol:
使用的特定协议
2、指定本地地址——bind()
将套接字地址与所创建的套接字号联系起来。
intPASCALFARbind(SOCKETs,conststructsockaddrFAR*name,intnamelen);
s:
是由socket()调用返回的并且未作连接的套接字描述符(套接字号)。
其它:
没有错误,bind()返回0,否则SOCKET_ERROR
地址结构说明:
structsockaddr_in
{
shortsin_family;
//AF_INET
u_shortsin_port;
//16位端口号,网络字节顺序
structin_addrsin_addr;
//32位IP地址,网络字节顺序
charsin_zero[8];
//保留
}
3、建立套接字连接——connect()和accept()
共同完成连接工作
intPASCALFARconnect(SOCKETs,conststructsockaddrFAR*name,intnamelen);
SOCKETPASCALFARaccept(SOCKETs,structsockaddrFAR*name,intFAR*addrlen);
同上
4、监听连接——listen()
用于面向连接服务器,表明它愿意接收连接。
intPASCALFARlisten(SOCKETs,intbacklog);
5、关闭套接字——closesocket()
关闭套接字s
BOOLPASCALFARclosesocket(SOCKETs);
3系统设计
3.1设计思想
整个系统分为广播发送端和接收端,发送端发送数据信息到多播组。
接受端可以选择接收与不接收,服务器端是信息的中心。
服务器端可以打开指定的文件,通过定时器不断发送信息,同时可以自己显示正在发送和已发送的信息。
客户端则可以选择接收和停止接收,同时显示接收到的内容。
本课程设计按照系统的具体功能要求,首先应用Socket编程创建客户端和服务器端,每个接收端就会相应的创建一个线程,它们之间通过这个连接来实现数据通信;
然后在发送端和接收端设置一个监听器,用于监听发出的消息。
并根据消息做出不同的动作。
3.2系统功能
该系统实现了局域网内部的信息广播,,同一子网掩码下的用户都可以接收并查看
发送端发送的信息。
发送端可以开始发送和停止发送,接收端也可以接收和停止接收,两端都可以显示发送的信息。
3.3系统架构
(1)选择用户数据报协议UDP,使用Java的Socket编程机制,分别建立发送端与接收端,自己可以设定主机的地址。
(2)分别设计发送端与接收器端的界面,并使用Java应用程序用户界面的开发工具包Swing进行窗体界面的布局,以及实现部分窗口事件的相应。
3.4模块设计
(1)广播发送端:
主要实现向各个接收端发布广播消息。
1、选择要发送的文件:
可以选择路径。
2、发送信息:
运用MulticastSocket多播数据报套接字类用于发送和接收IP多播包。
设置Timer计时器在指定时间间隔触发一个或多个ActionEvent。
3、显示消息:
显示发送的内容和已发送的内容。
主要用BufferedReader(Readerin)
创建一个使用默认大小输入缓冲区的缓冲字符输入流用来每次显示一行正发送的内容。
显示已发送的内容则要使用append(Stringstr)将给定文本追加到文本区的当前文本。
(2)客户端:
主要实现接收发送端发送的消息,和发送端一样可以显示已接收的信息内容。
和接受端得一个重要的区别在于它不需要打开一个文件,代码要简单一点。
4详细设计与实现
4.1服务器端
(1)这部分代码包含的包有:
importjava.io.*;
import.*;
importjava.awt.*;
importjava.awt.event.*;
importjavax.swing.Timer;
(2)界面设计
该段功能由ServerFrame.java文件中的ServerFrame类实现,具体实现过程如下:
窗口布局:
服务器端窗口使用了BorderLayout事务管理器,把整个容器分成了几个区域,每个面板又分别使用不同的事务管理器放置其他组件,如按钮、标签、文本框等,各个组将构成了一个完整的服务器端界面。
图4.1发送端初始化界面
3)事件处理:
通过Java的授权事件模型,针对组件“选择要广播的文件”、“开始广播”“停止广播”Button1~Button8,通过addActionListener(主要运用了addActionListener)方法注册监听器,并且实现ActionListener接口中的actionPerformed方法,这样,当组件触发了相应类型的事件后,此事件就会被传送给已注册的监听器,事件监听器负责处理事件。
至此,实现了窗口对以下几个事件的响应:
打开文件,开始发送信息、停止发送信息。
4.2服务器端
(1)这部分代码包含的包只有三个:
这部分的和发送端的原理一样,所以只给出代码如下:
Button开始接收,停止接收;
TextArea显示正在接收内容,显示已接收的内容;
Threadthread;
boolean停止=false;
publicReceive(){
super("
定时接收信息"
);
thread=newThread(this);
开始接收=newButton("
开始接收"
停止接收=newButton("
停止接收"
停止接收.addActionListener(this);
开始接收.addActionListener(this);
显示正在接收内容=newTextArea(10,10);
显示正在接收内容.setForeground(Color.blue);
显示已接收的内容=newTextArea(10,10);
Panelnorth=newPanel();
north.add(开始接收);
north.add(停止接收);
add(north,BorderLayout.NORTH);
Panelcenter=newPanel();
center.setLayout(newGridLayout(1,2));
center.add(显示正在接收内容);
center.add(显示已接收的内容);
add(center,BorderLayout.CENTER);
validate();
图4.2接收端初始化界面
(3)事件处理部分主要代码
while(true){
bytedata[]=newbyte[8192];
DatagramPacketpacket=null;
packet=newDatagramPacket(data,data.length,group,port);
try{
socket.receive(packet);
Stringmessage=newString(packet.getData(),0,packet
.getLength());
显示正在接收内容.setText("
正在接收的内容:
\n"
+message);
显示已接收的内容.append(message+"
}catch(Exceptione){
}
if(停止==true){
break;
从这段代码中可以看出接收端的这部分代码和发送端的区别主要就在于把socket.send(packet);
改为socket.receive(packet);
4.3核心类
(1)类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(InetAddressgroupAddr)方法来加入多播组:
将消息发送到多播组时,该主机和端口的所有预定接收者都将接收到消息(在数据包的生存时间范围内,请参阅下文)。
套接字不必成为多播组的成员即可向其发送消息。
当套接字预定多播组/端口时,它将接收由该组/端口的其他主机发送的数据报,像该组和端口的所有其他成员一样。
套接字通过leaveGroup(InetAddressaddr)方法放弃组中的成员资格。
多个MulticastSocket可以同时预定多播组和端口,并且都会接收到组数据报。
同时,不允许applet使用多播套接字。
(2)类Frame:
Frame是带有标题和边框的顶层窗口。
窗体的大小包括为边框指定的所有区域。
边框区域的尺寸可以使用getInsets方法获得,但是,由于这些尺寸与平台相关,因此在通过调用pack或show将窗体设置为可显示之前,将无法获得有效的insets值。
由于窗体的总大小包括了边框区,因此边框实际上遮掩了窗体的部分区域,并将可用于在矩形中呈现和/或显示子部件的区域限制在一个矩形内,该矩形左上角的位置为(insets.left,insets.top),宽度为width-(insets.left+insets.right),长度为height-(insets.top+insets.bottom)。
(3)类Thread
线程是程序中的执行线程。
Java虚拟机允许应用程序并发地运行多个执行线程。
每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。
每个线程都可以或不可以标记为一个守护程序。
当某个线程中运行的代码创建一个新Thread对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护程序。
当Java虚拟机启动时,通常都会有单个非守护线程(它通常会调用某个指定类的main方法)。
Java虚拟机会继续执行线程,直到下列任一情况出现时为止。
调用了Runtime类的exit方法,并且安全管理器允许退出操作发生。
非守护线程的所有线程都已停止运行,无论是通过从对run方法的调用中返回,还是通过抛出一个传播到run方法之外的异常。
创建新执行线程有两种方法。
一种方法是将类声明为Thread的子类。
该子类应重写Thread类的run方法。
接下来可以分配并启动该子类的实例。
创建线程的另一种方法是声明实现Runnable接口的类。
该类然后实现run方法。
然后可以分配该类的实例,在创建Thread时作为一个参数来传递并启动。
每个线程都有一个标识名,多个线程可以同名。
如果线程创建时没有指定标识名,就会为其生成一个新名称。
4.4效果截图
运行BroadCastWord.java后,点击“选择要广播的文件”按钮时出现图4.3:
图4.3选择文件路径
选择一txt文档,点击“开始广播”一段时间后出现图4.4:
图4.4点击“开始广播”
然后点击“停止广播”时的截图4.5:
图4.6点击“开始接收”
5总结
经过努力,将课程设计做完了。
在这次作业过程中,遇到了许多困难,但在老师,同学的帮助下,顺利的完成了设计。
这个程序代码并不多,也不复杂,但程序编写中用到了JAVA中的Swing组件,面板容器,事件处理,线程的创建、同步,输入输出处理,内部类,异常处理,和网络通信的知识。
设计过程中对程序整体的认知不够准确,只能想到一部分功能而不能满足整体的要求。
通过查询参考书和向同学请教,最后终于搞明白了。
在整个设计过程中,收获最大的是方法和能力,那些分析和解决问题的方法与能力。
在整个过程中,发现理论知识和实际应用脱节。
总体来说,觉得做这种设计帮助还是很大的,它需要将学过的相关知识都系统地联系起来,对学过的理论进行深入的理解,为以后进行相关的工作打下了基础。
参考文献:
[1]孙卫琴.JAVA网络程序精解[M].北京:
电子工业出版社.
[2]孙印杰,刘斌,孙玉强.JAVA编程案例精解[M].北京:
[3]朱福喜.java程序设计技巧与开发实例[M].北京:
人民邮电出版社.
课程设计成绩评定表
出勤
情况
出勤天数
缺勤天数
成
绩
评
定
出勤情况及设计过程表现(20分)
论文(20分)
设计成果(60分)
总成绩(100分)
综
合
指导教师签名:
年月日
BroadCastWord类:
packagechat;
//通过数据流、序列化和文件系统提供系统输入和输出。
//为实现网络应用程序提供类。
//包含用于创建用户界面和绘制图形图像的所有类。
//提供处理由AWT组件所激发的各类事件的接口和类。
//计时器
publicclassBroadCastWordextendsFrameimplementsActionListener{//Actionlisener监听器
intport;
//Frame是带有标题和边框的顶层窗口
InetAddressgroup=null;
//此类表示互联网协议(IP)地址。
MulticastSocketsocket=null;
//MulticastSocket播数据报套接字类用于发送和接收IP多播包。
Timertime=null;
//Timer计时器在指定时间间隔触发一个或多个ActionEvent。
FileDialogopen=null;
//FileDialog类显示一个对话框窗口,用户可以从中选择文件。
Buttonselect,开始广播,停止广播;
//Button此类创建一个标签按钮。
当按下该按钮时,应用程序能执行某项动作。
Filefile=null;
//文件和目录路径名的抽象表示形式。
StringFileDir=null,fileName=null;
FileReaderin=null;
//FileReader用来读取字符文件的便捷类。
BufferedReaderbufferIn=null;
//BufferedReader从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
inttoken=0;
TextArea显示正在播放内容,显示已播放的内容;
//TextArea对象是显示文本的多行区域。
可以将它设置为允许编辑或只读。
publicBroadCastWord(){
单词广播系统"
select=newButton("
选择要广播的文件"
开始广播=newButton("
开始广播"
开始广播.setEnabled(false);
//setEnabled()根据参数的值启用或禁用此组件。
停止广播=newButton("
停止广播"
select.addActionListener(this);
//添加指定的动作侦听器,以接收发自此按钮的动作事件。
开始广播.addActionListener(this);
停止广播.addActionListener(this);
time=newTimer(2000,this);
open=newFileDialog(this,"
FileDialog.LOAD);
显示正在播放内容=newTextArea(10,10);
//构造一个新文本区,该文本区具有指定的行数和列数,并将空字符串作为文本。
显示正在播放内容.setForeground(Color.pink);
//设置组件的前景色为粉红色。
显示已播放的内容=newTextArea(10,10);
//Panel是最简单的容器类。
应用程序可以将其他组件放在面板提供的空间内,这些组件包括其他面板。
north.add(select);
//add将指定组件追加到此容器的尾部
north.add(开始广播);
north.add(停止广播);
//BorderLayout这是一个布置容器的边框布局,
//setLayout设置此容器的布局管理器。
center.add(显示正在播放内容);
center.add(显示已播放的内容);
add(center,BorderLayout.CENTER)