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

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

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

    Cyh的博客

    Email:kissyan4916@163.com
    posts - 26, comments - 19, trackbacks - 0, articles - 220

    網絡編程>>UDP編程

    Posted on 2009-12-17 22:59 啥都寫點 閱讀(859) 評論(0)  編輯  收藏 所屬分類: J2SE
      上面的例子都用Socket建立連接,屬于TCP(Transmission Control Protocol)連接,本節實例實現UDP(User Data Protocol)編程,包括發送和接收UDP報文。 首先來看看UDP與TCP的區別:

      TCP是基于連接的協議,也就是說,在正式收發數據前,必須和對方建立可靠的連接,這與打電話的機制相似。在前面幾節的編程中,客戶端都與服務器請求建立Socket連接,當服務器端的ServerSocket的accept方法接受連接時,客戶端與服務器的連接便確立了,由于要事先建立好連接,所以用TCP傳輸數據速度相對比較慢,但是比較穩定。
      UDP是面向非連接的協議,也就是說,在正式通信前不必與對方先建立連接,不管對方狀態就直接發送,這與用手機發短信的機制非常相似。由于不用建立連接,所以傳輸速度比較快,但是傳輸的可靠性較差。

    在Java中實現UDP編程的關鍵技術如下:

      java.net.DatagramSocket和java.net.DatagramPacket類可以實現UDP編程,前者實現與目標機的連接(這種連接不需要目標主機的認可),后者用于封裝UDP包。
      發送UDP包時,先將數據包裝成DatagramPacket對象,然后建立一個DatagramSocket,調用它的send方法,將DatagramPacket發送給目標主機
      收取UDP包時,建立一個偵聽本地端口的DatagramSocket,創建一個空的DatagramPacket對象,以存放收到的報文,調用DatagramSocket的receive方法將收到的UDP包寫入到DatagramPacket對象中。
      DatagramPacket 的getAddress方法能獲得UDP消息發送者的網絡地址信息。

    /** */

    import java.net.DatagramPacket;
    import java.net.DatagramSocket;

    /**
     * 該程序接收來自指定端口得UDP報文。
     *
    */

    public class UDPReceive {
        
    // 幫助信息
        public static final String usage = "Usage: java book.net.udp.UDPReceive <port>";

        
    public static void main(String args[]) {
            
    try {
                
    if (args.length != 1){
                    
    throw new IllegalArgumentException("Wrong number of args");
                }

                
    // 從命令行中獲取端口號參數
                int port = Integer.parseInt(args[0]);

                
    // 創建一個socket,偵聽這個端口。
                DatagramSocket dsocket = new DatagramSocket(port);

                
    // 保存接收到的UDP報文的字節數組
                byte[] buffer = new byte[2048];

                
    // 創建一個DatagramPacket,將收到的報文寫入buffer中。
                
    // 注意,這里指定了報文的長度,如果收到的UDP報文比2048大,多余的信息被舍棄
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

                
    // 不斷循環,接收數據
                for ( ; ;) {
                    
    // 等待收到一個數據包
                    dsocket.receive(packet);

                    
    // 將收到的報文的字節數組封裝成字符串。
                    String msg = new String(buffer, 0, packet.getLength());
                    
    // 從數據包中取得消息來源的地址
                    System.out.println("Receive: " + packet.getAddress().getHostAddress() + ""
                            
    + msg);

                    
    // 如果收到QUIT指令,則退出循環。
                    if (msg.equals("QUIT")){
                        System.out.println(
    "Exit the UDPReceive!");
                        
    break;
                    }

                    
                    
    // 重設數據包的長度
                    packet.setLength(buffer.length);
                }

                
    // 關閉socket
                dsocket.close();
            }
     catch (Exception e) {
                System.err.println(e);
                System.err.println(usage);
            }

        }

    }




    /**--------------------------------------------UDPSend.java---------------------------------------------------*/


    import java.io.File;
    import java.io.FileInputStream;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;

    /**
     * 該實例實現一個發送UDP報文的類。
     * UDP與TCP不同在于,UDP在發送報文前無需建立連接,直接發送;而TCP需要建立連接。
     * 即TCP比UDP更可靠。另外,UDP報文會出現舍棄的情況,因為發送端和接收端的報文大小可能不一致。
     * 體現在編程時,UDP編程無需ServerSocket和Socket,只需要DatagramSocket類即可。
     *
    */

    public class UDPSend {
        
    public static final String usage = 
        
    "Usage: java book.net.udp.UDPSend <hostname> <port> <msg>\n" +
        
    "   or: java book.net.udp.UDPSend <hostname> <port> -f <file>";

        
    public static void main(String args[]) {
            
    try 
                
    // 檢查參數個數
                if (args.length < 3)
                    
    throw new IllegalArgumentException("Wrong number of args");
                }

                
                
    // 域名和端口
                String host = args[0];
                
    int port = Integer.parseInt(args[1]);
            
                
    // 下面構造待發送報文的字節數組  
                byte[] message;
                
    if (args[2].equals("-f")) {
                    
    // 如果第三個參數為 -f,則表示將文件的內容以UDP方式發送
                    
    // 獲得待發送的文件對象以及文件的長度
                    File f = new File(args[3]);
                    
    int len = (int)f.length(); 
                    
    // 創建一個足夠容納文件內容的字節數組
                    message = new byte[len]; 
                    FileInputStream in 
    = new FileInputStream(f);
                    
    // 將文件內容以字節的方式讀到字節數組中
                    int bytes_read = 0, n;
                    
    do {
                        n 
    = in.read(message, bytes_read, len-bytes_read);
                        bytes_read 
    += n;
                    }
     while((bytes_read < len)&& (n != -1));
                }

                
    else 
                    
    // 如果第三個參數不是 -f,則將后面的參數當作消息發送
                    String msg = args[2];  
                    
    for (int i = 3; i < args.length; i++){
                        msg 
    += " " + args[i];
                    }

                    message 
    = msg.getBytes();
                }

                
                
    // 根據域名獲取IP地址
                InetAddress address = InetAddress.getByName(host);
            
                
    // 初始化一個UDP包。
                
    // DatagramPacket的構造方法中必須使用InetAddress,而不能是IP地址或者域名
                DatagramPacket packet = new DatagramPacket(message, message.length,
                                   address, port);
            
                
    // 創建一個DatagramSocket,以發送UDP包
                DatagramSocket dsocket = new DatagramSocket();
                dsocket.send(packet);
                System.out.println(
    "send: " + new String(message));
                dsocket.close();
                
                
    // 注意:如果在構造DatagramPacket時,不提供IP地址和端口號,
                
    // 則需要調用DatagramSocket的connect方法,否則無法發送UDP包
                packet = new DatagramPacket(message, message.length);
                dsocket 
    = new DatagramSocket();
                dsocket.connect(address, port);
                dsocket.send(packet);
                System.out.println(
    "Send: " + new String(message));
                dsocket.close();
                
            }
     catch (Exception e) {
                System.err.println(e);
                System.err.println(usage);
            }

        }

    }



    首先在命令行中輸入“java book.net.udp.UDPReceive 8888”,以啟動UDPReceive進程,接收來自8888端口的UDP報文,然后另開一個命令行,輸入"java book.net.udp.UDPSend 127.0.0.1 8888 This is the UDP message!" ,將發送一條消息給本地的8888端口。接著再發送一條“QUIT”消息,停止UDPReceive 進程。  





                                                                                                           --    學海無涯
            

    主站蜘蛛池模板: 国产午夜成人免费看片无遮挡 | 波多野结衣免费在线观看| 亚洲黄色免费网址| 成年大片免费视频| 一级毛片大全免费播放下载| 亚洲爱情岛论坛永久| 最近的中文字幕大全免费版| 一个人免费观看www视频| 亚洲精品视频免费看| 国产一区二区三区免费视频| 免费人成网站在线观看不卡| 亚洲欧美日韩久久精品| 亚洲精品无码MV在线观看| 国产香蕉九九久久精品免费| 香蕉免费一级视频在线观看| 久久精品亚洲AV久久久无码| 国产亚洲色视频在线| 免费观看无遮挡www的视频| 一级成人生活片免费看| 亚洲另类自拍丝袜第1页| 中文字幕亚洲一区二区三区| 欧美a级成人网站免费| 国产啪精品视频网站免费尤物| 亚洲日韩一区二区三区| 亚洲AV无码国产在丝袜线观看| 国产精品麻豆免费版| 亚洲高清免费在线观看| 香蕉免费看一区二区三区| 亚洲av成本人无码网站| 亚洲视频在线观看| 浮力影院亚洲国产第一页| 成人啪精品视频免费网站| 热re99久久6国产精品免费| 一个人看的www视频免费在线观看| 亚洲AV无码乱码在线观看代蜜桃 | 免费jjzz在线播放国产| 91九色精品国产免费| 免费国产99久久久香蕉| 一区二区三区视频免费| 久久亚洲精品无码gv| 亚洲高清一区二区三区|