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

 package cn.itcast_02;

 import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/*
* UDP协议发送数据:
* A:创建发送端Socket对象
* B:创建数据,并把数据打包
* C:调用Socket对象的发送方法发送数据包
* D:释放资源
*/
public class SendDemo {
public static void main(String[] args) throws IOException {
// 创建发送端Socket对象
// DatagramSocket()
DatagramSocket ds = new DatagramSocket(); // 创建数据,并把数据打包
// DatagramPacket(byte[] buf, int length, InetAddress address, int port)
// 创建数据
byte[] bys = "hello,udp,我来了".getBytes();//转码
// 长度
int length = bys.length;
// IP地址对象
InetAddress address = InetAddress.getByName("192.168.12.92");
// 端口
int port = 10086;
DatagramPacket dp = new DatagramPacket(bys, length, address, port); // 调用Socket对象的发送方法发送数据包
// public void send(DatagramPacket p)
ds.send(dp); // 释放资源
ds.close();
}
}

接收端:

 package cn.itcast_02;

 import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress; /*
9 * UDP协议接收数据:
10 * A:创建接收端Socket对象
11 * B:创建一个数据包(接收容器)
12 * C:调用Socket对象的接收方法接收数据
13 * D:解析数据包,并显示在控制台
14 * E:释放资源
*/
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
18 // 创建接收端Socket对象
19 // DatagramSocket(int port)

DatagramSocket ds = new DatagramSocket(10086); 22 // 创建一个数据包(接收容器)
23 // DatagramPacket(byte[] buf, int length)

byte[] bys = new byte[1024];
int length = bys.length;
DatagramPacket dp = new DatagramPacket(bys, length); 28 // 调用Socket对象的接收方法接收数据
29 // public void receive(DatagramPacket p)

ds.receive(dp); // 阻塞式

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

这里ds.close():

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

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

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

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

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

 package cn.itcast_03;

 import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress; public class SendDemo {
public static void main(String[] args) throws IOException {
// 创建发送端的Socket对象
DatagramSocket ds = new DatagramSocket(); // 创建数据并打包
byte[] bys = "helloworld".getBytes();
DatagramPacket dp = new DatagramPacket(bys, bys.length,
InetAddress.getByName("192.168.12.92"), 12345); // 发送数据
ds.send(dp); // 释放资源
ds.close();
}
}

接收端:

 package cn.itcast_03;

 import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket; 7 /*
8 * 多次启动接收端:
9 * java.net.BindException: Address already in use: Cannot bind
10 * 端口被占用。
11 */

public class ReceiveDemo {
public static void main(String[] args) throws IOException {
// 创建接收端的Socket对象
DatagramSocket ds = new DatagramSocket(12345); // 创建一个包裹
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys, bys.length); // 接收数据
ds.receive(dp); // 解析数据
String ip = dp.getAddress().getHostAddress();
String s = new String(dp.getData(), 0, dp.getLength());
System.out.println("from " + ip + " data is : " + s); // 释放资源
ds.close();
}
}

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

发送端:

 package cn.itcast_04;

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

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

// 发送数据
ds.send(dp);
} // 释放资源
ds.close();
}
}

接收端:

 package cn.itcast_04;

 import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket; /*
* 多次启动接收端:
* java.net.BindException: Address already in use: Cannot bind
* 端口被占用。
*/
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
// 创建接收端的Socket对象
DatagramSocket ds = new DatagramSocket(12345); while (true) {
// 创建一个包裹
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys, bys.length); // 接收数据
ds.receive(dp); // 解析数据
String ip = dp.getAddress().getHostAddress();
String s = new String(dp.getData(), 0, dp.getLength());
System.out.println("from " + ip + " data is : " + s);
} // 释放资源
32 // 接收端应该一直开着等待接收数据,是不需要关闭,就好比百度服务器是一直开着着,一样的,接收端好比服务器端
33 // ds.close();
}
}

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

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

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

 package cn.itcast_05;

 import java.io.IOException;
import java.net.DatagramSocket; /*
* 通过多线程改进刚才的聊天程序,这样我就可以实现在一个窗口发送和接收数据了
*/
public class ChatRoom {
public static void main(String[] args) throws IOException {
DatagramSocket dsSend = new DatagramSocket();
DatagramSocket dsReceive = new DatagramSocket(12306); SendThread st = new SendThread(dsSend);
ReceiveThread rt = new ReceiveThread(dsReceive); Thread t1 = new Thread(st);
Thread t2 = new Thread(rt); t1.start();
t2.start();
}
}
 package cn.itcast_05;

 import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket; public class ReceiveThread implements Runnable {
private DatagramSocket ds; public ReceiveThread(DatagramSocket ds) {
this.ds = ds;
} @Override
public void run() {
try {
while (true) {
// 创建一个包裹
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys, bys.length); // 接收数据
ds.receive(dp); // 解析数据
String ip = dp.getAddress().getHostAddress();
String s = new String(dp.getData(), 0, dp.getLength());
System.out.println("from " + ip + " data is : " + s);
}
} catch (IOException e) {
e.printStackTrace();
}
} }
 package cn.itcast_05;

 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 SendThread implements Runnable { private DatagramSocket ds; public SendThread(DatagramSocket ds) {
this.ds = ds;
} @Override
public void run() {
try {
// 封装键盘录入数据
BufferedReader br = new BufferedReader(new InputStreamReader(
System.in));
String line = null;
while ((line = br.readLine()) != null) {
if ("886".equals(line)) {
break;
} // 创建数据并打包
byte[] bys = line.getBytes();
// DatagramPacket dp = new DatagramPacket(bys, bys.length,
// InetAddress.getByName("192.168.12.92"), 12345);
DatagramPacket dp = new DatagramPacket(bys, bys.length,
InetAddress.getByName("192.168.12.255"), 12306); // 发送数据
ds.send(dp);
} // 释放资源
ds.close();
} catch (IOException e) {
e.printStackTrace();
}
} }

执行效果图如下:

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

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

    UDP协议发送数据:我们总是先运行接收端,再运行发送端发送端: 1 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学习笔记20(String类应用、StringBuffer类、StringBuilder类)

    1.获取指定字符串中大小写和数字的个数: package demo; public class StringTest { public static void main(String[] args) ...

  7. java学习笔记20(Arraylist复习,Collection接口方法,迭代器,增强型for循环)

    集合:集合是Java提供的一种容器,可以用来存储多个数据: 集合与数组的区别:集合的长度是可变的,数组的长度是固定的 集合中存储的数据必须是引用类型数据: ArrayList回顾: public cl ...

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

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

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

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

随机推荐

  1. PIE SDK矢量唯一值渲染

    1. 功能简介 图层的唯一值渲染即是根据矢量图层的某一个数值字段的属性值,按照值的不同大小设置不同的显示符号.属性数值相等的所有要素归为同一种类,即同一符号. 2. 功能实现说明 2.1. 实现思路及 ...

  2. PIE SDK面元素的绘制

    1. 功能简介 在数据的处理中会用到线元素的绘制,目前PIE SDK支持IFillSymbol接口,FillSymbol对象是用于修饰填充面状对象的符号,它包括MarkerFillSymbol(由点状 ...

  3. URL篇之URL

    URL(统一资源定位)是网络上使用的资源定位的方案,它是URI(由URL和URN组成)的子集. URL的通用格式 <scheme>://<user>:<password& ...

  4. 【3dsMax安装失败,如何卸载、安装3dMax 2016?】

    AUTODESK系列软件着实令人头疼,安装失败之后不能完全卸载!!!(比如maya,cad,3dsmax等).有时手动删除注册表重装之后还是会出现各种问题,每个版本的C++Runtime和.NET f ...

  5. 015-GenericEncodingFilter模板【解决全局乱码】

    package ${enclosing_package}; import java.io.IOException; import java.io.UnsupportedEncodingExceptio ...

  6. java线程中的 sleep() wait() yield()

    sleep()方法是让线程休眠  可以指定时间  其实就是让线程进入阻塞状态  指定的时间过后 进入就绪状态  不释锁 相当于抱着锁睡觉 wait()  让线程进入等待状态  被唤醒后才会继续执行   ...

  7. js消息提示框插件-----toastr用法

     (本文系转载) 因为个人项目中有一个提交表单成功弹出框的需求,从网上找了一些资料,发现toastr这个插件的样式还是不错的.所以也给大家推荐下,但是网上的使用资料不是很详细,所以整理了一下,希望能给 ...

  8. rabbitmq 命令&& rabbitmq教程(一)

    先来个官方教程 http://www.rabbitmq.com 在windows 下 命名 去掉sudo 我是在windows下测试 用net调用 常用命令 控制台命令:sudo rabbitmqct ...

  9. 跨页面传值之QueryString

    跨页面传值常用方法 1.QueryString 2.Form-post控件传递 3.Cookies传递 4.Application传递 5.Session传递(灵活强大) 1.query传值 http ...

  10. 05.if结构

    分支结构:if  if-else 选择结构:if else-if switch-case 循环结构:while do-while for foreach if语句 语法: if(判断条件) { //要 ...