Java模擬UDP通信示例代碼
Java基礎:模擬UDP通信
1、一次發(fā)送,一次接收
1.1、發(fā)送方
// 發(fā)送端,不需要連接服務器
public class UdpClientDemo {
public static void main(String[] args) throws Exception {
// 1. 發(fā)送數據包需要一個Socket
DatagramSocket socket = new DatagramSocket();
// 1.2 建立一個包
String msg = "你好";
InetAddress localhost = InetAddress.getByName("localhost");
System.out.println(localhost);
int port = 8080;
/*
通過UDP發(fā)送消息,需要通過 包 來發(fā)送,--> DatagramPacket(),該方法有多種重載形式,以下使用參數列表最多的那個
參數:
- 要發(fā)送的 消息 的字節(jié)數組
- 從字節(jié)數組的哪個位置開始發(fā)送
- 發(fā)送的長度
- 對方的 IP地址
- 對方的端口號
*/
DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);
// 2. 發(fā)送數據包
socket.send(packet);
socket.close();
}
}
1.2、接收方
// 接收端,接收端需要保證存在,否則接收不到,所以需要提前開啟
public class UdpServerDemo {
public static void main(String[] args) throws Exception {
// 1. 接收也需要一個Socket,并且要開啟接收的端口
DatagramSocket socket = new DatagramSocket(8080);
// 需要一個字節(jié)數組來接收數據
byte[] buffer = new byte[1024];
// 1.2 封裝數據包
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
// 2. 接收數據,阻塞式接收:一直處于監(jiān)聽狀態(tài)
socket.receive(packet);
// 關閉套接字
socket.close();
// 輸出一下
System.out.println(packet.getAddress().getHostAddress());
// trim():為了去除多余的空格
System.out.println(new String(packet.getData()).trim());
}
}
2、多次發(fā)送,多次接收
一方多次發(fā)送,一方多次接收,加上一個 while(true) {} 死循環(huán),并規(guī)定在什么情況下退出即可。
2.1、發(fā)送方
public class ChatSenderDemo {
public static void main(String[] args) throws Exception {
// 使用Socket來接收
DatagramSocket socket = new DatagramSocket();
while (true) {
// 準備發(fā)送包裹,從鍵盤接收數據
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
// 讀取一行
String data = reader.readLine();
byte[] dataBytes = data.getBytes();
DatagramPacket packet = new DatagramPacket(dataBytes, dataBytes.length, new InetSocketAddress("127.0.0.1", 6666));
// 發(fā)送
socket.send(packet);
// 什么時候退出
if ("bye".equals(data)) {
break;
}
}
// 關閉
socket.close();
}
}
2.2、接收方
public class ChatReceiveDemo {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(6666);
while (true) {
// 準備接收數據包裹
byte[] buffer = new byte[1024];
// 用來接收數據
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
// 接收包裹,阻塞時接收
socket.receive(packet);
// 接收到的數據
String receiveData = new String(packet.getData()).trim();
// 打印到控制臺
System.out.println(receiveData);
// 什么時候退出
if ("bye".equals(receiveData)) {
break;
}
}
// 關閉
socket.close();
}
}
3、模擬雙方通信
模擬雙方使用UDP通信,需要開啟兩個線程,并對以上代碼進行【共性提取】,進一步進行抽象。
由此,雙方可以通過指定的端口來互相發(fā)送消息。
3.1、發(fā)送方的線程
// 開啟多線程需要實現 Runnable 接口,實現 run()方法
public class TalkSender implements Runnable {
// 網絡套接字,發(fā)送需要
DatagramSocket socket = null;
// 緩沖讀取流
BufferedReader reader = null;
// 開啟哪個端口接收
private int fromPort;
// 對方的 IP
private String toIP;
// 對方的端口
private int toPort;
// 通過構造方法進行初始化
public TalkSender(int fromPort, String toIP, int toPort) {
this.fromPort = fromPort;
this.toIP = toIP;
this.toPort = toPort;
try {
socket = new DatagramSocket(fromPort);
} catch (SocketException e) {
e.printStackTrace();
}
}
// 重寫 run()方法,設置線程任務
@Override
public void run() {
while (true) {
String data = null;
try {
// 準備發(fā)送包裹,從鍵盤接收數據
reader = new BufferedReader(new InputStreamReader(System.in));
// 讀取一行
data = reader.readLine();
byte[] dataBytes = data.getBytes();
DatagramPacket packet = new DatagramPacket(dataBytes, dataBytes.length, new InetSocketAddress(toIP, toPort));
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
// 什么時候退出
if ("bye".equals(data)) {
break;
}
}
// 關閉
socket.close();
}
}
3.2、接收方的線程
public class TalkReveicer implements Runnable {
DatagramSocket socket = null;
// 從哪個端口接收
private int formPort;
// 發(fā)送方是誰
private String who;
public TalkReveicer(int formPort, String who) {
this.formPort = formPort;
this.who = who;
try {
socket = new DatagramSocket(formPort);
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (true) {
String receiveData = null;
try {
// 準備接收數據包裹
byte[] buffer = new byte[1024];
// 接收數據
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
// 接收數據,阻塞式
socket.receive(packet);
// 接收到的數據
receiveData = new String(packet.getData());
System.out.println(who + ":" + receiveData.trim());
} catch (IOException e) {
e.printStackTrace();
}
// 什么時候退出
if ("bye".equals(receiveData)) {
break;
}
}
// 關閉
socket.close();
}
}
3.3、模擬學生
// 學生端
public class TalkStudent {
public static void main(String[] args) {
// 開啟 5555端口,發(fā)送到本機的 6666端口
new Thread(new TalkSender(5555, "localhost", 6666)).start();
// 規(guī)定使用 7777 端口接收老師發(fā)送的消息
new Thread(new TalkReveicer(7777, "老師")).start();
}
}
3.4、模擬老師
// 教師端
public class TalkTeacher {
public static void main(String[] args) {
// 開啟 8888端口,發(fā)送到本機的 7777端口
new Thread(new TalkSender(8888, "localhost", 7777)).start();
// 規(guī)定使用 6666 端口接收學生發(fā)送的消息
new Thread(new TalkReveicer(6666, "學生")).start();
}
}
總結:
使用UDP通信,其實主要的步驟分為三步:
1 用 DatagramSocket() 來開啟端口,通過開啟端口聊天。
2 用DatagramPacket() 來發(fā)送或者接收數據。
3 關閉 DatagramSocket,釋放資源。
以上就是Java模擬UDP通信示例代碼的詳細內容,更多關于Java模擬UDP通信的資料請關注腳本之家其它相關文章!
相關文章
idea快速搭建spring cloud注冊中心與注冊的方法
這篇文章主要介紹了idea快速搭建spring cloud注冊中心與注冊的方法,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07
如何在 Linux 上搭建 java 部署環(huán)境(安裝jdk/tomcat/mys
這篇文章主要介紹了如何在 Linux 上搭建 java 部署環(huán)境(安裝jdk/tomcat/mysql) + 將程序部署到云服務器上的操作),本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-01-01
Java設計模式之Template?Pattern模板模式詳解
這篇文章主要介紹了Java設計模式之Template?Pattern模板模式詳解,模板模式(Template?Pattern)行為型模式之一,抽象父類定義一個操作中的算法的骨架,而將一些步驟延遲到子類中,需要的朋友可以參考下2023-10-10
解決SpringBoot內嵌Tomcat并發(fā)容量的問題
這篇文章主要介紹了解決SpringBoot內嵌Tomcat并發(fā)容量的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06
使用StringRedisTemplate操作Redis方法詳解
這篇文章主要為大家介紹了使用StringRedisTemplate操作Redis方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08

