本文介绍了网络通讯中通用的传输控制协议(TCP)和用户数据包协议(UDP)并 且利用Java语言设计了一个简单的基于UDP 数据广播的局域网络会议程序展示了 在Java语言中进行UDP 数据发送和接收的一般步骤由于Java语言卓越的跨平台特 性本系统能够不加修改的运行在Windows Linux Mac OS等一系列不同平台上
介绍
随着网络技术的普及网络会议在公司企业和单位中的应用也越来越广一 个网络会议系统通常包括一个服务器程序和一个客户端程序其中服务器端负责进 行用户管理信息交互以及表决统计客户端则实现收听发言公开发言私下讨 论投票表决等功能在一个网络会议系统的设计和实现中通常涉及到图形用户 界面设计TCP/IP连接UDP 数据广播多线程等一系列技术本文通过一个简单 示例程序展示了在Java语言中进行UDP 数据发送和接收的一般步骤以及UDP 数据 广播在局域网络会议系统中的作用
TCP (Transmission Control Protocol传输控制协议) 是一种基于连接的通 讯协议当两台计算机之间需要进行可靠的数据传输时它们通过网络建立起一个 稳定的连接这种连接通常也被称为数据链与电话网络相类似这种数据链是点 对点的通讯的双方则通过这条数据链来回传输数据在这条稳定的数据链的基础 上TCP 协议通过信息校验能够保证接收方所接收到的数据和发送方所发送的数据 在内容和顺序上是完全一致的从而实现了数据的可靠传输
UDP (User Datagram Protocol用户数据包协议)与TCP 协议之间的不同在于 UDP 不是一种基于稳定连接的通讯协议UDP 协议将独立的数据包从一台计算机传 输到另外一台计算机但是并不保证接受方能够接收到该数据包也不保证接收方 所接收到的数据和发送方所发送的数据在内容和顺序上是完全一致的因此UDP 协议更类似于普通邮政服务寄信人不能够保证所寄出去的信能够被收信人及时收 到后发出的信也许会比先发出的信更早到达
对于很多应用程序来说在互相通讯的两台计算机之间保证一个可靠与稳定的 数据链是至关重要的在这种情况下就应该首先考虑使用TCP 协议在凉台计算机 之间建立起TCP/IP连接在HTTP (HyperText Transfer Protocol超级文本传输 协议)FTP (File Transfer Protocol 文件传输协议)以及TELNET 应用程序中 均要求在通讯的双方之间建立起稳定可靠的数据链因此它们都使用了TCP 协议来 进行数据传输
在TCP 协议中发送方和接收方必须交换额外的信息以保证接收方已经接收到 所发送的数据包并且所接收到的数据和发送方所发送的数据在内容和顺序上是完全 一致的这些额外的信息交换提高了数据传输的可靠度但是也给网络带来了额外 的负担导致数据交换的延迟从而降低了整个网络的数据交换能力对于某些对 实时性要求较高的应用程序来说这样的延迟有可能是不可接受的例如一个毫秒 级的时钟服务器按照一定的频率向客户机提供当时的时间数据如果这些时间数据 在传输过程中受到了较大的延迟这些过时的时间数据是完全没有意义的即使客 户机准确无误的接收到了这些数据相反如果客户机所接收到的每一个数据包都 是实时的那么即使客户机错过了一两个数据包也是可以接受的因为他总是可以 根据后面所接收到的数据包来对自己进行校正因此对于对实时性要求比较高但 是对传输可靠度要求比较低的应用程序来说UDP 协议显然是一个合适的选择
在通用的以太网(Ehternet)构架下计算机于计算机之间的数据交换都是通过 交换机来完成的如果一份数据需要被传送给多个接收者在使用TCP/IP连接的情 况下数据发送者需要向交换机发送N 个同样的拷贝而交换机则负责将这N 个拷 贝分发给所有的接收者在使用UDP 数据广播的情况下数据发送者只需要向交换 机发送一个拷贝交换机负责将这个信息制作N 个拷贝发送给所有的机器在这种 情况下使用TCP/IP连接会大大的增加网络的负担在一个普通局域网络中可以 认为由于网络状况较差而造成数据丢失的可能性比较小而利用UDP 数据广播进行 数据交换能够大幅度减轻网络的负担因此设计一个基于UDP 数据广播的局域网络 会议系统式完全可行的
通常来说一台计算机只有一个物理界面与网络相连接所有的应用程序均通 过该物理界面从网络接收数据或者将数据发送到网络由于一个网络上同时存在多 台计算机并且一台计算机上有可能同时存在多个应用程序需要与网络进行数据交 换我们通常使用IP和端口号来识别需要进行数据交换的计算机和应用程序每台 计算机由一个位的IP地址来识别在一个网络中每台计算机的IP地址都是唯一 的因此应用程序能够根据IP地址来将数据发送到正确的计算机每个需要与网络 进行数据交换的应用程序均被系统分配一个位的端口号系统根据这个端口号将 从网络接收到的数据转发给相对应的应用程序端口号的范围是从 到 其 中从 到被系统所保留主要是用来提供HTTP FTP 以及TELNET等系统服务 因此用户自己的应用程序不应该试图去使用小于的端口
Java语言的一个显着优点就是它从语言的高度上提供了对网络的支持使得程 序员能够很容易的构建基于网络的应用程序在Java 版的标准类库中 提供了 个接口以及个Java类在这些接口和类的基础上程序员能够轻易的实 现几乎是所有的常见网络应用例如ServerSocket能够用来构建基于TCP/IP的服 务器程序Socket能够用来构建基于TCP/IP的客户端程序而DatagramPacket以及 DatagramSocket能够用来构建基于UDP 的数据广播程序在中的其他Java 库能够被用来实现域名解析身份认证安全许可等一系列功能由于这些Java库 的功能和具体用法等内容已经超出了本文的讨论范围感兴趣的读者可以进一步参 考Java的文档以及Sun 公司的Java Tutorial等资料
这个简单的程序包括如下三个模块
数据广播与接收模块 Broadcastjava
数据接收线程 Receiverjava
图形用户界面 Chatjava
程序设计
数据广播与接收模块Broadcastjava是本示例程序的核心部分该类包括一个 构造方法一个数据发送方法和一个数据接收方法为了使这个类能够被更加广泛 的应用到其它应用程序中作者又添加了一个端口配置方法
在构造方法中我们首先利用InetAddress 定义一个数据广播组同时构造一 个用于发送数据的DatagramSocket与一个用于接收数据的MulticastSocket 在这 里我们使用 来作为数据广播组的标示符虽然这个标示符与IP地址的格 式相同但是它并不表示Internet上的一台机器此外我们在端口配置方法中分 别指定端口和端口位数据发送和数据接收端口如果把一个UDP 数据广播 系统比喻成无线电广播系统的话数据广播标示符可以被认为是波段而数据接收 端口可以被认为是频率收音机用户必须把收音机调整到相应的波段和频率才能够 接收到电台信号我们的UDP 数据接收程序也必须加入相对应的数据广播组并且使 用正确的数据接收端口才能够正确的接收到UDP 广播数据在构造方法中我们利 用MulticastSocket 的构造函数指定数据接收端口(频率)并利用其joinGroup 方 法指定数据广播组(波段)
public Broadcast()
{
GetBroadcastPorts();
try
{
// 构造数据广播组标示符 (波段)
BroadcastGroup = InetAddressgetByName();
// 构造数据发送端口
Sender = new DatagramSocket(ServerPort);
// 构造数据接收端口 (频率)
Receiver = new MulticastSocket(ClientPort);
// 指定数据接收端口的数据广播组 (波段)
ReceiverjoinGroup(BroadcastGroup);
} catch (Exception e) {}
}
在数据发送方法中我们基于用户所提供的数据以及数据广播目标端口(频率) 构造一个DatagramPacket数据包然后利用发送数据的DatagramSocket的send方法将该数据包发送到局域网与此相反在数据接收方法中我们首先构造一个空的 DatagramPacket数据包然后利用接收数据的MulticastSocket的receive方法填充该数据包中的内容为了避免由于数据包大小不同所造成的数据丢失等麻烦我们特地将两个数据包的大小设置成一样的
// 数据发送方法
public void SendData(String Msg)
{
byte[] b = new byte[];
DatagramPacket packet;
try
{
// 字节序列b 包括需要发送的数据
b = MsggetBytes();
// 构造一个数据包BroadcastGroup是数据广播组标示符(波段)
// ClientPort是数据广播目标端口(频率)
packet = new DatagramPacket(b blength BroadcastGroup ClientPort);
// 发送数据包
Sendersend(packet);
} catch (Exception e) {}
}
// 数据接收方法
public String ReceiveData()
{
byte[] b = new byte[];
// 构造一个空的数据包
DatagramPacket packet = new DatagramPacket(b );
String InMsg;
try
{
// 接收数据
Receiverreceive(packet);
} catch (IOException e) {}
// 丛数据包中获得接收到的数据
b = packetgetData();
InMsg = new String(b);
return InMsg;
}