赞
踩
在了解了TCP协议中java代码TCP协议中java代码的相关编写后,今天我们继续了解UDP协议
[1] 不连接,不稳定
[2] 客户端与服务端没有明确界限
[3] 不管有没有准备好,都可以发送给你
(就好比导弹攻击;DDOS,洪水攻击)
1.1 我们下面先来模拟一个单方面的接收和单方面发送的例子
发送端
package com.gs.lesson03; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; //不需要连接服务器 public class UdpClientDemo01 { public static void main(String[] args) throws Exception { // 1.建立一个Socket DatagramSocket socket = new DatagramSocket(); // 2.建个包 String msg = "你好啊,服务器!"; //2.1发送给谁(IP地址+端口号) InetAddress localhost = InetAddress.getByName("localhost"); int port = 9090; //数据 数据的起始位置 数据的结束位置 IP地址 端口号 DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port); //3. 发送包 socket.send(packet); //4.关闭流 socket.close(); } }
接收端
package gs.lesson03; import java.net.DatagramPacket; import java.net.DatagramSocket; //还是要等待客户端连接 public class UdpServerDemo01 { public static void main(String[] args) throws Exception { //1.开放端口 DatagramSocket socket = new DatagramSocket(9090); //2.接收数据包 byte[] buffer = new byte[1024]; DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length); //阻塞(就是等待接收) socket.receive(packet); System.out.println(packet.getAddress().getHostAddress()); System.out.println(new String(packet.getData(),0,packet.getLength())); //3.关闭连接 socket.close(); } }
1.2 上面的例子显然只是一个入门,因为他只能接收一条信息;那么我们如何实现接收多条信息,并在适当的时候断开连接呢?
下面我们模拟一个接收方可以接收多条信息,并在接收到bye这个命令后就断开连接。
发送方
package gs.chat; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; public class UdpSenderDemo01 { public static void main(String[] args) throws Exception { DatagramSocket socket = new DatagramSocket(8888); //准备数据,控制台取 System.in BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); while(true){ String data = reader.readLine(); byte[] datas = data.getBytes(); DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("localhost",6666)); //发送数据包 socket.send(packet); //当接收到 bye时退出 if(data.startsWith("bye")){ break; } } socket.close(); } }
接收方
package gs.chat; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; public class UdpReceiverDemo01 { public static void main(String[] args) throws Exception { DatagramSocket socket = new DatagramSocket(6666); while (true){ // 准备接收包裹 byte[] container = new byte[1024]; DatagramPacket packet = new DatagramPacket(container,0,container.length); // 阻塞式接收包裹 socket.receive(packet); // 当收到 bye时断开连接 byte[] data = packet.getData(); String receiveData = new String(data,0,data.length); System.out.println(receiveData); if(receiveData.startsWith("bye")){ break; } } socket.close(); } }
1.3 上面的例子还是显然不足的,我们还是没有实现真正的通信,也就是你说一句,我能回一句的那种。那我们该如何实现呢?
这里我们可以开启两个线程进行模拟,这两个线程分别代表接收方和发送方。也就是每个人都是接受信息的人,也是发送信息的人。
[1] 编写接受方线程
package gs.chat; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; public class TalkReceiver implements Runnable { DatagramSocket socket = null; //接收方的端口 private int port; //信息来自谁 private String msgFrom; public TalkReceiver(int port,String msgFrom) { this.port = port; this.msgFrom = msgFrom; try { //新建数据报连接 socket = new DatagramSocket(port); } catch (SocketException e) { e.printStackTrace(); } } @Override public void run() { while (true){ try { // 准备接收包裹 byte[] container = new byte[1024]; DatagramPacket packet = new DatagramPacket(container,0,container.length); // 阻塞式接收包裹 socket.receive(packet); // 当收到 bye时断开连接 byte[] data = packet.getData(); String receiveData = new String(data,0,data.length); System.out.println(msgFrom+":"+receiveData); if(receiveData.startsWith("bye")){ break; } } catch (IOException e) { e.printStackTrace(); } } socket.close(); } }
[2] 编写发送方的线程
package gs.chat; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetSocketAddress; import java.net.SocketException; public class TalkSend implements Runnable { DatagramSocket socket = null; BufferedReader reader = null; //发送者的端口 private int fromPort; //接收者的IP private String toIp; //接收者的端口 private int toPort; public TalkSend(int fromPort, String toIp, int toPort) { this.fromPort = fromPort; this.toIp = toIp; this.toPort = toPort; try { //新建一个数据报连接 socket = new DatagramSocket(fromPort); //获取我们键盘上的输入 reader = new BufferedReader(new InputStreamReader(System.in)); } catch (Exception e) { e.printStackTrace(); } } @Override public void run() { while(true){ try { //读取相应的数据形成数据源包 String data = reader.readLine(); byte[] datas = data.getBytes(); DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress(this.toIp,this.toPort)); //发送数据包 socket.send(packet); //当接收到 bye时退出 if(data.startsWith("bye")){ break; } }catch (Exception e){ e.printStackTrace(); } } socket.close(); } }
[3] 模拟通信的双方,一个为Teacher,需要开启一个接收线程和发送线程
假设老师要发送给学生的地址是localhost 8888,则学生接收的地址就是localhost 8888
学生要发送给老师的地址是localhost 9999, 则老师接收的地址就是localhost 9999。
(看起来描述很愚蠢,只要你不被代码绕进去就好)
package gs.chat;
public class TalkTeacher {
public static void main(String[] args) {
new Thread(new TalkSend(5555,"localhost",8888)).start();
new Thread(new TalkReceiver(9999,"student")).start();
}
}
[4] 一个为Student
package gs.chat;
public class TalkStudent {
public static void main(String[] args) {
//开启两个线程
new Thread(new TalkSend(7777,"localhost",9999)).start();
new Thread(new TalkReceiver(8888,"teacher")).start();
}
}
运行后就是一个mini的聊天室了
以上这些网络编程的学习笔记都是在B站看狂神时所写的。如果有任何疑惑,可以下方留言,也请多关注这个UP主。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。