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)学习笔记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基础知识强化之网络编程笔记06:TCP之TCP协议发送数据 和 接收数据

    1. TCP协议发送数据 和 接收数据 TCP协议接收数据:• 创建接收端的Socket对象• 监听客户端连接.返回一个对应的Socket对象• 获取输入流,读取数据显示在控制台• 释放资源 TCP协 ...

随机推荐

  1. MFC 鼠标 移动到某控件时 修改鼠标形状为手的形状

    响应窗体的 OnSetCursor 消息响应 鼠标移动到某空间时改变 形状 BOOL CQQBulkDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT m ...

  2. C#的数组

    一维数组: 定义数组 int[] 变量名=new int [n]; 例一:输入班级人数,再输入每个人的姓名. 例二:输入班级人数,输入每个人的分数,求平均分 冒泡排序: 二维数组: 定义二维数组 in ...

  3. adroid 目录

    安桌程式安装后存在目录:\手机存储\Android\data 一: //  获取当前程序路径 getApplicationContext().getFilesDir().getAbsolutePath ...

  4. 2016.07.14,英语,《Vocabulary Builder》Unit 25

    verb: comes from the Latin verbum, meaning 'word'. verbally: ['vɜːbəli] adv. 口头地,词句地, 逐字地 verbalize: ...

  5. com.google.guava 包解析 ——Google Guava官方教程(中文版)

    全网址           http://ifeve.com/google-guava/ 竹子博客:  http://www.cnblogs.com/peida/archive/2013/06/08/ ...

  6. java多线程为什么要用while而不是if

    对于java多线程的wait()方法,我们在jdk1.6的说明文档里可以看到这样一段话 从上面的截图,我们可以看出,在使用wait方法时,需要使用while循环来判断条件十分满足,而不是if,那么我们 ...

  7. Windows Xp Home Edition 安装IIS组件

    问题描述: 在虚拟机(操作系统是Windows Xp Home Edition)中安装Sql Server 2005的时候警告缺少IIS相关组件,控制面板"添加/删除组件"中也没有 ...

  8. Stammering Aliens

    Stammering Aliens Time Limit: 2000MS   Memory Limit: 65536K       Description Dr. Ellie Arroway has ...

  9. Java Mac电脑配置java环境,JAVA IDE eclipse开发svn使用

    .SELECT TOP 规定返回记录的数目(对于大型数据库很有用的) SELECT TOP number|percent column--name FROM table; 1.2 SELECT LIM ...

  10. vue-入门

    数据绑定   <!--步骤1:创建html文件--> <!DOCTYPE html> <html lang="en"> <head> ...