论文部分内容阅读
摘要:随着网络技术与计算机开发语言的发展,越来越多的程序员利用Java来编写网络程序。数据报通讯是一个高效的网络通讯方式。通过C/S模型的程序来说明Java中如何利用UDP进行多播通信,对于网络编程有一定的参考价值。
关键词:Java;数据报;UDP;C/S;通讯
中图分类号:TP393文献标识码:A文章编号:1009-3044(2007)03-10669-01
1 引言
Java是一种可以编写跨平台应用软件的面向对象的程序设计语言。Java伴随着Internet的迅猛发展而发展,逐渐成为重要的网络编程语言。网络编程的目的就是指直接或间接地通过网络协议与其它计算机进行通讯,需要解决两个主要问题:一个是如何准确定位网络上的主机;另一个问题是找到主机后如何可靠有效地进行数据传输。在TCP/IP协议中IP层主要负责网络主机的定位,而TCP层提供面向应用的可靠的或非可靠的数据传输机制。
TCP/IP协议的名称中虽然只有TCP协议名,但是在TCP/IP的传输层同时存在TCP和UDP两个协议。这两个协议都可完成网络上从服务器到客户机的数据传输。
2 Socket、TCP和UDP
談及网络通讯,必定提到一个名词:Socket,中文是“套接字”。网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接,它是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。不管使用TCP还是UDP协议传输数据,都要用到Socket。
TCP是传输控制协议,是Transfer Control Protocol的简称,是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方的成对的两个Socket之间必须建立连接,以便在TCP协议的基础上进行通信。
UDP是用户数据报协议,是User Datagram Protocol的简称,是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址和目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。
TCP的传输是可靠的,而UDP的传输是不可靠的。为什么我们还要用UDP在网络上传输数据呢?因为保证数据的可靠传输是需要付出代价的,对数据内容正确性的检验必然占用计算机的处理时间和网络的带宽,所以UDP的传输效率比TCP要高一些;而且许多应用中并不需要保证严格的传输可靠性,比如视频会议系统,网络游戏,需要实时的交互,但并不要求音频视频的绝对正确。
3 数据报多播通讯方式
数据报(Datagram)就跟日常生活中的邮件系统一样,是不能保证每一封信都能可靠地寄到目的地。Java在java.net包是提供了三个类:DatagramSocket、DatagramPacket和MulticastSocket用来支持数据报多播通信。
3.1 DatagramSocket
DatagramSocket用于程序之间建立传送数据报的通信连接,是数据报通信中的Socket。在数据报实现C/S(Client/Server,客户机/服务器)通信程序时,无论在客户端还是服务器端,都要首先建立一个DatagramSocket对象,用来表示数据报通信的端点,应用程序通过Socket接收或发送数据报。
DatagramSocket的构造方法如下:
(1)DatagramSocket( ):与本机任何可用端口绑定
(2)DatagramSocket(int port):与指定端口绑定
(3)DatagramSocket(int port, InetAddress laddr):与指定本地地址的指定端口绑定
其中,laddr指明一个可用的本地地址,可用IP地址;port指明Socket所使用的端口号。在选择端口时必须小心。每一个端口提供一种特定的服务,只有给出正确的端口,才能获得相应的服务。0~1023的端口号为系统所保留,所以在选择端口号时,最好选择一个大于1023的数防止发生冲突。如果发生端口的冲突,会生成SocketException类异常。所以上述3个构造方法都声明抛出非运行时异常SocketException,程序中必须进行异常处理,或者捕获、或者声明抛出。
3.2 DatagramPacket
DatagramPacket用来表示一个数据报,它是传输数据的载体,封装了数据、数据长度、数据报地址等信息。DatagramPacket类的构造方法可以用来构造两种用途的数据报:接收外来数据的数据报和向外发送的数据报。构造方法如下:
(1)DatagramPacket(byte buf[],int length);
构造用来接收长度为length的数据报,字节数组buf存放数据报数据,length必须小于buf的长度。
(2)DatagramPacket(byte buf[], int length, InetAddress addr, int port);
构造用于发送指定长度的数据报,发送到指定主机的指定端口。
(3)DatagramPacket(byte[]buf, int offset, int length);
构造用来接收长度为length的数据报,并指定数据报在缓冲区buf中的偏移量offset。
(4)DatagramPacket(byte[]buf, int offset, int length, InetAddress address, int port);
构造用于发送指定长度的数据报,发送到指定主机的指定端口,并指定数据报的数据在缓冲区buf中的偏移量offset。
3.3 MulticastSocket
用于客户端接收服务器端发送的广播数据报。需要先创建多播数据报,并加入一个多播组。一个多播组由一个D类IP地址指定。D类IP地址的范围是:224.0.0.0~239.255.255.255,其中224.0.0.0是保留地址,不能使用。要加入到多播组,需要创建一个MulticastSocket并绑定到指定端口,然后调用该Socket的joinGroup(InetAddress groupAddr)方法。
4 数据报多播通信实例
采用数据报通信方式实现Client/Server的通信程序。程序由客户端和服务器端两部分组成。服务器端主机中有一个名为“bbb.txt”文件,文件中保存了一段英文。服务器端发送数据报的目的主机地址与端口固定为多播组地址。客户端从这个固定的主要地址和端口监听是否有数据报,如有则获取并显示数据。
4.1 服务器端程序
import java.io.*;
import java.net.*;
public class MultiUdpServer
{DatagramSocket socket=null;
BufferedReader in=null;
boolean moreQuotes=true;
public void serverWork() throws IOException
{socket=new DatagramSocket(3335);//創建端口号为3335的数据报套接字
in=new BufferedReader(new FileReader("bbb.txt"));
while(moreQuotes)
{byte buf[]=new byte[256]; //创建缓冲区
DatagramPacket packet; //创建发送数据报对象
String dString=null;//下面程序读取bbb.txt文件中一句英文并将它们存储在dString中
if((dString=in.readLine())==null)
{in.close();
moreQuotes=false;
dString="No more sentence. Bye!";}
buf=dString.getBytes();
InetAddress group=InetAddress.getByName("228.7.8.9");//多播组地址
packet=new DatagramPacket(buf,buf.length,group,3336);
// 构造要发送的数据报,并绑定主机地址和端口
socket.send(packet);//发送数据报
try{Thread.sleep(5000);}
catch(InterruptedException e){} //间隔5秒广播}
socket.close(); //关闭Socket}
public static void main(String args[])
{MultiUdpServer server=new MultiUdpServer();
try
{server.serverWork();}catch(IOException e){}}}
4.2 客户器端程序
import java.io.*;
import java.net.*;
public class MultiUdpClient
{public static void main(String args[]) throws IOException
{MulticastSocket socket=new MulticastSocket(3336);
//创建多播组套接字,绑定端口
InetAddress group=InetAddress.getByName("228.7.8.9"); // 绑定IP地址
socket.joinGroup(group); // 加入多播组
String bye="No more sentence.Bye!";
DatagramPacket packet;//创建数据报对象
for(int i=0;i<5; i++)
{byte buf[]=new byte[256]; // 创建缓冲区
packet=new DatagramPacket(buf,buf.length); //创建要接收的数据报对象
socket.receive(packet);// 从服务器端获取数据报
String received=new String(packet.getData());
//将数据报中的数据转换为字串并输出
System.out.println("The sentence send by the server:\n"+received);
if(received.substring(0,23).equals(bye)) // 没有数据可接收,退出循环
{break;}}
socket.leaveGroup(group);//退出多播组
socket.close(); //关闭套接字}}
服务器端程序和客户端程序运行顺序可不定,但客户端程序运行时服务器程序必须还在向外发送数据报。客户端的MulticastSocket和服务器端的DatagramSocket必须绑定同一个端口,因为所有在多播组的客户端都要监听服务器端的数据报,不能使用非固定端口。
当服务器端程序运行时,客户端程序可随时加入,所有多播组的客户端都可收到服务器发送的数据;但客户端根据加入的顺序和时间,所收到的数据报的个数是不同的,后加入的收到的数据报少一些。当服务器端数据发送完毕,多播组的所有客户接收到所需数据,Socket就关闭。
5 结束语
UDP是TCP协议的一种替代协议,为IP上快速传输数据而设计,但UDP是可靠性无法得到保障的协议。但对于质量要求不是很高的网络应用程序,UDP是一个很好的选择。在Java中,可以利用DatagramSocket、DatagramPacket和MulticastSocket三个类可以完成高质量的数据报多播通讯。
参考文献:
[1]张孝祥. Java就业培训教程[M]. 北京:清华大学出版社,2003.
[2]刘正林. Java技术基础[M]. 武汉:华中科技大学出版社,2002.
[3]朱喜福, 林建民, 唐永新. Java语言程序设计[M]. 北京:人民邮电出版社,2004.
[4]印旻. Java与面向对象程序设计教程[M]. 北京:高等教育出版社,2002.
[5]Jonathan Knudsen, Patrick Niemeyer. Learning Java, 3rd Edition [M]. O'Reilly, 2005.
[6]Steven Haines, Steve Potts. Java? 2 Primer Plus. Sams Publishing, 2002.
本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。
关键词:Java;数据报;UDP;C/S;通讯
中图分类号:TP393文献标识码:A文章编号:1009-3044(2007)03-10669-01
1 引言
Java是一种可以编写跨平台应用软件的面向对象的程序设计语言。Java伴随着Internet的迅猛发展而发展,逐渐成为重要的网络编程语言。网络编程的目的就是指直接或间接地通过网络协议与其它计算机进行通讯,需要解决两个主要问题:一个是如何准确定位网络上的主机;另一个问题是找到主机后如何可靠有效地进行数据传输。在TCP/IP协议中IP层主要负责网络主机的定位,而TCP层提供面向应用的可靠的或非可靠的数据传输机制。
TCP/IP协议的名称中虽然只有TCP协议名,但是在TCP/IP的传输层同时存在TCP和UDP两个协议。这两个协议都可完成网络上从服务器到客户机的数据传输。
2 Socket、TCP和UDP
談及网络通讯,必定提到一个名词:Socket,中文是“套接字”。网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接,它是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。不管使用TCP还是UDP协议传输数据,都要用到Socket。
TCP是传输控制协议,是Transfer Control Protocol的简称,是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方的成对的两个Socket之间必须建立连接,以便在TCP协议的基础上进行通信。
UDP是用户数据报协议,是User Datagram Protocol的简称,是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址和目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。
TCP的传输是可靠的,而UDP的传输是不可靠的。为什么我们还要用UDP在网络上传输数据呢?因为保证数据的可靠传输是需要付出代价的,对数据内容正确性的检验必然占用计算机的处理时间和网络的带宽,所以UDP的传输效率比TCP要高一些;而且许多应用中并不需要保证严格的传输可靠性,比如视频会议系统,网络游戏,需要实时的交互,但并不要求音频视频的绝对正确。
3 数据报多播通讯方式
数据报(Datagram)就跟日常生活中的邮件系统一样,是不能保证每一封信都能可靠地寄到目的地。Java在java.net包是提供了三个类:DatagramSocket、DatagramPacket和MulticastSocket用来支持数据报多播通信。
3.1 DatagramSocket
DatagramSocket用于程序之间建立传送数据报的通信连接,是数据报通信中的Socket。在数据报实现C/S(Client/Server,客户机/服务器)通信程序时,无论在客户端还是服务器端,都要首先建立一个DatagramSocket对象,用来表示数据报通信的端点,应用程序通过Socket接收或发送数据报。
DatagramSocket的构造方法如下:
(1)DatagramSocket( ):与本机任何可用端口绑定
(2)DatagramSocket(int port):与指定端口绑定
(3)DatagramSocket(int port, InetAddress laddr):与指定本地地址的指定端口绑定
其中,laddr指明一个可用的本地地址,可用IP地址;port指明Socket所使用的端口号。在选择端口时必须小心。每一个端口提供一种特定的服务,只有给出正确的端口,才能获得相应的服务。0~1023的端口号为系统所保留,所以在选择端口号时,最好选择一个大于1023的数防止发生冲突。如果发生端口的冲突,会生成SocketException类异常。所以上述3个构造方法都声明抛出非运行时异常SocketException,程序中必须进行异常处理,或者捕获、或者声明抛出。
3.2 DatagramPacket
DatagramPacket用来表示一个数据报,它是传输数据的载体,封装了数据、数据长度、数据报地址等信息。DatagramPacket类的构造方法可以用来构造两种用途的数据报:接收外来数据的数据报和向外发送的数据报。构造方法如下:
(1)DatagramPacket(byte buf[],int length);
构造用来接收长度为length的数据报,字节数组buf存放数据报数据,length必须小于buf的长度。
(2)DatagramPacket(byte buf[], int length, InetAddress addr, int port);
构造用于发送指定长度的数据报,发送到指定主机的指定端口。
(3)DatagramPacket(byte[]buf, int offset, int length);
构造用来接收长度为length的数据报,并指定数据报在缓冲区buf中的偏移量offset。
(4)DatagramPacket(byte[]buf, int offset, int length, InetAddress address, int port);
构造用于发送指定长度的数据报,发送到指定主机的指定端口,并指定数据报的数据在缓冲区buf中的偏移量offset。
3.3 MulticastSocket
用于客户端接收服务器端发送的广播数据报。需要先创建多播数据报,并加入一个多播组。一个多播组由一个D类IP地址指定。D类IP地址的范围是:224.0.0.0~239.255.255.255,其中224.0.0.0是保留地址,不能使用。要加入到多播组,需要创建一个MulticastSocket并绑定到指定端口,然后调用该Socket的joinGroup(InetAddress groupAddr)方法。
4 数据报多播通信实例
采用数据报通信方式实现Client/Server的通信程序。程序由客户端和服务器端两部分组成。服务器端主机中有一个名为“bbb.txt”文件,文件中保存了一段英文。服务器端发送数据报的目的主机地址与端口固定为多播组地址。客户端从这个固定的主要地址和端口监听是否有数据报,如有则获取并显示数据。
4.1 服务器端程序
import java.io.*;
import java.net.*;
public class MultiUdpServer
{DatagramSocket socket=null;
BufferedReader in=null;
boolean moreQuotes=true;
public void serverWork() throws IOException
{socket=new DatagramSocket(3335);//創建端口号为3335的数据报套接字
in=new BufferedReader(new FileReader("bbb.txt"));
while(moreQuotes)
{byte buf[]=new byte[256]; //创建缓冲区
DatagramPacket packet; //创建发送数据报对象
String dString=null;//下面程序读取bbb.txt文件中一句英文并将它们存储在dString中
if((dString=in.readLine())==null)
{in.close();
moreQuotes=false;
dString="No more sentence. Bye!";}
buf=dString.getBytes();
InetAddress group=InetAddress.getByName("228.7.8.9");//多播组地址
packet=new DatagramPacket(buf,buf.length,group,3336);
// 构造要发送的数据报,并绑定主机地址和端口
socket.send(packet);//发送数据报
try{Thread.sleep(5000);}
catch(InterruptedException e){} //间隔5秒广播}
socket.close(); //关闭Socket}
public static void main(String args[])
{MultiUdpServer server=new MultiUdpServer();
try
{server.serverWork();}catch(IOException e){}}}
4.2 客户器端程序
import java.io.*;
import java.net.*;
public class MultiUdpClient
{public static void main(String args[]) throws IOException
{MulticastSocket socket=new MulticastSocket(3336);
//创建多播组套接字,绑定端口
InetAddress group=InetAddress.getByName("228.7.8.9"); // 绑定IP地址
socket.joinGroup(group); // 加入多播组
String bye="No more sentence.Bye!";
DatagramPacket packet;//创建数据报对象
for(int i=0;i<5; i++)
{byte buf[]=new byte[256]; // 创建缓冲区
packet=new DatagramPacket(buf,buf.length); //创建要接收的数据报对象
socket.receive(packet);// 从服务器端获取数据报
String received=new String(packet.getData());
//将数据报中的数据转换为字串并输出
System.out.println("The sentence send by the server:\n"+received);
if(received.substring(0,23).equals(bye)) // 没有数据可接收,退出循环
{break;}}
socket.leaveGroup(group);//退出多播组
socket.close(); //关闭套接字}}
服务器端程序和客户端程序运行顺序可不定,但客户端程序运行时服务器程序必须还在向外发送数据报。客户端的MulticastSocket和服务器端的DatagramSocket必须绑定同一个端口,因为所有在多播组的客户端都要监听服务器端的数据报,不能使用非固定端口。
当服务器端程序运行时,客户端程序可随时加入,所有多播组的客户端都可收到服务器发送的数据;但客户端根据加入的顺序和时间,所收到的数据报的个数是不同的,后加入的收到的数据报少一些。当服务器端数据发送完毕,多播组的所有客户接收到所需数据,Socket就关闭。
5 结束语
UDP是TCP协议的一种替代协议,为IP上快速传输数据而设计,但UDP是可靠性无法得到保障的协议。但对于质量要求不是很高的网络应用程序,UDP是一个很好的选择。在Java中,可以利用DatagramSocket、DatagramPacket和MulticastSocket三个类可以完成高质量的数据报多播通讯。
参考文献:
[1]张孝祥. Java就业培训教程[M]. 北京:清华大学出版社,2003.
[2]刘正林. Java技术基础[M]. 武汉:华中科技大学出版社,2002.
[3]朱喜福, 林建民, 唐永新. Java语言程序设计[M]. 北京:人民邮电出版社,2004.
[4]印旻. Java与面向对象程序设计教程[M]. 北京:高等教育出版社,2002.
[5]Jonathan Knudsen, Patrick Niemeyer. Learning Java, 3rd Edition [M]. O'Reilly, 2005.
[6]Steven Haines, Steve Potts. Java? 2 Primer Plus. Sams Publishing, 2002.
本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。