1. UDP协议发送数据:我们总是先运行接收端,再运行发送端
发送端:

  1. package cn.itcast_02;
  2. import java.io.IOException;
  3. import java.net.DatagramPacket;
  4. import java.net.DatagramSocket;
  5. import java.net.InetAddress;
  6. /*
  7. * UDP协议发送数据:
  8. * A:创建发送端Socket对象
  9. * B:创建数据,并把数据打包
  10. * C:调用Socket对象的发送方法发送数据包
  11. * D:释放资源
  12. */
  13. public class SendDemo {
  14. public static void main(String[] args) throws IOException {
  15. // 创建发送端Socket对象
  16. // DatagramSocket()
  17. DatagramSocket ds = new DatagramSocket();
  18. // 创建数据,并把数据打包
  19. // DatagramPacket(byte[] buf, int length, InetAddress address, int port)
  20. // 创建数据
  21. byte[] bys = "hello,udp,我来了".getBytes();//转码
  22. // 长度
  23. int length = bys.length;
  24. // IP地址对象
  25. InetAddress address = InetAddress.getByName("192.168.12.92");
  26. // 端口
  27. int port = 10086;
  28. DatagramPacket dp = new DatagramPacket(bys, length, address, port);
  29. // 调用Socket对象的发送方法发送数据包
  30. // public void send(DatagramPacket p)
  31. ds.send(dp);
  32. // 释放资源
  33. ds.close();
  34. }
  35. }

接收端:

  1. package cn.itcast_02;
  2.  
  3. import java.io.IOException;
  4. import java.net.DatagramPacket;
  5. import java.net.DatagramSocket;
  6. import java.net.InetAddress;
  7.  
  8. /*
  9. 9 * UDP协议接收数据:
  10. 10 * A:创建接收端Socket对象
  11. 11 * B:创建一个数据包(接收容器)
  12. 12 * C:调用Socket对象的接收方法接收数据
  13. 13 * D:解析数据包,并显示在控制台
  14. 14 * E:释放资源
  15. */
  16. public class ReceiveDemo {
  17. public static void main(String[] args) throws IOException {
  18. 18 // 创建接收端Socket对象
  19. 19 // DatagramSocket(int port)
  20. DatagramSocket ds = new DatagramSocket(10086);
  21.  
  22. 22 // 创建一个数据包(接收容器)
  23. 23 // DatagramPacket(byte[] buf, int length)
  24. byte[] bys = new byte[1024];
  25. int length = bys.length;
  26. DatagramPacket dp = new DatagramPacket(bys, length);
  27.  
  28. 28 // 调用Socket对象的接收方法接收数据
  29. 29 // public void receive(DatagramPacket p)
  30. ds.receive(dp); // 阻塞式

  31. 32 // 解析数据包,并显示在控制台
  32. 33 // 获取对方的ip
  33. // public InetAddress getAddress()
  34. InetAddress address = dp.getAddress();
  35. String ip = address.getHostAddress();
  36. // public byte[] getData():获取数据缓冲区
  37. // public int getLength():获取数据的实际长度
  38. byte[] bys2 = dp.getData();
  39. int len = dp.getLength();
  40. String s = new String(bys2, 0, len);
  41. System.out.println(ip + "传递的数据是:" + s);
  42.  
  43. 44 // 释放资源
  44. ds.close();
  45. }
  46. }

这里ds.close():

Java的内存回收机制,也是要等到资源达到一定限度才开始回收,也是有生命周期的。用close()可以及时回收资源,更加高效.使用close()后就可以及时释放资源,不必非等到最后资源占用完了才开始痛苦的回收过程,而且从良好的编程习惯来说,创建了对象,就应该考虑到用完后就要释放内存资源,要养成一个良好的编程习惯。

这里首先我们是运行接收端,因为如果不先运行接收端,先运行发送端的话,数据也不会接收到。但是与此同时,如果先运行接收端,可是没有接收到数据,不可能解析数据和显示数据,所以:先运行接收端,后运行发送端,同时我们也定义接收端为阻塞式,(也就是等待数据发送过来)

UDP发送数据和接收数据图解:

UDP发送数据和接收数据代码的优化:

UDP协议发送数据:我们总是先运行接收端,再运行发送端
发送端:

  1. package cn.itcast_03;
  2.  
  3. import java.io.IOException;
  4. import java.net.DatagramPacket;
  5. import java.net.DatagramSocket;
  6. import java.net.InetAddress;
  7.  
  8. public class SendDemo {
  9. public static void main(String[] args) throws IOException {
  10. // 创建发送端的Socket对象
  11. DatagramSocket ds = new DatagramSocket();
  12.  
  13. // 创建数据并打包
  14. byte[] bys = "helloworld".getBytes();
  15. DatagramPacket dp = new DatagramPacket(bys, bys.length,
  16. InetAddress.getByName("192.168.12.92"), 12345);
  17.  
  18. // 发送数据
  19. ds.send(dp);
  20.  
  21. // 释放资源
  22. ds.close();
  23. }
  24. }

接收端:

  1. package cn.itcast_03;
  2.  
  3. import java.io.IOException;
  4. import java.net.DatagramPacket;
  5. import java.net.DatagramSocket;
  6.  
  7. 7 /*
  8. 8 * 多次启动接收端:
  9. 9 * java.net.BindException: Address already in use: Cannot bind
  10. 10 * 端口被占用。
  11. 11 */
  12. public class ReceiveDemo {
  13. public static void main(String[] args) throws IOException {
  14. // 创建接收端的Socket对象
  15. DatagramSocket ds = new DatagramSocket(12345);
  16.  
  17. // 创建一个包裹
  18. byte[] bys = new byte[1024];
  19. DatagramPacket dp = new DatagramPacket(bys, bys.length);
  20.  
  21. // 接收数据
  22. ds.receive(dp);
  23.  
  24. // 解析数据
  25. String ip = dp.getAddress().getHostAddress();
  26. String s = new String(dp.getData(), 0, dp.getLength());
  27. System.out.println("from " + ip + " data is : " + s);
  28.  
  29. // 释放资源
  30. ds.close();
  31. }
  32. }

2. 发送端数据来自于键盘录入的案例:(注意这里我们是如何更改上面的代码的)

发送端:

  1. package cn.itcast_04;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.IOException;
  5. import java.io.InputStreamReader;
  6. import java.net.DatagramPacket;
  7. import java.net.DatagramSocket;
  8. import java.net.InetAddress;
  9.  
  10. 10 /*
  11. 11 * 数据来自于键盘录入
  12. 12 * 键盘录入数据要自己控制录入结束。
  13. 13 */
  14. public class SendDemo {
  15. public static void main(String[] args) throws IOException {
  16. // 创建发送端的Socket对象
  17. DatagramSocket ds = new DatagramSocket();
  18.  
  19. 19 // 封装键盘录入数据
  20. 20 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  21. String line = null;
  22. while ((line = br.readLine()) != null) {
  23. 23 if ("886".equals(line)) { //键盘录入数据终止符定义为:886
  24. 24 break;
  25. 25 }

  26. // 创建数据并打包
  27. byte[] bys = line.getBytes();
  28. // DatagramPacket dp = new DatagramPacket(bys, bys.length,
  29. // InetAddress.getByName("192.168.12.92"), 12345);//发送给特定的用户电脑
  30. DatagramPacket dp = new DatagramPacket(bys, bys.length,
  31. InetAddress.getByName("192.168.12.255"), 12345);//发送给网内所有电脑

  32. // 发送数据
  33. ds.send(dp);
  34. }
  35.  
  36. // 释放资源
  37. ds.close();
  38. }
  39. }

接收端:

  1. package cn.itcast_04;
  2. import java.io.IOException;
  3. import java.net.DatagramPacket;
  4. import java.net.DatagramSocket;
  5. /*
  6. * 多次启动接收端:
  7. * java.net.BindException: Address already in use: Cannot bind
  8. * 端口被占用。
  9. */
  10. public class ReceiveDemo {
  11. public static void main(String[] args) throws IOException {
  12. // 创建接收端的Socket对象
  13. DatagramSocket ds = new DatagramSocket(12345);
  14. while (true) {
  15. // 创建一个包裹
  16. byte[] bys = new byte[1024];
  17. DatagramPacket dp = new DatagramPacket(bys, bys.length);
  18. // 接收数据
  19. ds.receive(dp);
  20. // 解析数据
  21. String ip = dp.getAddress().getHostAddress();
  22. String s = new String(dp.getData(), 0, dp.getLength());
  23. System.out.println("from " + ip + " data is : " + s);
  24. }
  25. // 释放资源
  26. 32 // 接收端应该一直开着等待接收数据,是不需要关闭,就好比百度服务器是一直开着着,一样的,接收端好比服务器端
  27. 33 // ds.close();
  28. }
  29. }

这里我们知道如果这个程序要完成通信的话,我们就必须打开两个界面,一个发送端一个接收端:

但是现实生活中我们都是在一个界面下发送和接收数据,例如如下的qq聊天界面:

于是我们这里引入对上面程序的进一步优化:这里就是利用多线程改进程序

  1. package cn.itcast_05;
  2. import java.io.IOException;
  3. import java.net.DatagramSocket;
  4. /*
  5. * 通过多线程改进刚才的聊天程序,这样我就可以实现在一个窗口发送和接收数据了
  6. */
  7. public class ChatRoom {
  8. public static void main(String[] args) throws IOException {
  9. DatagramSocket dsSend = new DatagramSocket();
  10. DatagramSocket dsReceive = new DatagramSocket(12306);
  11. SendThread st = new SendThread(dsSend);
  12. ReceiveThread rt = new ReceiveThread(dsReceive);
  13. Thread t1 = new Thread(st);
  14. Thread t2 = new Thread(rt);
  15. t1.start();
  16. t2.start();
  17. }
  18. }
  1. package cn.itcast_05;
  2. import java.io.IOException;
  3. import java.net.DatagramPacket;
  4. import java.net.DatagramSocket;
  5. public class ReceiveThread implements Runnable {
  6. private DatagramSocket ds;
  7. public ReceiveThread(DatagramSocket ds) {
  8. this.ds = ds;
  9. }
  10. @Override
  11. public void run() {
  12. try {
  13. while (true) {
  14. // 创建一个包裹
  15. byte[] bys = new byte[1024];
  16. DatagramPacket dp = new DatagramPacket(bys, bys.length);
  17. // 接收数据
  18. ds.receive(dp);
  19. // 解析数据
  20. String ip = dp.getAddress().getHostAddress();
  21. String s = new String(dp.getData(), 0, dp.getLength());
  22. System.out.println("from " + ip + " data is : " + s);
  23. }
  24. } catch (IOException e) {
  25. e.printStackTrace();
  26. }
  27. }
  28. }
  1. package cn.itcast_05;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import java.net.DatagramPacket;
  6. import java.net.DatagramSocket;
  7. import java.net.InetAddress;
  8. public class SendThread implements Runnable {
  9. private DatagramSocket ds;
  10. public SendThread(DatagramSocket ds) {
  11. this.ds = ds;
  12. }
  13. @Override
  14. public void run() {
  15. try {
  16. // 封装键盘录入数据
  17. BufferedReader br = new BufferedReader(new InputStreamReader(
  18. System.in));
  19. String line = null;
  20. while ((line = br.readLine()) != null) {
  21. if ("886".equals(line)) {
  22. break;
  23. }
  24. // 创建数据并打包
  25. byte[] bys = line.getBytes();
  26. // DatagramPacket dp = new DatagramPacket(bys, bys.length,
  27. // InetAddress.getByName("192.168.12.92"), 12345);
  28. DatagramPacket dp = new DatagramPacket(bys, bys.length,
  29. InetAddress.getByName("192.168.12.255"), 12306);
  30. // 发送数据
  31. ds.send(dp);
  32. }
  33. // 释放资源
  34. ds.close();
  35. } catch (IOException e) {
  36. e.printStackTrace();
  37. }
  38. }
  39. }

执行效果图如下:

Android(java)学习笔记80:UDP协议发送数据的更多相关文章

  1. Android(java)学习笔记20:UDP协议发送数据

    1. UDP协议发送数据:我们总是先运行接收端,再运行发送端发送端: package cn.itcast_02; import java.io.IOException; import java.net ...

  2. Java基础知识强化之网络编程笔记03:UDP之UDP协议发送数据 和 接收数据

    1. UDP协议发送数据 和 接收数据 UDP协议发送数据: • 创建发送端的Socket对象 • 创建数据,并把数据打包 • 调用Socket对象的发送方法,发送数据包 • 释放资源  UDP协议接 ...

  3. TCP和UDP 协议发送数据包的大小

    在进行UDP编程的时候,我们最容易想到的问题就是,一次发送多少bytes好? 当然,这个没有唯一答案,相对于不同的系统,不同的要求,其得到的答案是不一样的,这里仅对像ICQ一类的发送聊天消息的情况作分 ...

  4. TCP/IP详解学习笔记(6)-UDP协议

    1.UDP简要介绍 UDP是传输层协议,和TCP协议处于一个分层中,但是与TCP协议不同,UDP协议并不提供超时重传,出错重传等功能,也就是说其是不可靠的协议. 2.UDP协议头 2.1.UDP端口号 ...

  5. TCP 和 UDP 协议发送数据包的大小 (转载)

    MTU最大传输单元,这个最大传输单元实际上和链路层协议有着密切的关系,EthernetII帧的结构DMAC+SMAC+Type+Data+CRC由于以太网传输电气方面的限制,每个以太网帧都有最小的大小 ...

  6. java学习笔记(二)之数据部分

    数据类型 java数据类型 基本数据类型 数值型 整型byte/short/int/long   浮点型/double/float   字符型char     布尔型boolean 取值true  f ...

  7. Java学习笔记:输入、输出数据

    相关内容: 输出数据: print println printf 输入数据: Scanner 首发时间:2018-03-16 16:30 输出数据: JAVA中在屏幕中打印数据可以使用: System ...

  8. java学习笔记 (2) —— Struts2类型转换、数据验证重要知识点

    1.*Action.conversion-properties 如(point=com.test.Converter.PointListConverter) 具体操作类的配置文件 2.*Action. ...

  9. Java学习笔记-基础语法ⅩⅠ-UDP、TCP

    网络编程 三要素:IP地址.端口.协议 IP地址:使用ipconfig查看,如果装了VM的话,会有VMnet1.VMnet8和WLAN,net1不能从虚拟机到主机,net8不能从主机到虚拟机,net0 ...

随机推荐

  1. 题目1437:To Fill or Not to Fill:贪心算法解决加油站选择问题(未解决)

    //贪心算法解决加油站选择问题 //# include<iostream> # include<stdio.h> using namespace std; # include& ...

  2. 轻松突击ThreadLocal

    本文出自 代码大湿 代码大湿 ThreadLocal是用来保存线程的本地变量,可以保证每个线程都有一个自己的变量(包括static变量). 本文所有代码请点击我 1 看个实际场景. 我们要设计一个序列 ...

  3. MSSql得到表的结构和字段

    得到数据库中所有的表 select name from sysobjects where xtype='u' and name='{0}' 1.获取表的基本字段属性 --获取SqlServer中表结构 ...

  4. Spring For Android初体验

    Spring For Android是Spring框架的一个扩展,其主要目的在乎简化Android本地应用的开发,这其中包括了你可以使用该项目提供的 RestTemplate来为你的Android客户 ...

  5. Java缓存学习之三:CDN缓存机制

    CDN是什么? 关于CDN是什么,此前网友详细介绍过. CDN是Content Delivery Network的简称,即"内容分发网络"的意思.一般我们所说的CDN加速,一般是指 ...

  6. AutoCAD.NET二次开发:扩展数据之XData

    结果缓存——ResultBuffer 结果缓存即 Autodesk.AutoCAD.DatabaseServices.ResultBuffer 类型,使用 ResultBuffer 对象时需要提供一个 ...

  7. 贪心-poj-2437-Muddy roads

    题目链接: http://poj.org/problem?id=2437 题目意思: 给n个区间,每次可以用长度为L的棒A去覆盖,求将所有区间覆盖至少需要几次.给的区间不覆盖. 解题思路: 简单贪心. ...

  8. MVC神韵---你想在哪解脱!(十一)

    为了实现这一处理,我们需要在MoviesController类中追加第二个Create方法.这个Create方法具有一个[HttpPost]属性,它意味着我们将要用它来处理提交到“/Movies/Cr ...

  9. C++成员变量、构造函数的初始化顺序

    一.C++成员变量初始化 1.普通的变量:一般不考虑啥效率的情况下 可以在构造函数中进行赋值.考虑一下效率的可以再构造函数的初始化列表中进行 2.static 静态变量(本地化数据和代码范围): st ...

  10. MATLAB remove outliers.

    Answer by Richard Willey on 9 Jan 2012 Hi Michael MATLAB doesn't provide a specific function to remo ...