java UDP编程

2023-12-21 08:56:06
  • UDP协议是一个不安全、不连续的,把数据发送出去之后就结束了,根本不管对方有没有接收到。

  • 快递员:DatagramSocket

  • 包裹:DatagramPacket

原理就是将数据以及对方的信息都放到包裹里面,然后让快递员发送给对应的人。

1、UDP传输数据

/*
DatagramSocket ds = new DatagramSocket(port); // 创建一个快递员,这个端口是自己开放的端口,用来接收和发送数据的。
别人给你发消息,就是给你这个端口发送数据。
然后你这个端口的快递员就可以拿到快递。
*/
public class UDPsendMsg {
 ? ?public void sendMsg(DatagramSocket ds, int port, String host, String msg){ // 发送信息
 ? ? ? ?byte[] bs = msg.getBytes(); // UDP传输只能传输字节流,所以需要将信息先转为byte数组
 ? ? ? ?DatagramPacket dp; // 创建一个包裹,用来存放需要发送的数据以及目标信息
 ? ? ? ?try {
 ? ? ? ? ? ?//  length是为了让对方知道你传输的数据长度
 ? ? ? ? ? ?dp = new DatagramPacket(bs, bs.length, InetAddress.getByName(host), port); // 将数据以及目标信息放进包裹
 ? ? ? ? ? ?ds.send(dp); // 通过快递员ds发送包裹
 ? ? ?  } catch (UnknownHostException e) {
 ? ? ? ? ? ?throw new RuntimeException(e);
 ? ? ?  } catch (IOException e) {
 ? ? ? ? ? ?throw new RuntimeException(e);
 ? ? ?  }
 ?  }
 ? ?public String receMsg(DatagramSocket ds) { // 接收信息
 ? ? ? ?byte[] bs = new byte[1024]; // 用来存放接收的信息
 ? ? ? ?DatagramPacket dp = new DatagramPacket(bs, 1024); // 先创建一个新包裹
 ? ? ? ?try {
 ? ? ? ? ? ?ds.receive(dp); // 接收快递员ds的快递,放到dp包裹里
 ? ? ?  } catch (IOException e) {
 ? ? ? ? ? ?throw new RuntimeException(e);
 ? ? ?  }
 ? ? ? ?String msg = new String(bs, 0, dp.getLength()); // 数据在bs内,然后0,length是需要的数据信息,然后转为字符串
 ? ? ? ?return msg; 
 ?  }
}

2、练习

  • 实现一个多人聊天室内,跟之前的TCP多人聊天室功能相同

  • DatagramPacket包裹类通过快递员类得到包裹之后包裹类是有对方的host 、port等信息的。

public class UDPsendMsg { // 首先创建了一个工具类,用来发送和接收消息方法的封装调用
 ? ?public void sendMsg(DatagramSocket ds, int port, String host, String msg){
 ? ? ? ?byte[] bs = msg.getBytes();
 ? ? ? ?DatagramPacket dp;
 ? ? ? ?try {
 ? ? ? ? ? ?dp = new DatagramPacket(bs, bs.length, InetAddress.getByName(host), port);
 ? ? ? ? ? ?// 3.把包裹发送出去
 ? ? ? ? ? ?ds.send(dp);
 ? ? ?  } catch (UnknownHostException e) {
 ? ? ? ? ? ?throw new RuntimeException(e);
 ? ? ?  } catch (IOException e) {
 ? ? ? ? ? ?throw new RuntimeException(e);
 ? ? ?  }
 ?  }
 ? ?public Map<String, String> receMsg(DatagramSocket ds) {
 ? ? ? ?byte[] bs = new byte[1024];
 ? ? ? ?DatagramPacket dp = new DatagramPacket(bs, 1024);
 ? ? ? ?try {
 ? ? ? ? ? ?ds.receive(dp);
 ? ? ?  } catch (IOException e) {
 ? ? ? ? ? ?throw new RuntimeException(e);
 ? ? ?  }
 ? ? ? ?String msg = new String(bs, 0, dp.getLength());
 ? ? ? ?Map<String, String> data = new HashMap<String, String>();
 ? ? ? ?data.put("msg", msg);
 ? ? ? ?data.put("port", String.valueOf(dp.getPort()));
 ? ? ? ?data.put("ip", dp.getAddress().toString().substring(1));
 ? ? ? ?return data;
 ?  }
}
?
public class ReceThread extends Thread { // 实现客户端接收信息的线程
 ? ?private DatagramSocket ds;
?
 ? ?public ReceThread(DatagramSocket ds) {
 ? ? ? ?this.ds = ds;
 ?  }
?
 ? ?@Override
 ? ?public void run() {
 ? ? ? ?UDPsendMsg sendMsg = new UDPsendMsg();
 ? ? ? ?while(true) {
 ? ? ? ? ? ?Map<String, String> data = sendMsg.receMsg(ds);
 ? ? ? ? ? ?String str = (String)data.get("msg");
 ? ? ? ? ? ?System.out.println(str);
 ? ? ?  }
 ?  }
}
?
public class SendThread extends Thread { // 实现客户端发送信息的线程
 ? ?private DatagramSocket ds;
 ? ?public SendThread(DatagramSocket ds) {
 ? ? ? ?this.ds = ds;
 ?  }
 ? ?@Override
 ? ?public void run() {
 ? ? ? ?Scanner sc = new Scanner(System.in);
 ? ? ? ?UDPsendMsg sendMsg = new UDPsendMsg();
 ? ? ? ?System.out.println("可以进行聊天了!!");
 ? ? ? ?sendMsg.sendMsg(ds, 9999, "127.0.0.1", "asdf");
 ? ? ? ?while(true) {
 ? ? ? ? ? ?String str = sc.nextLine();
 ? ? ? ? ? ?sendMsg.sendMsg(ds, 9999, "127.0.0.1", str);
 ? ? ?  }
 ?  }
}
?
public class Client { // 实现客户端
 ? ?public static void main(String[] args) throws SocketException {
 ? ? ? ?Scanner sc ?= new Scanner(System.in);
 ? ? ? ?System.out.println("请输入你使用的端口号:");
 ? ? ? ?int port = Integer.parseInt(sc.nextLine());
 ? ? ? ?DatagramSocket ds = new DatagramSocket(port);
 ? ? ? ?new ReceThread(ds).start();
 ? ? ? ?new SendThread(ds).start();
 ?  }
}
?
public class ServerSendThread extends Thread { // 实现服务端的接收消息后发送给其它消息的线程
 ? ?private DatagramSocket ds;
 ? ?private List<Map<String, String>> datalist;
 ? ?public ServerSendThread(DatagramSocket ds, List<Map<String,String>> datalist) {
 ? ? ? ?this.ds = ds;
 ? ? ? ?this.datalist = datalist;
 ?  }
 ? ?@Override
 ? ?public void run() {
 ? ? ? ?UDPsendMsg sendMsg = new UDPsendMsg();
?
 ? ? ? ?while(true){
 ? ? ? ? ? ?Map<String, String> data = sendMsg.receMsg(ds);
 ? ? ? ? ? ?String msg = data.get("msg");
 ? ? ? ? ? ?Map<String, String> d = new HashMap<String, String>();
 ? ? ? ? ? ?d.put("port", data.get("port"));
 ? ? ? ? ? ?d.put("host", data.get("ip"));
 ? ? ? ? ? ?msg = data.get("ip") + "/" + data.get("port") + ": " + msg;
 ? ? ? ? ? ?if(!datalist.contains(d)) {
 ? ? ? ? ? ? ? ?// 聊天室内加入一个新成员
 ? ? ? ? ? ? ? ?System.out.println("聊天室内加入一个新成员" + d.get("host") + ":"+ d.get("port"));
 ? ? ? ? ? ? ? ?datalist.add(d);
 ? ? ? ? ? ? ? ?msg = "聊天室内加入一个新成员:" + data.get("ip") + "/" + data.get("port");
 ? ? ? ? ?  }
 ? ? ? ? ? ?for(Map<String, String> da : datalist){
 ? ? ? ? ? ? ? ?if(!d.equals(da)) {
 ? ? ? ? ? ? ? ? ? ?sendMsg.sendMsg(ds, Integer.parseInt(da.get("port")), da.get("host"), msg);
 ? ? ? ? ? ? ?  }
 ? ? ? ? ?  }
 ? ? ?  }
 ?  }
}
?
public class Server { // 实现服务器端
 ? ?public static void main(String[] args) throws SocketException {
 ? ? ? ?DatagramSocket ds = new DatagramSocket(9999);
 ? ? ? ?List<Map<String, String>> list = new ArrayList<Map<String, String>>();
 ? ? ? ?new ServerSendThread(ds, list).start();
 ?  }
}

文章来源:https://blog.csdn.net/qq_64468032/article/details/135120657
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。