您的位置:首页 > 理论基础 > 计算机网络

Java网络编程基础(三)---基于UDP编程

2016-05-23 15:15 615 查看
前面在介绍TCP/IP协议的时候我们已经提到,在TCP/IP协议的传输层除了TCP协议外还有一个UDP协议,相比UDP的应用不如TCP广泛,但是随着计算机网络的发展UDP协议正越来越显示出及其威力,尤其是在需要很强的实时交互性的场合,例如网络游戏和视频会议等,UDP更是显示出极强的威力。
UDP采用Datagram(数据报)传输,数据包是一种尽力而为的传送数据的方式,它只是 把数据的目的地记录在数据包中,然后就直接放在网络上,系统不保证数据是否能安全到达,或者什么时候可以送到,它并不保证传送质量。
Datagram(数据报)是网络层数据单元在介质上传输信息的一种逻辑分组格式,它是一种在网络中传播的、独立的、自身包含地址信息的消息,它能够到达目的地、到达时间、到达时内容是否会变化是不能准确知道的。它的通信双方不需要建立连接,对于一些不需要很高质量的应用程序来说,数据报通信是一个非常好的选择。还有就是对实时性很高的情况,比如在实时音频和视频应用中,数据包的丢失和位置是静态的,是可以被人们所忍受的,这时就可以利用UDP协议传输。
DatagramSocket(数据报套接字)工作包含了3个信息类:DatagramPacket、DatagramSocket和MulticastSocket。DatagramPacket对象描绘了数据报地址信息,DatagramSocket表示客户程序和服务程序报套接字,MulticastSocket描绘了能够进行多点传输的数据报套接字。
示例:利用数据报通信的Client/Server程序
(1)首先要建立数据报通信的Socket,我们可以通过创建一个DatagramSocket对象实现它
(2)创建一个数据报包,用来实现无连接的包传送服务。每个数据报包用DatagramPacket类创建,DatagramPacket对象封装了数据报包数据、包长度、目标地址和目标接口
(3)创建完DatagramSocket和DatagramPacket对象,就可以发送数据报包了。发送是通过调用DatagramSocket对象的send()方法实现的,它需要以DatagramPacket对象为参数,将刚才封装进DatagramPacket对象中的数据组成数据报发出。
(4)为了接收从服务器返回的结果数据报包,我们需要创建一个新的DatagramPacket对象,这就需要调用到DatagramPacket的另一个构造方式DatagramPacket(byte[] buffer,int length),即只需指明存放接收的数据报的缓存区和长度。调用DatagramSocket对象的receive()方法完成接收数据报的工作,此时需要将上面创建的DatagramPacket对象作为参数,该方法会一直阻塞,直到收到一个数据报包,
(5)处理接收缓存区内的数据,获取服务结果
(6)当通信完成后,可以使用DatagramSocket对象的close()方法关闭数据报通信Socket。
下面给出一个简单的利用数据报通信的服务器程序和客户端程序,它只能完成与服务器简单的通信。
a、服务器端程序
package org.test.socket.server;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

/**
* @author Administrator
*
*/
public class UDPServer {
public static void main(String[] args) {
try {
//创建Socket
DatagramSocket socket = new DatagramSocket(12345);
//创建接收包
byte[] buf = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(buf, buf.length);
System.out.println("开始接收包....");

//循环监听
while(true){
socket.receive(receivePacket);
String name = receivePacket.getAddress().toString();
System.out.println("来自主机:"+ name + "\n端口:"
+receivePacket.getPort());
String s = new String(receivePacket.getData(),0,receivePacket.getLength());
System.out.println("接收到数据:"+s);
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
b、客户端程序
package org.test.socket;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class UDPClient {

public static void main(String[] args) {
try {
// 创建Socket
DatagramSocket socket = new DatagramSocket();

//创建发送包
InetAddress host = InetAddress.getByName("localhost");
String msg = "hello,I'm client";
DatagramPacket sendPacket = new DatagramPacket(msg.getBytes(), msg.length(),host,12345);

//发送数据
socket.send(sendPacket);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}
c、运行结果:
开始接收包....
来自主机:/127.0.0.1
端口:51240
接收到数据:hello,I'm client
d、这只是演示udp通信方式,以上方式也可改为双方通信

组播套接字MulticastSocket
DatagramSocket只允许数据报发送一个目的地址,MulticastSocket允许数据报以广播的形式发送到该端口的所有客户。
多播数据报套接字用于发送和接收IP多播包。MulticastSocket是一种DatagramSocket,它具有加入Internet上其他多播主机的组的附加功能。
组播套接字和Client/Server程序
服务器端程序。
package org.test.socket.server;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;

public class MultiServer {

public static void main(String[] args) {
try {
// TODO 创建Socket
MulticastSocket socket = new MulticastSocket(12345);
InetAddress group = InetAddress.getByName("231.0.0.0");
socket.joinGroup(group);

//接收数据报
for(int i = 0;i<100;i++){
byte[] buf = new byte[256];
DatagramPacket receivePacket = new DatagramPacket(buf, buf.length);
socket.receive(receivePacket);

//去除空格
byte[] buf2 = new byte[receivePacket.getLength()];
System.arraycopy(receivePacket.getData(), 0, buf2, 0, receivePacket.getLength());
System.out.println(new String(buf2));
}
//删除组播地址
socket.leaveGroup(group);
socket.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}
客户端程序
package org.test.socket;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;

public class MultiClient {

public static void main(String[] args) {
try {
// 创建Socket
MulticastSocket socket = new MulticastSocket();
InetAddress group = InetAddress.getByName("231.0.0.0");

//创建发送数据包
byte[] buf = new byte[0];
DatagramPacket sendPacket = new DatagramPacket(buf, 0, group, 12345);

//发送数据
for(int i = 0;i < 5;i ++){
byte[] buf1 = ("Data line" + i).getBytes();
sendPacket.setData(buf1);
sendPacket.setLength(buf1.length);
socket.send(sendPacket);
}
socket.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java UDP 网络编程