1.单向通信

Client.java

/*
* 客户端:
* 1.创建DatagramSocket实例(一般不指定端口,而是使用动态端口)
* 2.创建用于发送数据报的非空的数据报DatagramPacket
* 3.调用DatagramSocket的send()方法发送数据报
* 4.发送完成后关闭DatagramSocket,一般用close()方法或者同try语句的自动关闭功能
*   本程序使用try语句的自动关闭功能
*/
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Scanner;
import java.io.IOException;
import java.net.SocketException;
public class Client{
	final static int SERVER_PORT = 2013;  //定义服务器端口(即数据报发往的端口)
	final static int PACKET_SIZE = 1024 * 4; //定义Packet大小
	public static void main(String[] args){
		try(
			//创建DatagramSocket实例(一般不指定端口,而是使用动态端口)
			DatagramSocket clientDatagramSocket = new DatagramSocket();
			//获得键盘输入
			Scanner scanner = new Scanner(System.in);

		){
			while(scanner.hasNextLine()){//等待输入
				String content = scanner.nextLine();

				//创建用于发送数据报的非空的数据报DatagramPacket
				//构造器:DatagramPacket(byte[] buf, int length, InetAddress address, int port)
				//Constructs a datagram packet for sending packets of length length to the specified port number on the specified host.
				//*注意InetAddress的用法*
				//public static InetAddress getByAddress(byte[] addr) throws UnknownHostException
				//Returns an InetAddress object given the raw IP address

				DatagramPacket sendPacket = new DatagramPacket(content.getBytes(), content.getBytes().length, 
					InetAddress.getByAddress(new byte[]{(byte)202,(byte)197,(byte)145,(byte)88}), SERVER_PORT);
				
				//调用DatagramSocket的send()方法发送数据报
				clientDatagramSocket.send(sendPacket); 
			}
			
		}
		catch(UnknownHostException ex){
			ex.printStackTrace();
		}
		catch(SocketException ex){
			ex.printStackTrace();
		}
		catch(IOException ex){
			ex.printStackTrace();
		}
	}
}

Server.java

/*
* 服务端:
* 1.创建有固定IP、规定端口的DatagramSocket实例
* 2.创建用于接收客户端的数据报的空的数据报DatagramPacket
* 3.调用DatagramSocket的receive()方法接收数据报
* 4.接收完成后关闭DatagramSocket,一般用close()方法或者同try语句的自动关闭功能
*   本程序使用try语句的自动关闭功能。
*/
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.io.IOException;
public class Server{
	final static int SERVER_PORT = 2013;  //定义服务器端口(服务器的接收端口)
	final static int PACKET_SIZE = 1024 * 4; //定义Packet大小
	public static void main(String[] args){
		try(
			//try语句的自动关闭
			//创建有固定IP、规定端口的DatagramSocket实例
			//构造器:public DatagramSocket(int port) throws SocketException
			DatagramSocket serverDatagramSocket = new DatagramSocket(SERVER_PORT);
		){
			while(true){ //Server一直开启


				//创建用于接收客户端的数据报的空的数据报DatagramPacket
				//构造器:DatagramPacket(byte[] buf, int length)
				//Constructs a DatagramPacket for receiving packets of length length.
				DatagramPacket serverPacket = new DatagramPacket(new byte[PACKET_SIZE],PACKET_SIZE);


				//用DatagramSocket的receive()方法接收数据报
				//public void receive(DatagramPacket p) throws IOException
				serverDatagramSocket.receive(serverPacket);


				/*****************至此接收完成*****************/


				/*****************下面是接收之后的处理*********/
				//将packet中字节数组转换为字符串,然后输出
				System.out.println(new String(serverPacket.getData(),0,serverPacket.getLength()));




			}
			
		}
		catch(SocketException ex){
			ex.printStackTrace();
		}
		catch(IOException ex){
			ex.printStackTrace();
		}
	}
}

2.双向通信

Client.java

/*
* 客户端:
* 1.创建DatagramSocket实例(一般不指定端口,而是使用动态端口)
* 2.创建用于发送数据报的非空的数据报DatagramPacket
* 3.调用DatagramSocket的send()方法发送数据报
* 4.发送完成后关闭DatagramSocket,一般用close()方法或者同try语句的自动关闭功能
*   本程序使用try语句的自动关闭功能
*/
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Scanner;
import java.io.IOException;
import java.net.SocketException;
public class Client{
	final static int SERVER_PORT = 2013;  //定义服务器端口(即数据报发往的端口)
	final static int PACKET_SIZE = 1024 * 4; //定义Packet大小
	public static void main(String[] args){
		try(
			//创建DatagramSocket实例(一般不指定端口,而是使用动态端口)
			DatagramSocket clientDatagramSocket = new DatagramSocket();
			//获得键盘输入
			Scanner scanner = new Scanner(System.in);

		){
			while(scanner.hasNextLine()){//等待输入

				String content = scanner.nextLine();

				//创建用于发送数据报的非空的数据报DatagramPacket
				//构造器:DatagramPacket(byte[] buf, int length, InetAddress address, int port)
				//Constructs a datagram packet for sending packets of length length to the specified port number on the specified host.
				//*注意InetAddress的用法*
				//public static InetAddress getByAddress(byte[] addr) throws UnknownHostException
				//Returns an InetAddress object given the raw IP address

				DatagramPacket sendToServerPacket = new DatagramPacket(content.getBytes(), content.getBytes().length, 
					InetAddress.getByAddress(new byte[]{(byte)202,(byte)197,(byte)145,(byte)88}), SERVER_PORT);
				
				//调用DatagramSocket的send()方法发送数据报
				clientDatagramSocket.send(sendToServerPacket); 

				/**************已上是客户端的发送************/

				/**************下面是客户端的接收************/
				//创建用于接收客户端的数据报的空的数据报DatagramPacket
				//构造器:DatagramPacket(byte[] buf, int length)
				//Constructs a DatagramPacket for receiving packets of length length.
				DatagramPacket receiveFromServerPacket = new DatagramPacket(new byte[PACKET_SIZE],PACKET_SIZE);

				//用DatagramSocket的receive()方法接收数据报
				//public void receive(DatagramPacket p) throws IOException
				clientDatagramSocket.receive(receiveFromServerPacket);

				/*****************至此接收完成*****************/

				/*****************下面是接收之后的处理*********/
				//将packet中字节数组转换为字符串,然后输出
				System.out.println(new String(receiveFromServerPacket.getData(),0,receiveFromServerPacket.getLength()));
				}
			
		}
		catch(UnknownHostException ex){
			ex.printStackTrace();
		}
		catch(SocketException ex){
			ex.printStackTrace();
		}
		catch(IOException ex){
			ex.printStackTrace();
		}
	}
}

Server.java

/*
* 服务端:
* 1.创建有固定IP、规定端口的DatagramSocket实例
* 2.创建用于接收客户端的数据报的空的数据报DatagramPacket
* 3.调用DatagramSocket的receive()方法接收数据报
* 4.接收完成后关闭DatagramSocket,一般用close()方法或者同try语句的自动关闭功能
*   本程序使用try语句的自动关闭功能。
*/
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.io.IOException;
import java.util.Random;
public class Server{
	final static int SERVER_PORT = 2013;  //定义服务器端口(服务器的接收端口)
	final static int PACKET_SIZE = 1024 * 4; //定义Packet大小

	private static String[] answers = {"AnswerOne","AnswerTwo","AnswerThree","AnswerFour"};//预定义服务器应答语句

	public static void main(String[] args){
		try(
			//try语句的自动关闭
			//创建有固定IP、规定端口的DatagramSocket实例
			//构造器:public DatagramSocket(int port) throws SocketException
			DatagramSocket serverDatagramSocket = new DatagramSocket(SERVER_PORT);
		){
			while(true){ //Server一直开启

			//创建用于接收客户端的数据报的空的数据报DatagramPacket
			//构造器:DatagramPacket(byte[] buf, int length)
			//Constructs a DatagramPacket for receiving packets of length length.
			DatagramPacket receiveFromClientPacket = new DatagramPacket(new byte[PACKET_SIZE],PACKET_SIZE);

			//用DatagramSocket的receive()方法接收数据报
			//public void receive(DatagramPacket p) throws IOException
			serverDatagramSocket.receive(receiveFromClientPacket);

			/*****************至此接收完成*****************/

			/*****************下面是接收之后的处理*********/
			//将packet中字节数组转换为字符串,然后输出
			System.out.println(new String(receiveFromClientPacket.getData(),0,receiveFromClientPacket.getLength()));


			
			/***************服务器发送消息*****************/
			//随机应答
			int random = new Random().nextInt(answers.length);  //获得0~answers.length的随机整数
			//发送
			//DatagramPacket(byte[] buf, int length, SocketAddress address)
			//Constructs a datagram packet for sending packets of length length to the specified port number on the specified host.
			//public SocketAddress getSocketAddress()
			//Gets the SocketAddress (usually IP address + port number) of the remote host that this packet is being sent to or is coming from.
			//从接收到的数据报中获得客户端的SocketAddress
			DatagramPacket sendToClientPacket = new DatagramPacket(answers[random].getBytes(), answers[random].getBytes().length, 
					receiveFromClientPacket.getSocketAddress());
				
			//调用DatagramSocket的send()方法发送数据报
			serverDatagramSocket.send(sendToClientPacket); 

			}
			
		}
		catch(SocketException ex){
			ex.printStackTrace();
		}
		catch(IOException ex){
			ex.printStackTrace();
		}
	}
}