Java实现UDP功能
部分內(nèi)容參考
UDP的Java支持
UDP協(xié)議提供的服務不同于TCP協(xié)議的端到端服務,它是面向非連接的,屬于不可靠的協(xié)議,UDP套接字在使用前不需要進行連接。實際上,UDP協(xié)議只實現(xiàn)了兩個功能:
1.在IP協(xié)議的基礎上添加了端口
2.對傳輸過程可能產(chǎn)生的數(shù)據(jù)錯誤進行了檢測,并拋棄已經(jīng)損壞的數(shù)據(jù)
Java通過DatagramPacket類和DatagramSocket類來使用UDP套接字,客戶端和服務端都通過DatagramSocket的send()方法和receive()方法來發(fā)送和接收數(shù)據(jù),用DatagramPacket來包裝需要發(fā)送或者接收到的數(shù)據(jù)。發(fā)送信息時,Java創(chuàng)建一個包含待發(fā)送信息的DatagramPacket實例,并將其作為參數(shù)傳遞給DatagramSocket實例的send()方法;接收信息時,Java程序首先創(chuàng)建一個DatagramPacket實例,該實例預先分配了一些空間,并將接收到的信息存放在該空間中,然后把該實例作為參數(shù)傳遞給DatagramSocket實例的receive()方法。在創(chuàng)建DatagramPacket實例時,要注意:如果該實例用來包裝待接收的數(shù)據(jù),則不指定數(shù)據(jù)來源的遠程主機和端口,只需要指定一個緩存數(shù)據(jù)的byte數(shù)組即可(在調(diào)用receive()方法接收到數(shù)據(jù)后,源地址和端口等信息會字段包含在DatagramPacket實例中),而如果該實例用來包裝待發(fā)送的數(shù)據(jù),則要指定要發(fā)送到的目的主機和端口。
UDP的通信建立步驟
UDP客戶端首先向被動等待聯(lián)系的服務器發(fā)送一個數(shù)據(jù)報文。一個典型的UDP客戶端要經(jīng)過一下三個操作:
1.創(chuàng)建一個DatagramSocket實例,可以有選擇的對本地地址和端口號進行設置,如果設置了端口號,則客戶端會在端口號上監(jiān)聽從服務器端發(fā)送來的數(shù)據(jù)
2.使用DatagramSocket實例的send()和receive()方法來發(fā)送和接收DatagramPacket實例,進行通信
3.通信完成后,調(diào)用DatagramSocket實例的close()方法來關閉套接字
由于UDP是無連接的,因UDP服務端不需要等待客戶端的請求以建立連接。另外,UDP服務器為所有通信使用同一套接字,這點與TCP服務器不同,TCP服務則為每個成功的accept()方法創(chuàng)建一個新的套接字。一個典型的UDP服務端要經(jīng)過下面三步操作:
1.創(chuàng)建一個DatagramSocket實例,指定本地端口號,并可以有選擇的指定本地地址,此時服務器已經(jīng)準備好從任何客戶端接收數(shù)據(jù)報文
2.使用DatagramSocket實例的receive()方法接收一個DatagramPacket實例,當receive()方法返回時,數(shù)據(jù)報文就包含了客戶端的地址,這樣就知道了回復信息應該發(fā)送到什么地方
3.使用DatagramSocket實例的send()方法向服務器返回DatagramPacket
java實現(xiàn)源客戶端程序如下:
import java.io.IOException;//導入IOException類 import java.net.DatagramPacket;//導入DatagramPacket類 import java.net.DatagramSocket;//導DatagramSocket入 import java.net.InetAddress;//導入InetAddress類 import java.util.Scanner;//導入Scanner類 /** 客戶端*/ public class UDPClient {//公共類public static void main(String[] args) throws IOException {//主程序入口/** 向服務器端發(fā)送數(shù)據(jù)*/ InetAddress address = InetAddress.getByName("localhost"); // 1.定義服務器的地址、端口號、數(shù)據(jù)int port = 8800;//定義端口類型while(true) {//通過循環(huán)不停的向客戶端發(fā)送和接受數(shù)據(jù)Scanner scanner = new Scanner(System.in);//從鍵盤接受數(shù)據(jù)String send = scanner.nextLine();//nextLine方式接受字符串byte[] data = send.getBytes();//將接收到的數(shù)據(jù)變成字節(jié)數(shù)組 DatagramPacket packet = new DatagramPacket(data, data.length, address, port);//2.創(chuàng)建數(shù)據(jù)報,包含發(fā)送的數(shù)據(jù)信息 DatagramSocket socket = new DatagramSocket(); // 3.創(chuàng)建DatagramSocket對象 socket.send(packet);// 4.向服務器端發(fā)送數(shù)據(jù)報/** 接收服務器端響應的數(shù)據(jù)*/ byte[] data2 = new byte[1024];//創(chuàng)建字節(jié)數(shù)組 DatagramPacket packet2 = new DatagramPacket(data2, data2.length);// 1.創(chuàng)建數(shù)據(jù)報,用于接收服務器端響應的數(shù)據(jù) socket.receive(packet2);// 2.接收服務器響應的數(shù)據(jù)//3.讀取數(shù)據(jù)String reply = new String(data2, 0, packet2.getLength());//創(chuàng)建字符串對象System.out.println("我是客戶端,服務器說:" + reply);//輸出提示信息socket.close();//4.關閉資源}} }java源程序服務端如下:
import java.io.IOException;//導入IOException類 import java.net.DatagramPacket;//導入DatagramPacket類 import java.net.DatagramSocket;//導入DatagramSocket類 import java.net.InetAddress;//導入InetAddress類 import java.util.Scanner;//導入Scanner類/** 服務器端,實現(xiàn)基于UDP的用戶登陸*/ public class UDPServer {//公共類public static void main(String[] args) throws IOException {//主程序入口/** 接收客戶端發(fā)送的數(shù)據(jù)*/ DatagramSocket socket = new DatagramSocket(8800); // 1.創(chuàng)建服務器端DatagramSocket,指定端口// 2.創(chuàng)建數(shù)據(jù)報,用于接收客戶端發(fā)送的數(shù)據(jù)byte[] data = new byte[1024];//創(chuàng)建字節(jié)數(shù)組,指定接收的數(shù)據(jù)包的大小DatagramPacket packet = new DatagramPacket(data, data.length);// 3.接收客戶端發(fā)送的數(shù)據(jù)System.out.println("****服務器端已經(jīng)啟動,等待客戶端發(fā)送數(shù)據(jù)");//輸出提示信息while(true) {//通過循環(huán)不停的向客戶端發(fā)送數(shù)據(jù)和接收數(shù)據(jù)socket.receive(packet);// 此方法在接收到數(shù)據(jù)報之前會一直阻塞// 4.讀取數(shù)據(jù) String info = new String(data, 0, packet.getLength());//創(chuàng)建字符串對象System.out.println("我是服務器,客戶端說:" + info);//輸出提示信息 /** 向客戶端響應數(shù)據(jù)*/// 1.定義客戶端的地址、端口號、數(shù)據(jù) InetAddress address = packet.getAddress();//獲取發(fā)送端的地址int port = packet.getPort();//獲取 發(fā)送端進程所綁定的端口 Scanner scanner = new Scanner(System.in);//從鍵盤接受數(shù)據(jù) String send = scanner.nextLine();//nextLine方式接受字符串 byte[] data2 = send.getBytes();//將接收到的數(shù)據(jù)轉換為字節(jié)數(shù)組DatagramPacket packet2 = new DatagramPacket(data2, data2.length,address,port);// 2.創(chuàng)建數(shù)據(jù)報,包含響應的數(shù)據(jù)信息 socket.send(packet2); // 3.響應客戶端 } } }總結
以上是生活随笔為你收集整理的Java实现UDP功能的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [vue] vue常用的修饰符有哪些?列
- 下一篇: java实现生成pdf_详解Java生成