基于UDP协议的通信程序

一、什么是UDP,它的缺点是什么?

UDP:用户数据报协议[无连接的协议]
缺点:不能保证数据的安全与可靠。
优点:消耗小,效率高

 二、建立基于UDP的网络通讯程序需要使用的类和常用方法

基于UDP的网络通讯程序是不区分客户端和服务器。
java.net.DatagramPacket---该类表示数据报包。【打包被发送的数据/接收发来的数据】
构造方法:
    DatagramPacket(byte[] buf, int length) 
    构造一个 DatagramPacket用于接收长度的数据包length。【接收发来的数据的数据包】
    DatagramPacket(byte[] buf, int length, InetAddress address, int port) 
    构造用于发送长度的分组的数据报包 length指定主机上到指定的端口号。
实例方法:
    byte[]    getData() 返回数据缓冲区。 
    int    getLength() 返回要发送的数据的长度或接收到的数据的长度。 
    InetAddress    getAddress() 返回该数据报发送或接收数据报的计算机的IP地址。
    int    getPort() 返回发送数据报的远程主机上的端口号,或从中接收数据报的端口号。 
UDP协议的通信程序创建步骤:
    发送方步骤:
    1.将需要发送的数据通过
      DatagramPacket(byte[] buf, int length, InetAddress address, int port) 构造方法打包好
    2.通过DatagramSocket()的构造方法创建DatagramSocket对象。
    3.DatagramSocket对象的send方法将打包好的数据报包,发送。
    4.关闭DatagramSocket。
    接收方步骤
    1.通过DatagramSocket(int port)创建接收数据的DatagramSocket对象。
    2.通过DatagramPacket(byte[] buf, int length) 创建一个空的数据报包。
    3.通过调用接收数据的DatagramSocket对象的receive方法接收数据报包到空的数据报包。
    4.解析数据报包
    5.关闭DatagramSocket
实例1:客户端向服务器发送数据,服务器接收客户端发送来的数据
发送端

package com.wangxing.test1;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPsend {
	public static void main(String[] args) throws Exception{
		BufferedReader bufferedReader=null;
		int serverPort=3000;
		InetAddress address=null;
		byte data[]=null;
		//将需要发送的数据通过DatagramPacket对象的构造方法 DatagramPacket(byte[] buf, int length, InetAddress address, int port)
		DatagramPacket sendPackset=null;
		//通过DatagramSocket()的构造方法得到DatagramPacket对象
		DatagramSocket sendSocket=null;
		//从键盘得到发送的数据
		bufferedReader=new BufferedReader(new InputStreamReader(System.in));
		System.out.print("请输入要发送的内容:");
		data=bufferedReader.readLine().getBytes();
		address=address.getLocalHost();
		sendPackset=new DatagramPacket(data,data.length,address,serverPort);
		sendSocket=new DatagramSocket();
		//3.DatagramSocket对象的send方法将打包好的数据报包,发送。
		sendSocket.send(sendPackset);
		//4.关闭DatagramSocket。
		sendSocket.close();
	}
}

接收端:

package com.wangxing.test1;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPreceive {
	public static void main(String[] args) throws Exception{
		DatagramSocket receiveScoket=null;
		DatagramPacket receivepacket=null;
		int receivePort=3000;
		int len=0;
		byte data[]=new byte[1024];
		InetAddress localHost=null;
		int port;
		String info=null;
		//1.通过DatagramSocket(int port)创建接收数据的DatagramSocket对象。
		receiveScoket=new DatagramSocket(receivePort);
		System.out.println("接受端已经开启-------------------");
		//2.通过DatagramPacket(byte[] buf, int length) 创建一个空的数据报包。
		receivepacket=new DatagramPacket(data,data.length);
		//3.通过调用接收数据的DatagramSocket对象的receive方法接收数据报包到空的数据报包。
		receiveScoket.receive(receivepacket);
		//4.解析数据报包
		//得到数据报中解析的数据
		info=new String(receivepacket.getData());
		//得到数据报中解析的数据发送方的主机IP
		localHost=receivepacket.getAddress();
		//得到数据报中解析的数据发送方的发送数据程序的端口
		port=receivepacket.getPort();
		System.out.println("从"+localHost+":"+port+"上接受到的数据:"+info);
		//5.关闭DatagramSocket
		receiveScoket.close();
	}
}

基于UDP协议的通信程序_第1张图片

 

基于UDP协议的通信程序_第2张图片

实例2:客户端向服务器持续发送数据,服务器持续接收客户端发送来的数据
发送端
package com.wangxing.test2;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPsend {
	public static void main(String[] args) throws Exception{
		BufferedReader bufferedReader=null;
		int serverPort=3000;
		InetAddress address=null;
		//得到数据字符
		String datastr=null;
		byte data[]=null;
		//将需要发送的数据通过DatagramPacket对象的构造方法 DatagramPacket(byte[] buf, int length, InetAddress address, int port)
		DatagramPacket sendPackset=null;
		//通过DatagramSocket()的构造方法得到DatagramPacket对象
		DatagramSocket sendSocket=null;
		//从键盘得到发送的数据
		bufferedReader=new BufferedReader(new InputStreamReader(System.in));
		address=address.getLocalHost();
		sendSocket=new DatagramSocket();
		//判断持续执行的变量
		boolean flag=true;
		while(flag){
			System.out.print("请输入要发送的内容:");
			datastr=bufferedReader.readLine();
			data=datastr.getBytes();
			sendPackset=new DatagramPacket(data,data.length,address,serverPort);
			//3.DatagramSocket对象的send方法将打包好的数据报包,发送。
			sendSocket.send(sendPackset);
			if(datastr.equals("exit")){
				flag=false;
			}
		}
		//4.关闭DatagramSocket。
		sendSocket.close();
	}
}
接收端
 
package com.wangxing.test2;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPreceive {
	public static void main(String[] args) throws Exception{
		DatagramSocket receiveScoket=null;
		DatagramPacket receivepacket=null;
		int receivePort=3000;
		int len=0;
		byte data[]=new byte[1024];
		InetAddress localHost=null;
		int port;
		String info=null;
		//判断持续执行的变量
		boolean flag=true;
		//1.通过DatagramSocket(int port)创建接收数据的DatagramSocket对象。
		receiveScoket=new DatagramSocket(receivePort);
		System.out.println("接收端已经开启-------------------");
		//2.通过DatagramPacket(byte[] buf, int length) 创建一个空的数据报包。
		receivepacket=new DatagramPacket(data,data.length);
		while(flag){
			//3.通过调用接收数据的DatagramSocket对象的receive方法接收数据报包到空的数据报包。
			receiveScoket.receive(receivepacket);
			//4.解析数据报包
			//得到数据报中解析的数据
			info=new String(receivepacket.getData(),0,receivepacket.getLength());
			//得到数据报中解析的数据发送方的主机IP
			localHost=receivepacket.getAddress();
			//得到数据报中解析的数据发送方的发送数据程序的端口
			port=receivepacket.getPort();
			System.out.println("从"+localHost+":"+port+"上接受到的数据:"+info);
			if(info.equals("exit")){
				flag=false;
			}
		}
		
		//5.关闭DatagramSocket
		receiveScoket.close();
	}
}

基于UDP协议的通信程序_第3张图片

 

基于UDP协议的通信程序_第4张图片

实例3:创建发送端和客户端双向传输数据
 
package com.wangxing.test3;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPsend {
	public static void main(String[] args) throws Exception{
		BufferedReader bufferedReader=null;
		int serverPort=3000;
		InetAddress address=null;
		//得到数据字符
		String datastr=null;
		byte data[]=null;
		//将需要发送的数据通过DatagramPacket对象的构造方法 DatagramPacket(byte[] buf, int length, InetAddress address, int port)
		DatagramPacket sendPackset=null;
		DatagramPacket sendPackset2=null;
		//通过DatagramSocket()的构造方法得到DatagramPacket对象
		DatagramSocket sendSocket=null;
		//通过DatagramSocket(int port)创建接收数据的DatagramSocket对象。
		DatagramSocket sendSocket2=null;
		//创建接收发送方返回的端口号
		int receiveport=3001;
		//通过DatagramPacket(byte[] buf, int length) 创建一个空的数据报包。
		DatagramPacket senPack=null;
		//创建即将保存得到发送反返回数据的数组
		byte receiveData[]=new byte[1024];
		//创建返回数据字节数组
		byte reData[]=new byte[1024];
		//创建保存返回字节数组数据的字符串
		String receiveInfo=null;
		//从键盘得到发送的数据
		bufferedReader=new BufferedReader(new InputStreamReader(System.in));
		address=InetAddress.getLocalHost();
		sendSocket=new DatagramSocket();
		//接收返回的数据
		sendSocket2=new DatagramSocket(receiveport);
		//创建接收返回数据的心数据报包
		sendPackset2=new DatagramPacket(receiveData,receiveData.length);
		//判断持续执行的变量
		boolean flag=true;
		while(flag){
			System.out.print("请输入要发送的内容:");
			datastr=bufferedReader.readLine();
			data=datastr.getBytes();
			sendPackset=new DatagramPacket(data,data.length,address,serverPort);
			//3.DatagramSocket对象的send方法将打包好的数据报包,发送。
			sendSocket.send(sendPackset);
			//使用DatagramSocket对象的实例方法receive()接收数据报包
			sendSocket2.receive(sendPackset2);
			receiveData=sendPackset2.getData();
			receiveInfo=new String(receiveData,0,sendPackset2.getLength());
			System.out.println(receiveInfo);
			if(datastr.equals("exit")){
				flag=false;
			}
		}
		//4.关闭DatagramSocket。
		sendSocket.close();
        sendSocket2.close();
	}
}
package com.wangxing.test3;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPreceive {
	public static void main(String[] args) throws Exception{
		DatagramSocket receiveScoket=null;
		DatagramSocket receiveScoket2=null;
		DatagramPacket receivepacket2=null;
		DatagramPacket receivepacket=null;
		int receivePort=3000;
		int len=0;
		byte arr[]=new byte[1024];
		InetAddress localHost=null;
		//定义发送数据段程序的端口
		int port;
		//保存返回给发送端的端口
		int sendPort=3001;
		//创建得到数据的字节数组
		byte data[]=null;
		//创建的得到数据字符串
		String info=null;
		//得到返回数组的IP
		InetAddress receiveAddress=InetAddress.getLocalHost();
		//判断持续执行的变量
		boolean flag=true;
		//1.通过DatagramSocket(int port)创建接收数据的DatagramSocket对象。
		receiveScoket=new DatagramSocket(receivePort);
		//通过通过DatagramPacket(byte[] buf, int length)
		System.out.println("接收端已经开启-------------------");
		//2.通过DatagramPacket(byte[] buf, int length, InetAddress address, int port)
		receivepacket=new DatagramPacket(arr,arr.length);
		while(flag){
			//3.通过调用接收数据的DatagramSocket对象的receive方法接收数据报包到空的数据报包。
			receiveScoket.receive(receivepacket);
			//4.解析数据报包
			//得到数据报中解析的数据
			info=new String(receivepacket.getData(),0,receivepacket.getLength());
			//得到数据报中解析的数据发送方的主机IP
			localHost=receivepacket.getAddress();
			//得到数据报中解析的数据发送方的发送数据程序的端口
			port=receivepacket.getPort();
			System.out.println("从"+localHost+":"+port+"上接受到的数据:"+info);
			//得到数据后返回给发送方结果
			String xinxi="接收方返回---";
			data=(xinxi+info).getBytes();
			receivepacket2=new DatagramPacket(data,data.length,receiveAddress,sendPort);
			receiveScoket2=new DatagramSocket();
			receiveScoket2.send(receivepacket2);
			if(info.equals("exit")){
				flag=false;
			}
		}
		
		//5.关闭DatagramSocket
		receiveScoket.close();
		receiveScoket2.close();
	}
}

基于UDP协议的通信程序_第5张图片

 

基于UDP协议的通信程序_第6张图片

实例4:多个客户端端给一个服务端
客户端(主要得到发客户端的端口,因为客户端本身使用了自己的端口了,接收服务端返回值时需要打开自己接收数据的端口所以讲这个端口+1就可以了,和服务端向客户端的接收地址的端口一致就可以了)
package com.wangxing.test4;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPsend {
	public static void main(String[] args) throws Exception{
		BufferedReader bufferedReader=null;
		int serverPort=3000;
		InetAddress address=null;
		//得到数据字符
		String datastr=null;
		byte data[]=null;
		//将需要发送的数据通过DatagramPacket对象的构造方法 DatagramPacket(byte[] buf, int length, InetAddress address, int port)
		DatagramPacket sendPackset=null;
		DatagramPacket sendPackset2=null;
		//通过DatagramSocket()的构造方法得到DatagramPacket对象
		DatagramSocket sendSocket=null;
		//通过DatagramSocket(int port)创建接收数据的DatagramSocket对象。
		DatagramSocket sendSocket2=null;
		//通过DatagramPacket(byte[] buf, int length) 创建一个空的数据报包。
		DatagramPacket senPack=null;
		//创建即将保存得到发送反返回数据的数组
		byte receiveData[]=new byte[1024];
		//创建返回数据字节数组
		byte reData[]=new byte[1024];
		//创建保存返回字节数组数据的字符串
		String receiveInfo=null;
		//从键盘得到发送的数据
		bufferedReader=new BufferedReader(new InputStreamReader(System.in));
		address=InetAddress.getLocalHost();
		sendSocket=new DatagramSocket();
		int cilentPort=sendSocket.getLocalPort();
		System.out.print(cilentPort);
		//接收返回的数据打开发送方的端口
		sendSocket2=new DatagramSocket(cilentPort+1);
		//创建接收返回数据的心数据报包
		sendPackset2=new DatagramPacket(receiveData,receiveData.length);
		//判断持续执行的变量
		boolean flag=true;
		while(flag){
			System.out.print("请输入要发送的内容:");
			datastr=bufferedReader.readLine();
			data=datastr.getBytes();
			sendPackset=new DatagramPacket(data,data.length,address,serverPort);
			//3.DatagramSocket对象的send方法将打包好的数据报包,发送。
			sendSocket.send(sendPackset);
			//使用DatagramSocket对象的实例方法receive()接收数据报包
			sendSocket2.receive(sendPackset2);
			receiveData=sendPackset2.getData();
			receiveInfo=new String(receiveData,0,sendPackset2.getLength());
			System.out.println(receiveInfo);
			if(datastr.equals("exit")){
				flag=false;
			}
		}
		//4.关闭DatagramSocket。
		sendSocket.close();
		sendSocket2.close();
	}
}
服务端(服务端需要和客户端的调用的接收数据的端口一致)
package com.wangxing.test4;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPreceive {
	public static void main(String[] args) throws Exception{
		DatagramSocket receiveScoket=null;
		DatagramPacket receivepacket=null;
		int receivePort=3000;
		InetAddress receiveAddress =InetAddress.getLocalHost() ;
		int len=0;
		byte arr[]=new byte[1024];
		//1.通过DatagramSocket(int port)创建接收数据的DatagramSocket对象。
		receiveScoket=new DatagramSocket(receivePort);
		//通过通过DatagramPacket(byte[] buf, int length)
		System.out.println("接收端已经开启-------------------");
		//2.通过DatagramPacket(byte[] buf, int length, InetAddress address, int port)
		receivepacket=new DatagramPacket(arr,arr.length);
		ReceiveThread receiveThread=new ReceiveThread(receiveScoket, receivepacket, receiveAddress);
		Thread thread=new Thread(receiveThread);
		thread.start();
	}
}
创建服务端的线程
package com.wangxing.test4;

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

public class ReceiveThread implements Runnable {
	private DatagramSocket receiveScoket = null;
	private DatagramSocket receiveScoket2 = null;
	private DatagramPacket receivepacket2 = null;
	private DatagramPacket receivepacket = null;
	private InetAddress receiveAddress = null;
	private InetAddress localHost = null;
	// 定义发送数据段程序的端口
	private int port;
	// 创建得到数据的字节数组
	private byte data[] = null;
	// 创建的得到数据字符串
	private String info = null;
	// 判断持续执行的变量
	private boolean flag = true;

	public ReceiveThread(DatagramSocket receiveScoket, DatagramPacket receivepacket, InetAddress receiveAddress) {
		this.receiveScoket = receiveScoket;
		this.receivepacket = receivepacket;
		this.receiveAddress = receiveAddress;
	}

	@Override
	public void run() {
		try {
			while (flag) {
				// 3.通过调用接收数据的DatagramSocket对象的receive方法接收数据报包到空的数据报包。
				receiveScoket.receive(receivepacket);
				// 4.解析数据报包
				// 得到数据报中解析的数据
				info = new String(receivepacket.getData(), 0, receivepacket.getLength());
				// 得到数据报中解析的数据发送方的主机IP
				localHost = receivepacket.getAddress();
				// 得到数据报中解析的数据发送方的发送数据程序的端口
				port = receivepacket.getPort();
				System.out.println("从" + localHost + ":" + port + "上接受到的数据:" + info);
				// 得到数据后返回给发送方结果
				String xinxi = "接收方返回---";
				data = (xinxi + info).getBytes();
				receivepacket2 = new DatagramPacket(data, data.length, receiveAddress, port+1);
				receiveScoket2 = new DatagramSocket();
				receiveScoket2.send(receivepacket2);
				if (info.equals("exit")) {
					flag = false;
				}
			}
			//5.关闭DatagramSocket
			receiveScoket.close();
			receiveScoket2.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

基于UDP协议的通信程序_第7张图片

 

基于UDP协议的通信程序_第8张图片

 

基于UDP协议的通信程序_第9张图片

你可能感兴趣的:(java基础,udp)