UDP传输
- DatagramSocket和DatagramPacket
- 建立发送端和接收端。
- 建立数据包。
- 调用Socket的数据接收方法。
- 关闭Socket。
发送端和接收端是两个独立运行的程序。
类DatagramSocket
此类表示用来发送和接收数据报包的套接字。
方法 | 方法简介 |
---|---|
void receive(DatagramPacket p) | 从此套接字接收数据报包。 |
void send(DatagramPacket p) | 从此套接字发送数据报包。 |
类DatagramPacket
数据报包用于实现无连接的包投递服务。每条报文仅根据包中包含的信息从一台机器路由到另一台机器。
构造方法:
-
DatagramPacket(byte[] buf,int length)
构造DatagramPacket,用于接收长度为length的数据包。 -
DatagramPacket(byte[] buf,int length, IntAddress address, int port)
构造长度为length的数据包。将数据发送到指定IP地址的指定端口号。
UDP发送数据流程
- 建立UDP socket服务。
- 提供数据并将数据封装到数据包中。
- 通过socket服务的发送功能将数据包发送出去。
- 关闭资源。
public static void main(String[] args) throws Exception {
//通过Datagramsocket对象创建UDP服务
DatagramSocket ds = new DatagramSocket();
//确定数据并封装成数据包
byte [] data = "UDP, I am coming.".getBytes();
DatagramPacket datap = new DatagramPacket(data, data.length, InetAddress.getByName("自己本机的IP地址"),10000);
//通过Socket服务将已有的数据包发送出去
ds.send(datap);
//关闭资源
ds.close();
}
由于没有接收端,因此该程序发送的数据丢失。
UDP接收端
- 定义UDP的Socket服务。
- 定义一个数据包DatagramPacket,用于存储接收到的字节数据。数据包对象中有更多功能可以提取字节信息中的不同信息。
- 通过Socket服务的receive方法将收到的数据存储到定义好的数据包中。
4.通过数据包对象中的特有功能将数据取出。 - 对数据进行处理。
- 关闭资源。
定义UDP接收端的时候通常会监听一个端口,其实就是给这个网络应用程序定义一个数字标识。如果不定义系统会分配一个随机的。方便于明确哪些数据过来该应用程序可以处理。接收端通常会指定一个监听端口。
public static void main(String[] args) throws Exception{
//创建UDP的Scoket服务,建立端点。同时指定监听端口为10000。
DatagramSocket ds = new DatagramSocket(10000);
//定义数据包用于存储数据。
byte [] buffer = new byte[1024];
DatagramPacket datap = new DatagramPacket(buffer, buffer.length);
//通过服务的receive方法将收到的数据存入数据包中
ds.receive(datap);
//通过数据包的方法获取其中的数据
String IP = datap.getAddress().getHostAddress();
String data = new String(datap.getData(), 0, datap.getLength());
int port = datap.getPort();
System.out.println(IP);
System.out.println(data);
System.out.println(port);
//关闭端口
ds.close();
}
- 接收端的receive为阻塞式方法。
- 如果系统没有指定发送端从哪里发送数据,系统会随机给发送端分配一个端口,代表数据是从这里发送的。如果发送端的端口用完之后没有释放则下一次发送数据的端口会按照上一次的进行顺延。
键盘输入发送
发送端
public static void main(String[] args) throws Exception {
//通过Datagramsocket对象创建UDP服务
DatagramSocket ds = new DatagramSocket();
//键盘录入
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line = bufr.readLine())!= null){
if(line.equals("886")){
break;
}
byte [] buffer = line.getBytes();
DatagramPacket datap = new DatagramPacket(buffer, buffer.length, InetAddress.getByName("输入要发送的机器的IP地址"), 10001);
ds.send(datap);
}
ds.close();
}
接收端
public static void main(String[] args) throws Exception{
DatagramSocket ds = new DatagramSocket(10001);
while(true){
byte [] buffer = new byte[1024];
DatagramPacket datap = new DatagramPacket(buffer, buffer.length);
ds.receive(datap);
String ip = datap.getAddress().getHostAddress();
String data = new String(datap.getData(), 0, datap.getLength());
System.out.println("ip:" + ip + "String:" + data);
}
}
使用UDP建立聊天室
虽然实现了使用UDP进行两个窗口之间的通信,但是要想在一个窗口实现信息的接收与发送需要使用多线程技术。一个线程实现信息的发送,一个线程实现信息的接收。
发送端
public class Send implements Runnable {
private DatagramSocket socket;
public Send(DatagramSocket socket) {
// TODO Auto-generated constructor stub
this.socket = socket;
}
@Override
public void run() {
// TODO Auto-generated method stub
try{
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while((line = bufr.readLine()) != null){
if(line.equals("886"))
break;
byte [] buffer = line.getBytes();
DatagramPacket datap =
new DatagramPacket(buffer, buffer.length, InetAddress.getByName("输入自己的IP地址"), 10002);
this.socket.send(datap);
}
}catch(Exception e){
throw new RuntimeException("Fail to send.");
}
}
}
接收端
public class Receive implements Runnable{
private DatagramSocket socket;
public Receive(DatagramSocket socket) {
// TODO Auto-generated constructor stub
this.socket = socket;
}
@Override
public void run() {
try{
while(true){
byte [] buffer = new byte[1024];
DatagramPacket datap = new DatagramPacket(buffer, buffer.length);
this.socket.receive(datap);
String ip = datap.getAddress().getHostAddress();
String data = new String(datap.getData(), 0, datap.getLength());
System.out.println(ip + "::" + data);
}
}catch(Exception e){
throw new RuntimeException("Fail to receive.");
}
}
}
主函数
public static void main(String[] args) throws Exception {
DatagramSocket sendds = new DatagramSocket();
DatagramSocket receiveds = new DatagramSocket(10002);
new Thread(new Send(sendds)).start();
new Thread(new Receive(receiveds)).start();
}
网友评论