UDP通訊協議


常見的通訊協議有udp和tcp。

先來簡單了解一下這兩個協議各自的特點:

UDP:

--將數據及源、目的封裝在數據包中,不需要建立連接;

--每個數據包的大小限制在64k以內;

--因無連接,是不可靠協議;

--不需要建立連接,所以傳輸速度快,但是容易丟失數據;

總之:Udp是面向無連接的通訊協議,傳輸數據時,不管對端服務是否啟動,直接發送。

日常中使用Udp技術的軟件有:飛秋、視頻會議等;

 

TCP:

--建立連接,形成傳輸數據的通道;

--在連接中進行大的數據量傳輸;

--通過三次握手完成連接,是可靠協議;

--必須建立連接,效率會稍低;

日常中使用Tcp技術的軟件有:打電話的場景,下載。

 

了解了以上兩種常用的通訊協議之后,再認識一下網絡通訊的機制:Socket  

Socket:

--就是為網絡服務提供的一種機制;

--通信的兩端都有Socket;

--網絡通信其實就是Socket建的通信;

--數據再兩個Socket間通過 IO 傳輸。

也可以這樣理解:Socket就像連接航線兩端的港口。

 

============================優雅的分割線============================

 

我們在實現網絡編程時,最重要的是要理解並掌握其實現的原理:

下面先講解一下Udp傳輸的原理:

--1、Udp傳輸技術基於 DatagramSocket 與 DatagramPacket對象;

--2、建立發送端、接收端;

--3、建立數據包;

--4、調用Socket的發送接收方法;

--5、關閉Socket;

--6、發送端和接收端是兩個獨立的運行程序;

 

下面來看一個簡單Udp傳輸Demo:

//發送端:

package com.shindo.java.udp;

import java.net.*;

/**
 * 需求:通過Udp傳輸方式,將一段文字數據發送 出去;
 * 
 * 思路:
 * 1、建立UdpSocket服務;
 * 2、提供數據,並將數據封裝到數據包中;
 * 3、通過Socket服務的發送功能,將數據包發出去
 * 4、關閉資源
 */
public class UdpSend {
    public static void main(String[] args)throws Exception{
        //1、創建Udp服務,通過DatagramSocket對象
        DatagramSocket ds = new DatagramSocket();
        
        //2、確定數據,並封裝成數據包
        byte[] buf = "This's UdpSend test first Demo".getBytes();
        
        /*DatagramPacket(byte[] buf, int length, InetAddress address, int port) 
              構造數據報包,用來將長度為 length 的包發送到指定主機上的指定端口號。
         */
         DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),11010);
         
         //3、通過Socket服務,將已有的數據包發送出去,通過send方法
         ds.send(dp);
         
         Thread.sleep(10000);
         //4、關閉資源
         ds.close();
    }
}
View Code

 

//接收端:

package com.shindo.java.udp;
import java.net.*;
/**
 * 需求:定義一個應用程序,用於接收Udp協議傳輸的數據並處理
 * 
 * 思路:
 * 1、定義UdpSocket服務,並監聽一個端口;
 * 2、定義個數據包,因為要存儲接收到的字節數據--數據包對象中封裝了提取字節數據信息的方法;
 * 3、通過Socket服務的receive方法將收到的數據存入已定義好的數據包中;
 * 4、通過數據包對象的特有功能,將這些不同的數據去除,打印在控制台上;
 * 5、關閉資源
 */
public class Udpreceive {
    public static void main(String[] args)throws Exception{
        //創建UdpSocket,建立端點
        DatagramSocket ds = new DatagramSocket(11010);
        
        while(true){
            //2、定義數據包用於存儲數據
            byte[] buf = new byte[1024];
            /*
             * DatagramPacket(byte[] buf, int length) 
                  構造 DatagramPacket,用來接收長度為 length 的數據包。
             */
            DatagramPacket dp = new DatagramPacket(buf,buf.length);
            
            //3、通過數服務的receive方法,將收到的數據存入數據包中
            ds.receive(dp);
            
            //4、通過數據包的方法獲取其中的數據
            String ip = dp.getAddress().getHostAddress();
            System.out.println(ip + "..........is connected");
            String data = new String(dp.getData(),0,dp.getLength());//只打印接收數據的長度,不打印全部緩沖流
            System.out.println(data);
            int port = dp.getPort();
            System.out.println("port:" + port);
            
            //5、關閉資源
            ds.close();
        }
    }
}
View Code

 

運行結果:

127.0.0.1..........is connected
This's UdpSend test first Demo
port:52793
Exception in thread "main" java.net.SocketException: Socket closed
    at java.net.PlainDatagramSocketImpl.receive0(Native Method)
    at java.net.PlainDatagramSocketImpl.receive(PlainDatagramSocketImpl.java:136)
    at java.net.DatagramSocket.receive(DatagramSocket.java:725)
    at com.shindo.java.udp.Udpreceive.main(Udpreceive.java:28)

 

============================優雅的分割線============================

上面的Demo我們可以看到只是實現了簡單的客戶端發送,服務端讀取並展示的過程。而且客戶端只能發送特定的內容:This's UdpSend test first Demo

我們下面就把客戶端改寫一下,讓它能夠讀取鍵盤錄入的信息:

//發送端:使用鍵盤錄入信息

package com.shindo.java.udp;
import java.io.*;
import java.net.*;
/**
 * 需求:實現發送信息的鍵盤錄入
 */
public class UdpSendKeyboard {
    public static void main(String[] args) throws Exception{
        DatagramSocket ds = new DatagramSocket();
        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
        String line = null;
        while((line = bufr.readLine()) != null ){
            if("byebye".equals(line)) break;
            
            byte[] buf = line.getBytes();
            DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),11010);
            
            ds.send(dp);
        }
        ds.close();
    }
}
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM