X-Teamer提煉商業萬有引力模型, 低成本定製化開發
阿新 • • 發佈:2019-02-19
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