Udp编程的一些练习:
前面我们学习了Udp编程的引入,写的代码有点繁琐,现在我们直接优化改进一下:
package com.westos.Udp; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; /** * 优化Udp编程 * */ public class SendDome { public static void main(String[] args) throws IOException { //1)创建Socket对象 DatagramSocket ds=new DatagramSocket(); //2)创建数据并打包 byte[] bys = "我来了,北京".getBytes(); DatagramPacket dp=new DatagramPacket(bys, bys.length,InetAddress.getByName("192.168.43.204"),12345); //3)发生数据报包 ds.send(dp); //4)关闭资源 ds.close(); } }
package com.westos.Udp; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class ReceiveDome { public static void main(String[] args) throws IOException { //1)创建Socket对象,接收端的Socket对象必须有发送端相对应的端口号 DatagramSocket ds=new DatagramSocket(12345); //2)创建数据报包 byte[] bys=new byte[1024]; DatagramPacket dp=new DatagramPacket(bys, bys.length); //3)接收数据报包 ds.receive(dp); //4)实时分析数据 String data=new String(dp.getData(),0,dp.getLength()); String ip=dp.getAddress().getHostAddress(); //5)输出数据 System.out.println("from"+ip+"data is"+data); //6)关闭数据 ds.close(); } }
以上的案例只是可以实现一句话的传输,那么当我们想要进行多句话的传输时应该怎么改进呢?
分析这里讲运用到我们的键盘录入的第二种方法(标准输入流)
package com.westos.Udp02; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; /** * * @author 杰哥 *实现发送多条语句 */ public class SendDome { public static void main(String[] args) { try { //1)创建Socket对象,并且整体给它Try...catch... DatagramSocket ds=new DatagramSocket(); //2)使用字符串缓冲输出流录入数据(键盘录入的第二种方法) BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); //一次读取一行 /** * 这里的while循环得把数据报包也包括进去 * 这样可以每读取一句话就去往报包里传输一句话知道over结束 */ String line=null; while((line=br.readLine())!=null) { //判断语句,出现over后就结束输入数据 if("over".equals(line)) { break; } //创建数据报包 DatagramPacket dp=new DatagramPacket(line.getBytes(), line.getBytes().length,InetAddress.getByName("192.168.43.204"),13579); //发送数据 ds.send(dp); } //关闭资源 /** * 这里的关闭数据必须得写在while循环外面 * 不然当你一句话说完后就已经关闭资源了无法再继续说话 * 就会出现异常:java.net.SocketException: Socket is closed * 所以我们这里得注意把它放在while循环的外面 */ ds.close(); } catch (IOException e) { e.printStackTrace(); } } }
package com.westos.Udp02; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class ReceiveDome { public static void main(String[] args){ try { //创建Socket类对象 DatagramSocket ds=new DatagramSocket(13579); /** * 这里的while循环是为了不断的接收多条数据 */ //创建数据报包 byte[] bys=new byte[1024]; DatagramPacket dp=new DatagramPacket(bys, bys.length); while(true) { //接收数据 ds.receive(dp); //解析数据 String line=new String(dp.getData(),0,dp.getLength()); String ip=dp.getAddress().getHostAddress(); //输出数据 System.out.println("from"+ip+"Data is"+line); } } catch (IOException e) { e.printStackTrace(); } } }
以上案例是当我们在发送端输入数据,在接收端接收数据,然后我们还得切换到发送端继续去输入数据,那么有没有可以在一个控制台去输出呢?
分析这里将运用到我们的多线程问题
package com.westos.Udp03; import java.io.BufferedReader;import java.io.IOException; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class SendDome implements Runnable{ //创建Socket类对象 private DatagramSocket ds; //创建有参构造 public SendDome (DatagramSocket ds) { this.ds=ds; } @Override public void run() { try { DatagramSocket dsSend=new DatagramSocket(); //创建字符缓冲输入流对象 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); String line=null; while((line=br.readLine())!=null) { if("拜拜".equals(line)) { break; } //创建数据报包 DatagramPacket dp=new DatagramPacket (line.getBytes(), line.getBytes().length, InetAddress.getByName("192.168.43.204"),10086); //发生数据报包 ds.send(dp); } //关闭数据 dsSend.close(); } catch (IOException e) { e.printStackTrace(); } } }
package com.westos.Udp03; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class ReceiveDome implements Runnable{ //创建Socket类对象 private DatagramSocket ds; //有参构造 public ReceiveDome(DatagramSocket ds) { this.ds=ds; } @Override public void run() { try { //创建数据报包 byte[] bys=new byte[1024]; DatagramPacket dp=new DatagramPacket(bys, bys.length); while(true) { //去接收它 ds.receive(dp); //解析数据 String data=new String(dp.getData(),0,dp.getLength()); String ip=dp.getAddress().getHostAddress(); //输出数据 System.out.println("from"+ip+"data is"+data); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } //解析数据 } }
package com.westos.Udp03; /** *我们这里是为了创建一个房间可以不断的去接收数据‘ *所以这里我们需要运用到多线程 、IO流等 * */ import java.io.IOException; import java.net.DatagramSocket; public class ChartRoom { public static void main(String[] args) throws IOException { //创建发生端对象和接收端对象 DatagramSocket dsSend=new DatagramSocket(); DatagramSocket dsReceive=new DatagramSocket(10086); //创建资源类对象 SendDome sd=new SendDome(dsSend); ReceiveDome rd=new ReceiveDome(dsReceive); //创建Tread类对象 Thread t1=new Thread(sd); Thread t2=new Thread(rd); //启动线程 t1.start(); t2.start(); } }
Udp编程的原理分析:
1)首先发送端和接收端双方都必须创建Socket对象
2)发送端设置好自己的ip以及端口号后,接收端也得绑定相对于的端口号
3)将需要发送的数据封装进数据报包中,在底层通过流的形式发送给接收方,接收端也创建一个数据报包,去接收发送端接收来的数据,然后去解析数据,最终输出它