1.UDP定义
????? UDP也叫用户数据协议【无连接的协议】
????? 优点:不能保证数据的安全与可靠
????? 缺点:消耗小,效率高
2.基于UDP的网络通讯程序需要的类和方法
????? 基于UDP的网络通讯程序是不区分客户端和服务器。
(1)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() 返回发送数据报的远程主机上的端口号,或从中接收数据报的端口号。【得到发送方的端口号】
(2)java.net.DatagramSocket【负责包的发送和包的接收】
此类表示用于发送和接收数据报数据包的套接字。
????? 构造方法:
????? DatagramSocket() 构造数据报套接字并将其绑定到本地主机上的任何可用端口。【发包】
????? DatagramSocket(int?port) 构造数据报套接字并将其绑定到本地主机上的指定端口。【收包】
????? 实例方法:
????? void???? send(DatagramPacket?p) 从此套接字发送数据报包。
????? void???? receive(DatagramPacket?p) 从此套接字接收数据报包。
????? void???? close() 关闭此数据报套接字。
3. 基于UDP协议的通信程序创建步骤
????? (1)发送方:
- 将需要发送的数据通过DatagramPacket(byte[]?buf, int?length, InetAddress?address, int?port) 构造方法打包好。
- 通过DatagramSocket()的构造方法创建DatagramSocket对象。
- DatagramSocket对象的send方法将打包好的数据报包,发送。
- 关闭DatagramSocket。
????? (2)接收方:
- 通过DatagramSocket(int?port)创建接收数据的DatagramSocket对象。
- 通过DatagramPacket(byte[]?buf, int?length) 创建一个空的数据报包。
- 通过调用接收数据的DatagramSocket对象的receive方法接收数据报包到空的数据报包。
- 解析数据报包。
- 关闭DatagramSocket。
4.代码演示
4.1客户端发,服务器收
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class ClientSendMain {??
?? public static void main(String[] args) throws Exception{
????? //定义数据报包
????? DatagramPacket sendpacket=null;
????? InetAddress receiveaddress=null;
????? int port=3000;
????? BufferedReader buff=null;
????? DatagramSocket sendsocket=null;
????? /*
????? ?* 创建发送的包---数据打包----发送
????? ?*/
????? //键盘输入数据----准备发送的数据
????? System.out.println("请输入需要发送的数据:");
????? buff=new BufferedReader(new InputStreamReader(System.in));
????? String info = buff.readLine();
????? byte[] bytes = info.getBytes();
????? int length=bytes.length;
????? //本机地址
????? receiveaddress=InetAddress.getLocalHost();
????? //创建带有服务器地址和端口号的发送包
????? sendpacket=new DatagramPacket(bytes, length, receiveaddress, port);
????? //创建DatagramSocket对象
????? sendsocket=new DatagramSocket();
????? sendsocket.send(sendpacket);
????? sendsocket.close();
?? }
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class ServerMain {
?? public static void main(String[] args) throws Exception {
????? /*
????? ?* 创建接收对象---创建接收用的空的数据报包-----解析
????? ?*/
???
????? //创建接收包的对象
????? int port=3000;
????? DatagramSocket receivesocket = new DatagramSocket(port);
????? //创建空的数据报包??
????? byte buff[]=new byte[1024];
????? DatagramPacket receivepacket = new DatagramPacket(buff, buff.length);
????? //接收数据
????? receivesocket.receive(receivepacket);
????? //解析数据
????? byte data[] = receivepacket.getData();
????? int len=receivepacket.getLength();
????? String msg=new String(data,0,len);
????? String clientip = receivepacket.getAddress().getHostAddress();
????? int clientsendport = receivepacket.getPort();
????? System.out.println("接收到来自"+clientip+":"+clientsendport+"的消息:"+msg);
????? receivesocket.close();
?? }
}
4.2 客户端持续发,服务器持续收
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class ClientSendMain {
?? public static void main(String[] args) throws Exception {
????? BufferedReader buff = null;
????? InetAddress receiveaddress = null;
????? int serverport = 3000;
????? DatagramPacket sendpacket = null;
????? DatagramSocket sendsocket = null;
????? buff = new BufferedReader(new InputStreamReader(System.in));
????? sendsocket = new DatagramSocket();
????? receiveaddress = InetAddress.getLocalHost();
????? boolean flag = true;
????? while (flag) {
????????? System.out.println("请输入需要发送的数据:");
????????? String sendinfo = buff.readLine();??????
????????? sendpacket = new DatagramPacket(sendinfo.getBytes(), sendinfo.getBytes().length, receiveaddress,
??????????????? serverport);
????????? sendsocket.send(sendpacket);
????????? if (sendinfo.equals("exit")) {
???????????? flag=false;
????????? }
????? }
????? sendsocket.close();
?? }
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class ServerMain {
?? public static void main(String[] args) throws Exception {
????? DatagramSocket receivesocket = null;
????? DatagramPacket receivepacket = null;
????? String receivemsg = null;
????? int serverport = 3000;
????? String clientip = null;
????? int clientsendport = 0;
????? boolean flag = true;
?????
????? receivesocket = new DatagramSocket(serverport);
????? byte buff[] = new byte[1024];
????? receivepacket = new DatagramPacket(buff, buff.length);
?????
????? while (flag) {?
????????? receivesocket.receive(receivepacket);
????????? byte data[] = receivepacket.getData();
????????? int len = receivepacket.getLength();
????????? receivemsg = new String(data, 0, len);
????????? clientip = receivepacket.getAddress().getHostAddress();
????????? clientsendport = receivepacket.getPort();
????????? System.out.println("服务器接收到来自" + clientip + ":" + clientsendport + "的消息:" + receivemsg);
????????? if(receivemsg.equals("exit")){
???????????? flag=false;
????????? }
????? }
????? receivesocket.close();
?? }
}
4.3双向-客户端持续发和收,服务器持续收和发
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class ClientSendMain {
?? public static void main(String[] args) throws Exception {
????? //客户端发,需要的变量和对象
????? BufferedReader buff = null;
????? InetAddress receiveaddress = null;
????? int serverport = 3000;
????? DatagramPacket sendpacket = null;
????? DatagramSocket sendsocket = null;????
????? buff = new BufferedReader(new InputStreamReader(System.in));
????? sendsocket = new DatagramSocket();
????? receiveaddress = InetAddress.getLocalHost();
?????
????? //客户端收,需要的变量和对象
????? DatagramPacket receivepacket=null;
????? DatagramSocket receivesocket=null;
????? int receiveport=2000;
????? receivesocket=new DatagramSocket(receiveport);
????? byte bys[]=new byte[1024];
????? receivepacket=new DatagramPacket(bys,bys.length);
?????
????? boolean flag = true;
????? while (flag) {
????????? //发
????????? System.out.println("请输入需要发送的数据:");
????????? String sendinfo = buff.readLine();??????
????????? sendpacket = new DatagramPacket(sendinfo.getBytes(), sendinfo.getBytes().length, receiveaddress,
??????????????? serverport);
????????? sendsocket.send(sendpacket);
?????????
????????? //收
????????? receivesocket.receive(receivepacket);???????
????????? String receivemsg = new String( receivepacket.getData(), 0, receivepacket.getLength());
????????? System.out.println("收到来自服务器返回的数据---"+receivemsg);
?????????????
????????? if (receivemsg.equals("exit")) {
???????????? flag=false;
????????? }
????? }
????? sendsocket.close();
????? receivesocket.close();
?? }
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class ServerMain {
?? public static void main(String[] args) throws Exception {
????? System.out.println("服务器已启动....");
?????
????? //服务器收
????? DatagramSocket receivesocket = null;
????? DatagramPacket receivepacket = null;
????? int serverport = 3000;
????? receivesocket = new DatagramSocket(serverport);
????? byte buff[] = new byte[1024];
????? receivepacket = new DatagramPacket(buff, buff.length);
?????
????? //服务器发
????? DatagramPacket sendpacket = null;
????? DatagramSocket sendsocket = null;
????? int sendport=2000;
????? InetAddress receiveaddress = InetAddress.getLocalHost();
????? sendsocket=new DatagramSocket();
?????
????? boolean flag = true;
????? while (flag) {?
????????? //收
????????? receivesocket.receive(receivepacket);
????????? byte data[] = receivepacket.getData();
????????? int len = receivepacket.getLength();
????????? String receivemsg = new String(data, 0, len);
????????? String clientip = receivepacket.getAddress().getHostAddress();
????????? int clientsendport = receivepacket.getPort();
????????? System.out.println("服务器接收到来自" + clientip + ":" + clientsendport + "的消息:" + receivemsg);
?????????
????????? //发
????????? sendpacket=new DatagramPacket(receivemsg.getBytes(),receivemsg.getBytes().length,receiveaddress,sendport);
????????? sendsocket.send(sendpacket);
?????????
?????????
????????? if(receivemsg.equals("exit")){
???????????? flag=false;
????????? }
????? }
????? sendsocket.close();
????? receivesocket.close();
?????
?? }
}
?
4.4 多个客户端持续发和收,服务器持续发和收
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;
/**
?* 发送数据的客户端
?*/
public class Client {
?? public static void main(String[] args) throws Exception {
????? BufferedReader buff = new BufferedReader(new InputStreamReader(System.in));
?? ?? //绑定一个指定的端口用于接收数据和发送数据
????? DatagramSocket server=new DatagramSocket();
????? //定义接收数据的空包
????? byte[] sbyte=new byte[1024];
?????? DatagramPacket spack=new DatagramPacket(sbyte, sbyte.length);
????? //定义持续控制发送的循环变量
????? boolean flag=true;
????? while (flag) {
????????? System.out.println("请输入要发送的数据:");
????????? String info=buff.readLine();
????????? //打包数据
????????? byte[] fbyte=info.getBytes();
????????? DatagramPacket fpack=new DatagramPacket(fbyte, fbyte.length, InetAddress.getLocalHost(), 3000);????????
????????? //发送数据
????????? server.send(fpack);
????????? //判断退出
????????? if (info.equals("886")) {
???????????? flag=false;
???????????? System.out.println("关闭客户端!");
????????? }else{
???????????? //接收数据
???????????? server.receive(spack);
???????????? //拆包
???????????? byte data[]=spack.getData();
???????????? String msg=new String(data,0,spack.getLength());
???????????? System.out.println("接收到服务器返回的数据是:"+msg);
????????? }
????? }????
????? server.close();
?? }
}
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/**
?* 接收数据的服务器端
?*/
public class Server {
????? public static void main(String[] args) throws Exception {
???????????? //绑定接收数据的端口
???????????? DatagramSocket server=new DatagramSocket(3000);
???????????? System.out.println("----》服务器端已经启动,等待客户端发送数据");
???????????? byte[] bytes = new byte[1024];
???????????? while(true){
???????????? DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
??????????
???????????? server.receive(packet);
???????????? ClientThread clientThread=new ClientThread(server,packet);
???????????? Thread th=new Thread(clientThread);????????????
???????????? th.start();
?????????????????? }
??????????????? }
}
/**
?* 用户发送数据线程类
?*/
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class ClientThread implements Runnable{
????? private DatagramSocket server;
????? private DatagramPacket datagramPacket;
????? private? boolean falg=true;
????? public ClientThread(DatagramSocket server,DatagramPacket datagramPacket ) {
????????? this.server=server;
????????? this.datagramPacket=datagramPacket;
????? }
?????
???????? public void run() {
????????? ?
???? try{
???????? ? while(falg){????????????
???????????? //拆包
???????????? byte data[]=datagramPacket.getData();
???????????? int len=datagramPacket.getLength();
???????????? String info=new String(data,0,len);
???????????? String clientip = datagramPacket.getAddress().getHostAddress();
???????????? int clientsendport = datagramPacket.getPort();
???????????? System.out.println("服务器接收到来自" + clientip + ":" + clientsendport + "的消息:" + info);
???????????? //判断退出
???????????? if (info.equals("886")) {
??????????????? falg=false;
??????????????? //server.close();
??????????????? System.out.println("客户端退出");
???????????? }else{
??????????????? //发送数据
??????????????? info="server:"+info;
??????????????? byte fbyte[]=info.getBytes();
??????????????? DatagramPacket fPacket=new DatagramPacket(fbyte, fbyte.length,datagramPacket.getAddress(),datagramPacket.getPort());
??????????????? server.send(fPacket);
??????????????? falg=false;
???????????? }???????????
????????? }
????????? //关闭
????????? }catch(Exception e){
???????????? e.printStackTrace();
????????? }?????????
????? }
}
?
?
?
|