首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 編程那些事兒 106:UDP 網絡編程進階——多次交換與多線程並發服務端

     編輯:Java 相關知識

UDP 簡單示例:客戶端發送系統時間,服務端回饋 "OK"

客戶端代碼:

package udp;
import java.net.*;
import java.util.*;

public class SimpleUDPClient {
public static void main(String[] args) {
DatagramSocket ds = null;
DatagramPacket sendDp, receiveDp;
String serverHost = "127.0.0.1";
int serverPort = 10010;
try {
ds = new DatagramSocket();
Date d = new Date();
String content = d.toString();
byte[] data = content.getBytes();
InetAddress address = InetAddress.getByName(serverHost);
sendDp = new DatagramPacket(data, data.length, address, serverPort);
ds.send(sendDp);

byte[] b = new byte[1024];
receiveDp = new DatagramPacket(b, b.length);
ds.receive(receiveDp);
byte[] response = receiveDp.getData();
int len = receiveDp.getLength();
String s = new String(response, 0, len);
System.out.println("服務器端回饋為:" + s);
} catch (Exception e) { e.printStackTrace(); }
finally { try { ds.close(); } catch (Exception e) {} }
}
}

流程:建立連接 → 獲取本地時間 → 構造發送包含地址端口的 DatagramPacket → 發送 → 構造接收包 → 接收回饋 → 輸出 → 關閉。

服務端代碼:

package udp;
import java.net.*;

public class SimpleUDPServer {
public static void main(String[] args) {
DatagramSocket ds = null;
DatagramPacket sendDp, receiveDp;
final int PORT = 10010;
try {
ds = new DatagramSocket(PORT);
System.out.println("服務器端已啟動:");
byte[] b = new byte[1024];
receiveDp = new DatagramPacket(b, b.length);
ds.receive(receiveDp);
InetAddress clientIP = receiveDp.getAddress();
int clientPort = receiveDp.getPort();
byte[] data = receiveDp.getData();
int len = receiveDp.getLength();
System.out.println("客戶端IP:" + clientIP.getHostAddress());
System.out.println("客戶端端口:" + clientPort);
System.out.println("客戶端發送內容:" + new String(data, 0, len));

String response = "OK";
byte[] bData = response.getBytes();
sendDp = new DatagramPacket(bData, bData.length, clientIP, clientPort);
ds.send(sendDp);
} catch (Exception e) { e.printStackTrace(); }
finally { try { ds.close(); } catch (Exception e) {} }
}
}

服務端監聽端口,receive 阻塞等待數據。收到後提取客戶端 IP/端口、輸出內容,回饋 "OK"。同樣存在客戶端無法多次交換、服務端不支援多客戶端問題。

UDP 特性:無狀態

UDP 不建立虛擬連接,最大特點是「無狀態」:服務端僅從數據包獲取信息,無法識別發送者身份,要求發送內容攜帶更多標識信息。

進階結構:客戶端多次發送 + 服務端多線程並發

原理同 TCP:客戶端循環發送/接收,服務端循環接收並啟動線程處理每個包。

多次發送客戶端

package udp;
import java.net.*;
import java.util.*;

public class MulUDPClient {
public static void main(String[] args) {
DatagramSocket ds = null;
DatagramPacket sendDp, receiveDp;
String serverHost = "127.0.0.1";
int serverPort = 10012;
try {
ds = new DatagramSocket();
InetAddress address = InetAddress.getByName(serverHost);
byte[] b = new byte[1024];
receiveDp = new DatagramPacket(b, b.length);
System.out.println("客戶端准備完成");
for (int i = 0; i < 30; i++) {
Date d = new Date();
String content = d.toString();
byte[] data = content.getBytes();
sendDp = new DatagramPacket(data, data.length, address, serverPort);
ds.send(sendDp);
Thread.sleep(10);
ds.receive(receiveDp);
byte[] response = receiveDp.getData();
int len = receiveDp.getLength();
String s = new String(response, 0, len);
System.out.println("服務器端回饋為:" + s);
}
} catch (Exception e) { e.printStackTrace(); }
finally { try { ds.close(); } catch (Exception e) {} }
}
}

循環 30 次發送時間,間隔 10ms,每次接收回饋。

並發服務端

package udp;
import java.net.*;

public class MulUDPServer {
public static void main(String[] args) {
DatagramSocket ds = null;
DatagramPacket receiveDp;
final int PORT = 10012;
byte[] b = new byte[1024];
receiveDp = new DatagramPacket(b, b.length);
try {
ds = new DatagramSocket(PORT);
System.out.println("服務器端已啟動:");
while (true) {
ds.receive(receiveDp);
new LogicThread(ds, receiveDp);
}
} catch (Exception e) { e.printStackTrace(); }
finally { try { ds.close(); } catch (Exception e) {} }
}
}

主循環接收包,啟動 LogicThread 處理。

邏輯處理線程

package udp;
import java.net.*;

public class LogicThread extends Thread {
DatagramSocket ds;
DatagramPacket dp;

public LogicThread(DatagramSocket ds, DatagramPacket dp) {
this.ds = ds; this.dp = dp; start();
}

public void run() {
try {
byte[] data = dp.getData();
int len = dp.getLength();
InetAddress clientAddress = dp.getAddress();
int clientPort = dp.getPort();
System.out.println("客戶端IP:" + clientAddress.getHostAddress());
System.out.println("客戶端端口號:" + clientPort);
System.out.println("客戶端發送內容:" + new String(data, 0, len));
byte[] b = "OK".getBytes();
DatagramPacket sendDp = new DatagramPacket(b, b.length, clientAddress, clientPort);
ds.send(sendDp);
} catch (Exception e) { e.printStackTrace(); }
}
}

線程處理單次 UDP 通訊,輸出信息並回饋 "OK"。因 UDP 可能丟包導致阻塞,生產環境建議發送端也採用線程。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved