UDP 在无线通信中用处非常之广, 比如某个终端硬件采集数据, 会使用UDP的方式进行通信。 比如这是我们当前的一个需求架构示意图:
图: 采用UDP协议的产品架构示意图
解释:
① 表示GPS向Server传输数据, 这个就是【终端GPS所在公司】提供的协议接口
② Server向GPS发送命令, 大部分是配置相关的服务, 或者升级命令,目前大体需要这样的功能,依然是【终端GPS所在公司】提供的接口:
- 设置回传周期时间
- 设置指定传输的数据服务器IP地址和端口号
- 设置自动升级包的IP地址
- 查询所有设置接口
这些接口采用的都是UDP通信协议, 因此我在做整体架构之前做了基本的Demo以满足后续业务需求。
本文为UDP的一个小程序。
包括两个部分:
1. 在本机监听某个端口, 接受其它PC发过来的数据
2. 本机主动向其它PC的特定端口发送数据
主程序UDPApplication.java:
package cn.com.sany.udp;
/**
* 启动UDP线程
*
*
*/
public class UDPApplication {
public static void main(String[] args)
{
int len = args.length;
if (len != 3)
{
System.out.println("用法错误, 正确用法如下:");
System.out.println("-p 10.0.6.217 1122 (主动模式的设置, 指明对方的端口号和IP地址)");
System.out.println("-n 10.0.6.217 1122 (被动模式的设置, 指明本地的端口号和IP地址)");
return;
}
String mode = args[0];
String ip = args[1];
String portString = args[2];
int port = 0;
try{
port = Integer.valueOf(portString);
}
catch (Exception e)
{
e.printStackTrace();
}
if(mode.equalsIgnoreCase("-p"))
{
testPositive(ip, port);
return;
}
if(mode.equalsIgnoreCase("-n"))
{
testNegtive(ip, port);
return;
}
System.out.println("用法错误, 正确用法如下:");
System.out.println("-p 10.0.6.217 1122 (主动模式的设置, 指明对方的端口号和IP地址)");
System.out.println("-n 10.0.6.217 1122 (被动模式的设置, 指明本地的端口号和IP地址)");
}
/**
* 测试被动接收UDP信息
* 侦听本机所在PC的端口
*/
public static void testNegtive(String ip, int port)
{
final UDPNegtive un = new UDPNegtive(port, ip);
un.process();
}
/**
* 测试主动发送UDP信息
* 往指定的PC(即知道远程IP以及端口)
*
*/
public static void testPositive(String ip, int port)
{
final UDPPositive up = new UDPPositive(ip, port);
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (true)
{
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
up.sendUdpData();
}
}
});
t.start();
}
}
主动发送的UDP程序: 本机主动向其它PC的特定端口发送数据
package cn.com.sany.udp;
import java.net.DatagramSocket;
import java.net.SocketException;
/**
* UDP主动发送
*
* 1. 明确对方的端口号, 向对方主动发送消息, 如心跳消息
* 2. 不断接受到对方的回应
*
*
*/
public class UDPPositive {
private boolean isStoped;
private String serverIP;
private int serverPort;
private DatagramSocket socket;
public UDPPositive(String serverIP, int serverPort)
{
this.serverIP = serverIP;
this.serverPort = serverPort;
try {
socket = new DatagramSocket();
} catch (SocketException e) {
e.printStackTrace();
return;
}
new Thread(new Runnable() {
@Override
public void run() {
//接收线程
//接收线程
while(!isStoped){
UDPTool.receiveData(socket);
}
}
}).start();
}
/**
* 发送消息[这里以心跳为例]
*/
public void sendUdpData()
{
byte[] data = new byte[]{0x30,0x30,0x00,0x00,0x01,0x5E,0x5D,0x59,0x1F,0x00,0x00,0x0E,(byte)0xA2,0x01};
UDPTool.sendData(serverIP, serverPort, data, socket);
System.out.println(socket.getLocalPort() + "本地端口");
}
}
被动接收的UDP程序: 在本机监听某个端口, 接受其它PC发过来的数据
package cn.com.sany.udp;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* UDP被动发送消息
* 1. 不知道对方的IP
* 2. 仅仅在本地的端口接收消息
* 3. 接受到消息后, 可以发送回应, 但这里省略该步骤
*
*/
public class UDPNegtive {
private boolean isStoped;
private DatagramSocket socket;
public UDPNegtive(int port, String ip)
{
try {
InetAddress add = InetAddress.getByName(ip);
socket = new DatagramSocket(port, add);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void process()
{
new Thread(new Runnable() {
@Override
public void run() {
//接收线程
while(!isStoped){
UDPTool.receiveData(socket);
}
}
}).start();
}
}
本程序用到的代码, 附调试工具NetAssis