11.8.什么是UDP,它的优缺点是什么?
UDP—>用户数据报协议
报—报文
优点:消耗小,效率高
缺点:不能保证数据的安全与可靠。
11.7.建立基于UDP的网络通讯程序需要使用的类和常用方法?
1.基于UDP的网络通讯程序是不区分客户端和服务器。
java.net Class DatagramPacket—该类表示数据报包。【打包被发送的数据/接收发来的数据】
构造方法
DatagramPacket(byte[] buf, int length) 构造一个 DatagramPacket用于接收长度的数据包 length 。 【接收发来的数据的数据包】
DatagramPacket(byte[] buf, int length, InetAddress address, int port) 构造用于发送长度的分组的数据报包 length指定主机上到指定的端口号。 【打包被发送的数据】
实例方法
java.net Class DatagramSocket 此类表示用于发送和接收数据报数据包的套接字。
【发包/收包】
构造方法
DatagramSocket() 构造数据报套接字并将其绑定到本地主机上的任何可用端口。【发包】
DatagramSocket(int port) 构造数据报套接字并将其绑定到本地主机上的指定端口。【收包】
实例方法
例如: 客户端向服务器发送数据,服务器接收客户端发送来的数据。
客户端向服务器发送数据
package com.lx.test1;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPClient {
public static void main(String[] args)throws Exception {
//定义服务器的ip对象
InetAddress serverip=null;
//定义服务器的端口号
int prot=3000;
//定义从控制台得到被发送数据的输入流对象
BufferedReader inputreader=null;
//定义保存被发送的数据变量
String info=null;
//定义打包数据用的数据包对象
DatagramPacket dabaopacket=null;
//定义发送数据包的客户端对象
DatagramSocket sendSocket=null;
//实例化服务器的ip对象
serverip=InetAddress.getLocalHost();
//实例化从控制台得到被发送数据的输入流对象
inputreader=new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入被发送的数据:");
info=inputreader.readLine();
//实例化打包数据用的数据包对象
dabaopacket=new DatagramPacket(info.getBytes(),info.getBytes().length,
serverip,prot);
//实例化发送数据包的客户端对象
sendSocket=new DatagramSocket();
//发送数据包
sendSocket.send(dabaopacket);
//关闭socket和输入流
sendSocket.close();
inputreader.close();
}
}
服务器接收客户端发送来的数据。
package com.lx.test1;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPServer {
public static void main(String[] args)throws Exception {
//定义服务器开放的端口号
int prot=3000;
//定义保存被接收的数据变量
String msg=null;
//定义接收数据用的数据包对象
DatagramPacket jieshoupacket=null;
//定义接收数据包的Socket对象
DatagramSocket jieshouSocket=null;
//实例化接收数据用的数据包对象
byte databyte[]=new byte[100];
jieshoupacket=new DatagramPacket(databyte,databyte.length);
//实例化接收数据包的Socket对象
jieshouSocket=new DatagramSocket(prot);
System.out.println("服务器已经启动,等待接收数据.....");
//接收数据包
jieshouSocket.receive(jieshoupacket);
//拆包
byte data[]=jieshoupacket.getData();
int len=jieshoupacket.getLength();
String clientip=jieshoupacket.getAddress().getHostAddress();
int outprot=jieshoupacket.getPort();
msg=new String(data,0,len);
System.out.println("今收到来自"+clientip+"的从"+outprot+
"端口发来的数据--"+msg);
//关闭socket
jieshouSocket.close();
}
}
例如: 客户端持续向服务器发送数据,服务器持续接收客户端发送来的数据。
package com.lx.test2;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPClient {
public static void main(String[] args)throws Exception {
//定义服务器的ip对象
InetAddress serverip=null;
//定义服务器的端口号
int prot=3000;
//定义从控制台得到被发送数据的输入流对象
BufferedReader inputreader=null;
//定义保存被发送的数据变量
String info=null;
//定义打包数据用的数据包对象
DatagramPacket dabaopacket=null;
//定义发送数据包的Socket对象
DatagramSocket sendSocket=null;
//定义一个控制持续发送信息的变量
boolean flag=true;
//实例化服务器的ip对象
serverip=InetAddress.getLocalHost();
//实例化从控制台得到被发送数据的输入流对象
inputreader=new BufferedReader(new InputStreamReader(System.in));
//实例化发送数据包的Socket对象
sendSocket=new DatagramSocket();
//控制持续发送信息
while(flag) {
System.out.println("请输入被发送的数据:");
info=inputreader.readLine();
if(info.equals("bey")) {
flag=false;
}
//实例化打包数据用的数据包对象
dabaopacket=new DatagramPacket(info.getBytes(),info.getBytes().length,
serverip,prot);
//发送数据包
sendSocket.send(dabaopacket);
}
//关闭socket和输入流
sendSocket.close();
inputreader.close();
}
}
package com.lx.test2;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPServer {
public static void main(String[] args)throws Exception {
//定义服务器开放的端口号
int prot=3000;
//定义保存被接收的数据变量
String msg=null;
//定义接收数据用的数据包对象
DatagramPacket jieshoupacket=null;
//定义接收数据包的Socket对象
DatagramSocket jieshouSocket=null;
//定义一个控制持续接收数据的变量
boolean flag=true;
//实例化接收数据包的Socket对象
jieshouSocket=new DatagramSocket(prot);
System.out.println("服务器已经启动,等待接收数据.....");
//控制持续接收
while(flag) {
//实例化接收数据用的数据包对象
byte databyte[]=new byte[100];
jieshoupacket=new DatagramPacket(databyte,databyte.length);
//接收数据包
jieshouSocket.receive(jieshoupacket);
//拆包
byte data[]=jieshoupacket.getData();
int len=jieshoupacket.getLength();
String clientip=jieshoupacket.getAddress().getHostAddress();
int outprot=jieshoupacket.getPort();
msg=new String(data,0,len);
System.out.println("今收到来自"+clientip+"的从"+outprot+
"端口发来的数据--"+msg);
if(msg.equals("bey")) {
flag=false;
}
}
//关闭socket
jieshouSocket.close();
}
}
例如: 客户端持续向服务器发送数据,并且接收服务器返回的数据;服务器持续接收客户端发送来的数据,并且可以向客户端返回值数据。
package com.lx.test2;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPClient {
public static void main(String[] args)throws Exception {
//定义服务器的ip对象
InetAddress serverip=null;
//定义服务器的端口号
int prot=3000;
//定义服务器开发的端口号
int openprot=4000;
//定义从控制台得到被发送数据的输入流对象
BufferedReader inputreader=null;
//定义保存被发送的数据变量
String info=null;
//定义打包数据用的数据包对象
DatagramPacket dabaopacket=null;
//定义发送数据包的Socket对象
DatagramSocket sendSocket=null;
//定义一个控制持续发送信息的变量
boolean flag=true;
//定义保存被接收的数据变量
String msg=null;
//定义接收数据用的数据包对象
DatagramPacket jieshoupacket=null;
//定义接收数据包的Socket对象
DatagramSocket jieshouSocket=null;
//实例化服务器的ip对象
serverip=InetAddress.getLocalHost();
//实例化从控制台得到被发送数据的输入流对象
inputreader=new BufferedReader(new InputStreamReader(System.in));
//实例化发送数据包的Socket对象
sendSocket=new DatagramSocket();
//实例化接收数据包的Socket对象
jieshouSocket=new DatagramSocket(openprot);
//控制持续发送信息
while(flag) {
System.out.println("请输入被发送的数据:");
info=inputreader.readLine();
if(info.equals("bey")) {
flag=false;
}
//实例化打包数据用的数据包对象
dabaopacket=new DatagramPacket(info.getBytes(),info.getBytes().length,
serverip,prot);
//发送数据包
sendSocket.send(dabaopacket);
//接收数据
//实例化接收数据用的数据包对象
byte databyte[]=new byte[100];
jieshoupacket=new DatagramPacket(databyte,databyte.length);
//接收数据包
jieshouSocket.receive(jieshoupacket);
//拆包
String clientip=jieshoupacket.getAddress().getHostAddress();
int outprot=jieshoupacket.getPort();
msg=new String(jieshoupacket.getData(),0,jieshoupacket.getLength());
System.out.println("今收到来自服务器端"+clientip+"的从"+outprot+
"端口返回的数据--"+msg);
}
//关闭socket和输入流
jieshouSocket.close();
sendSocket.close();
inputreader.close();
}
}
package com.lx.test2;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class UDPServer {
public static void main(String[] args)throws Exception {
//定义服务器开放的端口号
int openprot=3000;
//定义保存被接收的数据变量
String msg=null;
//定义接收数据用的数据包对象
DatagramPacket jieshoupacket=null;
//定义接收数据包的Socket对象
DatagramSocket jieshouSocket=null;
//定义一个控制持续接收数据的变量
boolean flag=true;
//定义服务器的ip对象
InetAddress serverip=null;
//定义服务器的端口号
int prot=4000;
//定义保存被发送的数据变量
String info=null;
//定义打包数据用的数据包对象
DatagramPacket dabaopacket=null;
//定义发送数据包的Socket对象
DatagramSocket sendSocket=null;
//实例化接收数据包的Socket对象
jieshouSocket=new DatagramSocket(openprot);
System.out.println("服务器已经启动,等待接收数据.....");
//实例化服务器的ip对象
serverip=InetAddress.getLocalHost();
//实例化发送数据包的Socket对象
sendSocket=new DatagramSocket();
//控制持续接收
while(flag) {
//实例化接收数据用的数据包对象
byte databyte[]=new byte[100];
jieshoupacket=new DatagramPacket(databyte,databyte.length);
//接收数据包
jieshouSocket.receive(jieshoupacket);
//拆包
byte data[]=jieshoupacket.getData();
int len=jieshoupacket.getLength();
String clientip=jieshoupacket.getAddress().getHostAddress();
int outprot=jieshoupacket.getPort();
msg=new String(data,0,len);
System.out.println("今收到来自"+clientip+"的从"+outprot+
"端口发来的数据--"+msg);
if(msg.equals("bey")) {
flag=false;
}
//发送数据
info="server-"+msg;
//实例化打包数据用的数据包对象
dabaopacket=new DatagramPacket(info.getBytes(),info.getBytes().length,
serverip,prot);
sendSocket.send(dabaopacket);
}
//关闭socket
sendSocket.close();
jieshouSocket.close();
}
}