<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 297,  comments - 1618,  trackbacks - 0
    一. UDP協議定義
       UDP協議的全稱是用戶數據報,在網絡中它與TCP協議一樣用于處理數據包。在OSI模型中,在第四層——傳輸層,處于IP協議的上一層。UDP有不提供數據報分組、組裝和不能對數據包的排序的缺點,也就是說,當報文發送之后,是無法得知其是否安全完整到達的。

    二. 使用UDP的原因
       它不屬于連接型協議,因而具有資源消耗小,處理速度快的優點,所以通常音頻、視頻和普通數據在傳送時使用UDP較多,因為它們即使偶爾丟失一兩個數據包,也不會對接收結果產生太大影響。比如我們聊天用的ICQ和OICQ就是使用的UDP協議。在選擇使用協議的時候,選擇UDP必須要謹慎。在網絡質量令人不十分滿意的環境下,UDP協議數據包丟失會比較嚴重。

    三. 在Java中使用UDP協議編程的相關類
    1. InetAddress
        用于描述和包裝一個Internet IP地址。有如下方法返回實例:
        getLocalhost():返回封裝本地地址的實例。

     getAllByName(String host):返回封裝Host地址的InetAddress實例數組。

     getByName(String host):返回一個封裝Host地址的實例。其中,Host可以是域名或者是一個合法的IP地址。
        InetAddress.getByAddress(addr):根據地址串返回InetAddress實例。
        InetAddress.getByAddress(host, addr):根據主機地符串和地址串返回InetAddress實例。

    2. DatagramSocket
        用于接收和發送UDP的Socket實例。該類有3個構造函數:
        DatagramSocket():通常用于客戶端編程,它并沒有特定監聽的端口,僅僅使用一個臨時的。程序會讓操作系統分配一個可用的端口。
        DatagramSocket(int port):創建實例,并固定監聽Port端口的報文。通常用于服務端

     DatagramSocket(int port, InetAddress localAddr):這是個非常有用的構建器,當一臺機器擁有多于一個IP地址的時候,由它創建的實例僅僅接收來自LocalAddr的報文。
        DatagramSocket具有的主要方法如下:
        1)receive(DatagramPacket d):接收數據報文到d中。receive方法產生一個“阻塞”。“阻塞”是一個專業名詞,它會產生一個內部循環,使程序暫停在這個地方,直到一個條件觸發。

     2)send(DatagramPacket dp):發送報文dp到目的地。

     3)setSoTimeout(int timeout):設置超時時間,單位為毫秒。

     4)close():關閉DatagramSocket。在應用程序退出的時候,通常會主動釋放資源,關閉Socket,但是由于異常地退出可能造成資源無法回收。所以,應該在程序完成時,主動使用此方法關閉Socket,或在捕獲到異常拋出后關閉Socket。

    3. DatagramPacket
        用于處理報文,它將Byte數組、目標地址、目標端口等數據包裝成報文或者將報文拆卸成Byte數組。應用程序在產生數據包是應該注意,TCP/IP規定數據報文大小最多包含65507個,通常主機接收548個字節,但大多數平臺能夠支持8192字節大小的報文。DatagramPacket類的構建器共有4個:
        DatagramPacket(byte[] buf, int length):將數據包中Length長的數據裝進Buf數組,一般用來接收客戶端發送的數據。
        DatagramPacket(byte[] buf, int offset, int length):將數據包中從Offset開始、Length長的數據裝進Buf數組。
        DatagramPacket(byte[] buf, int length, InetAddress clientAddress, int clientPort):從Buf數組中,取出Length長的數據創建數據包對象,目標是clientAddress地址,clientPort端口,通常用來發送數據給客戶端。

     DatagramPacket(byte[] buf, int offset, int length, InetAddress clientAddress, int clientPort):從Buf數組中,取出Offset開始的、Length長的數據創建數據包對象,目標是clientAddress地址,clientPort端口,通常用來發送數據給客戶端。
        主要的方法如下:
         1)getData(): 從實例中取得報文的Byte數組編碼。
         2)setDate(byte[]  buf):將byte數組放入要發送的報文中。

    四. 實例解析
        下面讓我們來看一個UDP的服務端和客戶端交互通信的例子,在本例中,服務端循環等待客戶端發送的信息,并對其進行回應,客戶端向服務端發送信息,并接收服務端的回應信息。代碼如下:
        1. UDP的服務端程序

    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.InetSocketAddress;
    import java.net.SocketException;

    /**
     * Copyright 2007 GuangZhou Cotel Co. Ltd.
     * All right reserved.    
     * UTP服務類.     
     * 
    @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
     * 
    @version 1.0 
     * Creation date: 2007-8-16 - 下午10:32:31
     
    */

    public class UdpServerSocket {
        
    private byte[] buffer = new byte[1024];
        
        
    private DatagramSocket ds = null;

        
    private DatagramPacket packet = null;

        
    private InetSocketAddress socketAddress = null;

        
    private String orgIp;

        
    /**
         * 構造函數,綁定主機和端口.
         * 
    @param host 主機
         * 
    @param port 端口
         * 
    @throws Exception
         
    */

        
    public UdpServerSocket(String host, int port) throws Exception {
            socketAddress 
    = new InetSocketAddress(host, port);
            ds 
    = new DatagramSocket(socketAddress);
            System.out.println(
    "服務端啟動!");
        }

        
        
    public final String getOrgIp() {
            
    return orgIp;
        }


        
    /**
         * 設置超時時間,該方法必須在bind方法之后使用.
         * 
    @param timeout 超時時間
         * 
    @throws Exception
         
    */

        
    public final void setSoTimeout(int timeout) throws Exception {
            ds.setSoTimeout(timeout);
        }


        
    /**
         * 獲得超時時間.
         * 
    @return 返回超時時間.
         * 
    @throws Exception
         * 
    @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
         * Creation date: 2007-8-16 - 下午10:34:36
         
    */

        
    public final int getSoTimeout() throws Exception {
            
    return ds.getSoTimeout();
        }


        
    /**
         * 綁定監聽地址和端口.
         * 
    @param host 主機IP
         * 
    @param port 端口
         * 
    @throws SocketException
         * 
    @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
         * Creation date: 2007-8-16 - 下午10:36:17
         
    */

        
    public final void bind(String host, int port) throws SocketException {
            socketAddress 
    = new InetSocketAddress(host, port);
            ds 
    = new DatagramSocket(socketAddress);
        }



        
    /**
         * 接收數據包,該方法會造成線程阻塞.
         * 
    @return 返回接收的數據串信息
         * 
    @throws IOException
         * 
    @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
         * Creation date: 2007-8-16 - 下午10:38:24
         
    */

        
    public final String receive() throws IOException {
            packet 
    = new DatagramPacket(buffer, buffer.length);
            ds.receive(packet);
            orgIp 
    = packet.getAddress().getHostAddress();
            String info 
    = new String(packet.getData(), 0, packet.getLength());
            System.out.println(
    "接收信息:" + info);
            
    return info;
        }


        
    /**
         * 將響應包發送給請求端.
         * 
    @param bytes 回應報文
         * 
    @throws IOException
         * 
    @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
         * Creation date: 2007-8-16 - 下午11:05:31
         
    */

        
    public final void response(String info) throws IOException {
            System.out.println(
    "客戶端地址 : " + packet.getAddress().getHostAddress()
                    
    + ",端口:" + packet.getPort());
            DatagramPacket dp 
    = new DatagramPacket(buffer, buffer.length, packet
                    .getAddress(), packet.getPort());
            dp.setData(info.getBytes());
            ds.send(dp);
        }


        
    /**
         * 設置報文的緩沖長度.
         * 
    @param bufsize 緩沖長度
         * 
    @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
         * Creation date: 2007-8-16 - 下午10:47:49
         
    */

        
    public final void setLength(int bufsize) {
            packet.setLength(bufsize);
        }


        
    /**
         * 獲得發送回應的IP地址.
         * 
    @return 返回回應的IP地址
         * 
    @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
         * Creation date: 2007-8-16 - 下午10:48:27
         
    */

        
    public final InetAddress getResponseAddress() {
            
    return packet.getAddress();
        }


        
    /**
         * 獲得回應的主機的端口.
         * 
    @return 返回回應的主機的端口.
         * 
    @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
         * Creation date: 2007-8-16 - 下午10:48:56
         
    */

        
    public final int getResponsePort() {
            
    return packet.getPort();
        }


        
    /**
         * 關閉udp監聽口.
         * 
    @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
         * Creation date: 2007-8-16 - 下午10:49:23
         
    */

        
    public final void close() {
            
    try {
                ds.close();
            }
     catch (Exception ex) {
                ex.printStackTrace();
            }

        }


        
    /**
         * 測試方法.
         * 
    @param args
         * 
    @throws Exception
         * 
    @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
         * Creation date: 2007-8-16 - 下午10:49:50
         
    */

        
    public static void main(String[] args) throws Exception {
            String serverHost 
    = "127.0.0.1";
            
    int serverPort = 3344;
            UdpServerSocket udpServerSocket 
    = new UdpServerSocket(serverHost, serverPort);
            
    while (true{
                udpServerSocket.receive();
                udpServerSocket.response(
    "你好,sterning!");
                
            }

        }

    }

       2. UDP客戶端程序

    import java.io.*;
    import java.net.*;

    /**
     * Copyright 2007 GuangZhou Cotel Co. Ltd.
     * All right reserved.    
     * UDP客戶端程序,用于對服務端發送數據,并接收服務端的回應信息.
     * 
    @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
     * 
    @version 1.0 
     * Creation date: 2007-8-16 - 下午10:54:23
     
    */

    public class UdpClientSocket {
        
    private byte[] buffer = new byte[1024];

        
    private DatagramSocket ds = null;

        
    /**
         * 構造函數,創建UDP客戶端
         * 
    @throws Exception
         
    */

        
    public UdpClientSocket() throws Exception {
            ds 
    = new DatagramSocket();
        }

        
        
    /**
         * 設置超時時間,該方法必須在bind方法之后使用.
         * 
    @param timeout 超時時間
         * 
    @throws Exception
         * 
    @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
         * Creation date: 2007-8-16 - 下午10:55:12
         
    */

        
    public final void setSoTimeout(final int timeout) throws Exception {
            ds.setSoTimeout(timeout);
        }


        
    /**
         * 獲得超時時間.
         * 
    @return 返回超時時間
         * 
    @throws Exception
         * 
    @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
         * Creation date: 2007-8-16 - 下午10:55:25
         
    */

        
    public final int getSoTimeout() throws Exception {
            
    return ds.getSoTimeout();
        }


        
    public final DatagramSocket getSocket() {
            
    return ds;
        }


        
    /**
         * 向指定的服務端發送數據信息.
         * 
    @param host 服務器主機地址
         * 
    @param port 服務端端口
         * 
    @param bytes 發送的數據信息
         * 
    @return 返回構造后俄數據報
         * 
    @throws IOException
         * 
    @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
         * Creation date: 2007-8-16 - 下午11:02:41
         
    */

        
    public final DatagramPacket send(final String host, final int port,
                
    final byte[] bytes) throws IOException {
            DatagramPacket dp 
    = new DatagramPacket(bytes, bytes.length, InetAddress
                    .getByName(host), port);
            ds.send(dp);
            
    return dp;
        }


        
    /**
         * 接收從指定的服務端發回的數據.
         * 
    @param lhost 服務端主機
         * 
    @param lport 服務端端口
         * 
    @return 返回從指定的服務端發回的數據.
         * 
    @throws Exception
         * 
    @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
         * Creation date: 2007-8-16 - 下午10:52:36
         
    */

        
    public final String receive(final String lhost, final int lport)
                
    throws Exception {
            DatagramPacket dp 
    = new DatagramPacket(buffer, buffer.length);
            ds.receive(dp);
            String info 
    = new String(dp.getData(), 0, dp.getLength());
            
    return info;
        }


        
    /**
         * 關閉udp連接.
         * 
    @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
         * Creation date: 2007-8-16 - 下午10:53:52
         
    */

        
    public final void close() {
            
    try {
                ds.close();
            }
     catch (Exception ex) {
                ex.printStackTrace();
            }

        }


        
    /**
         * 測試客戶端發包和接收回應信息的方法.
         * 
    @param args
         * 
    @throws Exception
         * 
    @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
         * Creation date: 2007-8-16 - 下午11:03:54
         
    */

        
    public static void main(String[] args) throws Exception {
            UdpClientSocket client 
    = new UdpClientSocket();
            String serverHost 
    = "127.0.0.1";
            
    int serverPort = 3344;
            client.send(serverHost, serverPort, (
    "你好,阿蜜果!").getBytes());
            String info 
    = client.receive(serverHost, serverPort);
            System.out.println(
    "服務端回應數據:" + info);
        }

    }


       參考文章:http://java.photoshopjiaocheng.com/sun-applet-class/sdk-api-code/virtual-machine-programming-9178.html
                          http://www.eoot.cn/html/pro/java/20070511/25276.html
                          http://topic.csdn.net/t/20060204/19/4539686.html
    posted on 2007-08-16 23:30 阿蜜果 閱讀(15519) 評論(16)  編輯  收藏 所屬分類: 網絡通信相關


    FeedBack:
    # re: Java中的UDP協議編程[未登錄]
    2007-08-16 23:37 | -274°C
    沙發哦。呵呵。
    寫得好。  回復  更多評論
      
    # re: Java中的UDP協議編程
    2007-08-17 01:19 | 楊愛友
    運行過了,以前學過網絡,還比較容易看懂  回復  更多評論
      
    # re: Java中的UDP協議編程
    2007-08-17 10:54 | Scott.Pan
    新文章哦,不錯!
    暫時還沒接觸協議編程,希望有機會向你學習!  回復  更多評論
      
    # re: Java中的UDP協議編程
    2007-08-18 00:00 | 三告習習
    學習,先記下了
    現在都直接用了ice,都還不懂udp...回頭再看看
    :)
      回復  更多評論
      
    # re: Java中的UDP協議編程
    2007-08-20 09:54 | BeanSoft
    保存, 支持. 不理解原理用類庫, 出了問題怎么改? 所以還是要掌握基礎的.  回復  更多評論
      
    # re: Java中的UDP協議編程[未登錄]
    2007-11-15 00:06 | Jack
    非常好,懂了  回復  更多評論
      
    # re: Java中的UDP協議編程
    2007-12-12 14:38 | norvid
    有疑問!
    客戶端中為什么方法
    public final String receive(final String lhost, final int lport) throws Exception;
    的兩個參數lhost, lport在方法體內沒有用到?如果說這兩個參數不起作用,那為什么還要作為參數呢?  回復  更多評論
      
    # re: Java中的UDP協議編程
    2008-01-19 16:28 | Anonymous
    好東西啊~~
    終于找到比較全的UDP編程文章了  回復  更多評論
      
    # re: Java中的UDP協議編程
    2009-05-13 10:08 | 感謝
    不錯的文章  回復  更多評論
      
    # re: Java中的UDP協議編程
    2010-10-06 10:03 | WiHi
    很不錯,很實用,感謝!  回復  更多評論
      
    # re: Java中的UDP協議編程
    2010-12-07 18:45 | 大剛
    好  回復  更多評論
      
    # re: Java中的UDP協議編程
    2011-05-09 23:02 | forth leaf
    要是有個界面就更好了。  回復  更多評論
      
    # re: Java中的UDP協議編程[未登錄]
    2012-06-24 10:45 | wei
    sdfsdf  回復  更多評論
      
    # re: Java中的UDP協議編程[未登錄]
    2012-06-24 10:48 | wei
    想問下大俠java如何接收c++發送過來的結構體。就是接受到結構體后怎么將其還原,具體還原的數據處理能看下嘛?大小端問題我已解決,就是不知道怎么將結構體還原!
    跪求答案,謝謝賜教  回復  更多評論
      
    # re: Java中的UDP協議編程
    2013-10-14 10:58 | danifer
    非常不錯,易懂。  回復  更多評論
      
    # re: Java中的UDP協議編程
    2014-10-27 15:03 | sc
    UDP能正常收發,但是發送DNS報文的時候就不行了,就樓主解救。  回復  更多評論
      
    <2007年8月>
    2930311234
    567891011
    12131415161718
    19202122232425
    2627282930311
    2345678

          生活將我們磨圓,是為了讓我們滾得更遠——“圓”來如此。
          我的作品:
          玩轉Axure RP  (2015年12月出版)
          

          Power Designer系統分析與建模實戰  (2015年7月出版)
          
         Struts2+Hibernate3+Spring2   (2010年5月出版)
         

    留言簿(263)

    隨筆分類

    隨筆檔案

    文章分類

    相冊

    關注blog

    積分與排名

    • 積分 - 2294312
    • 排名 - 3

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 爽爽爽爽爽爽爽成人免费观看| 亚洲А∨精品天堂在线| 亚洲Aⅴ无码一区二区二三区软件 亚洲AⅤ视频一区二区三区 | 亚洲韩国在线一卡二卡| 久草在视频免费福利| 色窝窝亚洲av网| 亚洲第一中文字幕| 四只虎免费永久观看| 久久国产乱子伦精品免费看| 国产精品亚洲专区无码牛牛| 亚洲av中文无码乱人伦在线观看 | 69式互添免费视频| 一个人看的在线免费视频| 亚洲精品国产专区91在线| 女人被弄到高潮的免费视频| 全黄A免费一级毛片| 亚洲国产成人无码AV在线影院| 国产成人 亚洲欧洲| 在线观看亚洲AV日韩A∨| 亚洲AV日韩AV鸥美在线观看| 中文无码亚洲精品字幕| 亚洲欧洲国产精品你懂的| 亚洲国产精品无码专区影院| 亚洲午夜久久久影院| 情人伊人久久综合亚洲| 国产亚洲玖玖玖在线观看| 久久久精品视频免费观看| 国产亚洲视频在线观看网址| 久久aa毛片免费播放嗯啊| 在线涩涩免费观看国产精品| 91视频免费观看| 全免费a级毛片免费看无码| 日本免费一区二区三区 | 两个人看的www免费视频| 免费看美女被靠到爽| 内射干少妇亚洲69XXX| 亚洲综合视频在线观看| 美女的胸又黄又www网站免费| 国产亚洲精品VA片在线播放| 日本免费中文视频| 亚洲人成网址在线观看|