网络编程(UDP)
一、什么是UDP,它的优缺点是什么?
UDP—>用户数据报协议
报—报文
优点:消耗小,效率高
缺点:不能保证数据的安全与可靠。
二、建立基于UDP的网络通讯程序需要使用的类和常用方法?
1.基于UDP的网络通讯程序是不区分客户端和服务器。
java.net Class 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() 返回发送数据报的远程主机上的端口号,或从中接收数据报的端口号。
java.net Class DatagramSocket 此类表示用于发送和接收数据报数据包的套接字。【发包/收包】
构造方法
DatagramSocket() 构造数据报套接字并将其绑定到本地主机上的任何可用端口。【发包】
DatagramSocket(int port) 构造数据报套接字并将其绑定到本地主机上的指定端口。【收包】
实例方法
void send(DatagramPacket p) 从此套接字发送数据报包。
void receive(DatagramPacket p) 从此套接字接收数据报包。
void close() 关闭此数据报套接字。
例如: 客户端向服务器发送数据,服务器接收客户端发送来的数据。
客户端向服务器发送数据
package com.udp;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
//客户端
public class SocketDome {
public static void main(String[] args) throws Exception{
//定义服务器的IP对象
InetAddress ip = null;
//定义服务器的端口号
int prot = 3000;
//定义从控制台得到被发送数据的输入流对象
BufferedReader in = null;
//定义保存被发送的数据变量
String info = null;
//定义打包数据用的数据包对象
DatagramPacket dabao = null;
//定义发送数据包的数据包对象
DatagramSocket sendsocket = null;
//实例化服务器IP地址
ip = InetAddress.getLocalHost();
//实例化从控制台得到被发送数据的输入流对象
in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入被发送的数据");
info = in.readLine();
//实例化打包数据的数据包对象
dabao = new DatagramPacket(info.getBytes(),info.getBytes().length,ip,prot);
//实例化发送数据的客户端对象
sendsocket = new DatagramSocket();
//发送数据包
sendsocket.send(dabao);
//关闭socket和输入流
sendsocket.close();
in.close();
}
}
服务器接收客户端发送来的数据。
package com.udp;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ServerDome {
public static void main(String[] args) throws Exception {
//定义服务器开放的端口号
int prot = 3000;
//定义保存被接收的数据变量
String msg = null;
//定义接收数据用的数据包对象
DatagramPacket jieshou = null;
//定义接收数据包的Socket对象
DatagramSocket jieshouSocket=null;
//实例化接收数据用的数据包对象
byte array[] = new byte[100];
jieshou = new DatagramPacket(array,array.length);
//实例化接收数据包的Socket对象
jieshouSocket = new DatagramSocket(prot);
System.out.println("服务器已经启动,等待接受数据......");
//接收数据包
jieshouSocket.receive(jieshou);
//拆包
byte data[] = jieshou.getData();
int len = jieshou.getLength();
String ip = jieshou.getAddress().getHostAddress();
int outprot = jieshou.getPort();
msg = new String(data,0,len);
System.out.println("今收到来自"+ip+"的从"+outprot+"端口发来的数据=="+msg);
//关闭socket
jieshouSocket.close();
}
}
执行结果:
例如2: 客户端持续向服务器发送数据,服务器持续接收客户端发送来的数据。
客户端持续向服务器发送数据
package com.udp2;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
//客户端
public class SocketDome2 {
public static void main(String[] args) throws Exception{
//定义服务器的IP对象
InetAddress ip = null;
//定义服务器的端口号
int prot = 3000;
//定义从控制台得到被发送数据的输入流对象
BufferedReader in = null;
//定义保存被发送的数据变量
String info = null;
//定义打包数据用的数据包对象
DatagramPacket dabao = null;
//定义发送数据包的数据包对象
DatagramSocket sendsocket = null;
//定义一个控制持续发送信息的变量
boolean flag = true;
//实例化服务器IP地址
ip = InetAddress.getLocalHost();
//实例化从控制台得到被发送数据的输入流对象
in = new BufferedReader(new InputStreamReader(System.in));
//实例化发送数据的客户端对象
sendsocket = new DatagramSocket();
//持续发出信息
while(flag) {
System.out.println("请输入被发送的数据");
info = in.readLine();
if(info.equals("再见")) {
flag = false;
}
//实例化打包数据的数据包对象
dabao = new DatagramPacket(info.getBytes(),info.getBytes().length,ip,prot);
//发送数据包
sendsocket.send(dabao);
}
//关闭socket和输入流
sendsocket.close();
in.close();
}
}
服务器持续接收客户端发送来的数据
package com.udp2;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ServerDome2 {
public static void main(String[] args) throws Exception {
//定义服务器开放的端口号
int prot = 3000;
//定义保存被接收的数据变量
String msg = null;
//定义接收数据用的数据包对象
DatagramPacket jieshou = null;
//定义接收数据包的Socket对象
DatagramSocket jieshouSocket=null;
//定义一个控制持续接收信息的变量
boolean flag = true;
//实例化接收数据包的Socket对象
jieshouSocket = new DatagramSocket(prot);
System.out.println("服务器已经启动,等待接受数据......");
while(flag) {
//实例化接收数据用的数据包对象
byte array[] = new byte[100];
jieshou = new DatagramPacket(array,array.length);
//接收数据包
jieshouSocket.receive(jieshou);
//拆包
byte data[] = jieshou.getData();
int len = jieshou.getLength();
String ip = jieshou.getAddress().getHostAddress();
int outprot = jieshou.getPort();
msg = new String(data,0,len);
System.out.println("今收到来自"+ip+"的从"+outprot+"端口发来的数据=="+msg);
if(msg.equals("再见")) {
flag =false;
}
}
//关闭socket
jieshouSocket.close();
}
}
执行结果:
例如: 客户端持续向服务器发送数据,并且接收服务器返回的数据;服务器持续接收客户端发送来的数据,并且可以向客户端返回值数据。
客户端持续向服务器发送数据,并且接收服务器返回的数据
package com.udp3;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
//客户端
public class SocketDome3 {
public static void main(String[] args) throws Exception{
//定义服务器的IP对象
InetAddress ip = null;
//定义服务器的端口号
int prot = 3000;
//定义服务器开发的端口号
int openprot=4000;
//定义从控制台得到被发送数据的输入流对象
BufferedReader in = null;
//定义保存被发送的数据变量
String info = null;
//定义打包数据用的数据包对象
DatagramPacket dabao = null;
//定义发送数据包的数据包对象
DatagramSocket sendsocket = null;
//定义一个控制持续发送信息的变量
boolean flag = true;
//定义保存被接收的数据变量
String msg=null;
//定义接收数据用的数据包对象
DatagramPacket jieshou=null;
//定义接收数据包的Socket对象
DatagramSocket jieshouSocket=null;
//实例化服务器IP地址
ip = InetAddress.getLocalHost();
//实例化从控制台得到被发送数据的输入流对象
in = new BufferedReader(new InputStreamReader(System.in));
//实例化发送数据的客户端对象
sendsocket = new DatagramSocket();
//实例化接收数据包的Socket对象
jieshouSocket = new DatagramSocket(openprot);
//持续发送数据
while(flag) {
System.out.println("请输入被发送的数据");
info = in.readLine();
if(info.equals("再见")) {
flag = false;
}
//实例化打包数据的数据包对象
dabao = new DatagramPacket(info.getBytes(),info.getBytes().length,ip,prot);
//发送数据包
sendsocket.send(dabao);
//接收数据
//实例化接收数据用的数据包对象
byte a[]=new byte[100];
jieshou = new DatagramPacket(a,a.length);
//接收包
jieshouSocket.receive(jieshou);
//拆包
String ip2 = jieshou.getAddress().getHostAddress();
int outprot = jieshou.getPort();
msg = new String(jieshou.getData(),0,jieshou.getLength());
System.out.println("今收到来自服务器端"+ip2+"的从"+outprot+
"端口返回的数据--"+msg);
}
//关闭socket和输入流
sendsocket.close();
in.close();
}
}
服务器持续接收客户端发送来的数据,并且可以向客户端返回值数据。
package com.udp3;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class ServerDome3 {
public static void main(String[] args) throws Exception {
//定义服务器的ip对象
InetAddress ip1=null;
//定义服务器开放的端口号
int prot = 3000;
//定义服务器的端口号
int prot2=4000;
//定义保存被接收的数据变量
String msg = null;
//定义接收数据用的数据包对象
DatagramPacket jieshou = null;
//定义接收数据包的Socket对象
DatagramSocket jieshouSocket=null;
//定义一个控制持续接收信息的变量
boolean flag = true;
//实例化接收数据包的Socket对象
jieshouSocket = new DatagramSocket(prot);
//定义保存被发送的数据变量
String info=null;
//定义打包数据用的数据包对象
DatagramPacket dabaopacket=null;
//定义发送数据包的Socket对象
DatagramSocket sendSocket=null;
//实例化服务器的ip对象
ip1=InetAddress.getLocalHost();
//实例化发送数据包的Socket对象
sendSocket=new DatagramSocket();
System.out.println("服务器已经启动,等待接受数据......");
//持续接收数据
while(flag) {
//实例化接收数据用的数据包对象
byte array[] = new byte[100];
jieshou = new DatagramPacket(array,array.length);
//接收数据包
jieshouSocket.receive(jieshou);
//拆包
byte data[] = jieshou.getData();
int len = jieshou.getLength();
String ip2 = jieshou.getAddress().getHostAddress();
int outprot = jieshou.getPort();
msg = new String(data,0,len);
System.out.println("今收到来自"+ip2+"的从"+outprot+"端口发来的数据=="+msg);
if(msg.equals("再见")) {
flag =false;
}
//发送数据
if(msg.equals("吃饭了吗?")) {
info = "吃了";
//实例化打包数据用的数据包对象
dabaopacket=new DatagramPacket(info.getBytes(),info.getBytes().length,
ip1,prot2);
sendSocket.send(dabaopacket);
}else
if(msg.equals("吃的什么?")) {
info = "米饭";
//实例化打包数据用的数据包对象
dabaopacket=new DatagramPacket(info.getBytes(),info.getBytes().length,
ip1,prot2);
sendSocket.send(dabaopacket);
}else {
info = "我去忙了";
//实例化打包数据用的数据包对象
dabaopacket=new DatagramPacket(info.getBytes(),info.getBytes().length,
ip1,prot2);
sendSocket.send(dabaopacket);
}
}
//关闭socket
jieshouSocket.close();
}
}
执行结果: