1. 程式人生 > 其它 >網路程式設計(inetAddress類的概述和使用----UDP傳送和接受資料)

網路程式設計(inetAddress類的概述和使用----UDP傳送和接受資料)


* 如果一個類沒有構造方法:
* A:成員全部是靜態的(Math,Arrays,Collections)
* B:單例設計模式(Runtime)
* C:類中有靜態方法返回該類的物件(InetAddress)
* class Demo {
* private Demo(){}
*
* public static Demo getXxx() {
* return new Demo();
* }
* }
*
* 看InetAddress的成員方法:
* public static InetAddress getByName(String host):根據主機名或者IP地址的字串表示得到IP地址物件


*/

package cn.itcast_01;

import java.net.InetAddress;
import java.net.UnknownHostException;

/*
 * 如果一個類沒有構造方法:
 * A:成員全部是靜態的(Math,Arrays,Collections)
 * B:單例設計模式(Runtime)
 * C:類中有靜態方法返回該類的物件(InetAddress)
 *         class Demo {
 *             private Demo(){}
 * 
 *             public static Demo getXxx() {
 *                 return new Demo();
 *             }
 *         }
 * 
 * 看InetAddress的成員方法:
 * public static InetAddress getByName(String host):根據主機名或者IP地址的字串表示得到IP地址物件
 
*/ public class InetAddressDemo { public static void main(String[] args) throws UnknownHostException { // public static InetAddress getByName(String host) // InetAddress address = InetAddress.getByName("liuyi"); // InetAddress address = InetAddress.getByName("192.168.12.92"); InetAddress address = InetAddress.getByName("192.168.12.63");
// 獲取兩個東西:主機名,IP地址 // public String getHostName()--------獲取主機名 String name = address.getHostName(); // public String getHostAddress()----返回 IP 地址字串(以文字表現形式)。 String ip = address.getHostAddress(); System.out.println(name + "---" + ip); } }

 UDP進行程式碼測試時---首先執行接受資料---然後執行傳送資料

UDP傳送資料

/*
* UDP協議傳送資料:
* A:建立傳送端Socket物件
* B:建立資料,並把資料打包
* C:呼叫Socket物件的傳送方法傳送資料包
* D:釋放資源
*/

package Day26;

import java.io.IOException;
import java.net.*;
/*
 * UDP協議傳送資料:
 * A:建立傳送端Socket物件
 * B:建立資料,並把資料打包
 * C:呼叫Socket物件的傳送方法傳送資料包
 * D:釋放資源
 */

public class SendDemo {
    public static void main(String[] args) throws IOException {
        // 建立傳送端Socket物件
        //public class DatagramSocketextends Object此類表示用來發送和接收資料報包的套接字
        // DatagramSocket()
        DatagramSocket tt = new DatagramSocket();

        //建立資料並把資料打包
        //public final class DatagramPacket  extends Object此類表示資料報
        //public DatagramPacket(byte[] buf,int length,InetAddress address,int port)
        //buf - 包資料。
        //length - 包長度。
        //address - 目的地址。
        //port - 目的埠號。
        // 構造資料報包,用來將長度為 length 的包傳送到指定主機上的指定埠

        //包資料---建立資料
        byte [] buf = "hello你好".getBytes();//---將字串型別的資料轉換為位元組陣列
        //獲取包長度
        int a= buf.length;
        //目的地地址
        //得到IP地址物件---並同時獲取主機名和主機的IP地址
        InetAddress ia = InetAddress.getByName("192.168.1.4");
        //給出傳送的目的埠
        int port = 10086;

        //打包資料
        DatagramPacket DP = new DatagramPacket(buf,a,ia,port);

        // 呼叫Socket物件的傳送方法傳送資料包
        //public void send(DatagramPacket p)throws IOException從此套接字傳送資料報包。
        //DatagramPacket 包含的資訊指示:將要傳送的資料、其長度、遠端主機的 IP 地址和遠端主機的埠號。
        tt.send(DP);

        //釋放資源
        tt.close();

    }
}

 UDP接受資料

/*
* UDP協議接收資料:
* A:建立接收端Socket物件
* B:建立一個數據包(接收容器)
* C:呼叫Socket物件的接收方法接收資料
* D:解析資料包,並顯示在控制檯
* E:釋放資源
*/

package Day26;

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

//UDP協議接受資料
/*
 * UDP協議接收資料:
 * A:建立接收端Socket物件
 * B:建立一個數據包(接收容器)
 * C:呼叫Socket物件的接收方法接收資料
 * D:解析資料包,並顯示在控制檯
 * E:釋放資源
 */
public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
        //建立接收端物件---並給出要接受機器的埠
        DatagramSocket DS = new DatagramSocket(10086);

        //建立一個數據包(接受容器)
        //public DatagramPacket(byte[] buf,int length)
        // 構造 DatagramPacket,用來接收長度為 length 的資料包
        //buf - 儲存傳入資料報的緩衝區。
        //len - 要讀取的位元組數。
        //指定資料包的大小---用於儲存傳入的資料報的緩衝區
        byte [] bt = new byte[1024];
        //獲取包的位元組數長度
        int length = bt.length;
        DatagramPacket DP = new DatagramPacket(bt,length);

        //呼叫Sockt物件的方法來接受資料
        //public void receive(DatagramPacket p)從此套接字接收資料報包
        //p - 要放置傳入資料的 DatagramPacket
        DS.receive(DP);

        //解析資料包並顯示在控制檯上
        // 獲取傳送端對方的ip
        // public InetAddress getAddress()
        //某臺機器的 IP 地址,此資料報將要發往該機器或者是從該機器接收到的。
        InetAddress IA = DP.getAddress();
        //public String getHostAddress()返回 IP 地址字串(以文字表現形式)。
        String ip = IA.getHostAddress();

        // public byte[] getData():獲取資料緩衝區
        //用來接收或傳送資料的緩衝
        // public int getLength():獲取資料的實際長度
        //將要傳送或接收到的資料的長度。
        byte[] bt1 = DP.getData();
        int get = DP.getLength();
        //public String(byte[] bytes,int offset,int length)---將位元組陣列轉換為字串
        //bytes - 要解碼為字元的 byte
        //offset - 要解碼的第一個 byte 的索引
        //length - 要解碼的 byte 數
        String s = new String(bt1,0,get);
        //輸出檢視某個IP地址的機器傳遞來的資料包
        System.out.println(ip+"傳送的資料是:"+s);

        //釋放資源
        DS.close();

    }
}

 

/*
* 資料來自於鍵盤錄入
* 鍵盤錄入資料要自己控制錄入結束。
*/

// 封裝鍵盤錄入資料-----鍵盤自己控制錄入資料---輸入規定字元就會結束迴圈
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = null;

while ((line = br.readLine()) != null) {

if ("886".equals(line)) {
break;
}

UDP傳送端

 

package cn.itcast_04;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/*
 * 資料來自於鍵盤錄入
 * 鍵盤錄入資料要自己控制錄入結束。
 */
public class SendDemo {
    public static void main(String[] args) throws IOException {
        // 建立傳送端的Socket物件
        DatagramSocket ds = new DatagramSocket();

        // 封裝鍵盤錄入資料
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = null;
        while ((line = br.readLine()) != null) {
            if ("886".equals(line)) {
                break;
            }

            // 建立資料並打包
            byte[] bys = line.getBytes();
            // DatagramPacket dp = new DatagramPacket(bys, bys.length,
            // InetAddress.getByName("192.168.12.92"), 12345);
            DatagramPacket dp = new DatagramPacket(bys, bys.length,
                    InetAddress.getByName("192.168.12.255"), 12345);

            // 傳送資料
            ds.send(dp);
        }

        // 釋放資源
        ds.close();
    }
}

 

 

 

UDP接收端---接收端應該一直開著等待接收資料,是不需要關閉

package cn.itcast_04;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

/*
 * 多次啟動接收端:
 *         java.net.BindException: Address already in use: Cannot bind
 *         埠被佔用。
 */
public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
        // 建立接收端的Socket物件
        DatagramSocket ds = new DatagramSocket(12345);

        while (true) {
            // 建立一個包裹
            byte[] bys = new byte[1024];
            DatagramPacket dp = new DatagramPacket(bys, bys.length);

            // 接收資料
            ds.receive(dp);

            // 解析資料
            String ip = dp.getAddress().getHostAddress();
            String s = new String(dp.getData(), 0, dp.getLength());
            System.out.println("from " + ip + " data is : " + s);
        }

        // 釋放資源
        // 接收端應該一直開著等待接收資料,是不需要關閉
        // ds.close();
    }
}

 

 多執行緒實現聊天室程式

一:傳送端

package cn.itcast_05;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class SendThread implements Runnable {

    private DatagramSocket ds;

    public SendThread(DatagramSocket ds) {
        this.ds = ds;
    }

    @Override
    public void run() {
        try {
            // 封裝鍵盤錄入資料
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    System.in));
            String line = null;
            while ((line = br.readLine()) != null) {
                if ("886".equals(line)) {
                    break;
                }

                // 建立資料並打包
                byte[] bys = line.getBytes();
                // DatagramPacket dp = new DatagramPacket(bys, bys.length,
                // InetAddress.getByName("192.168.12.92"), 12345);
                DatagramPacket dp = new DatagramPacket(bys, bys.length,
                        InetAddress.getByName("192.168.12.255"), 12306);

                // 傳送資料
                ds.send(dp);
            }

            // 釋放資源
            ds.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

 

二:接收端

package cn.itcast_05;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class ReceiveThread implements Runnable {
    private DatagramSocket ds;

    public ReceiveThread(DatagramSocket ds) {
        this.ds = ds;
    }

    @Override
    public void run() {
        try {
            while (true) {
                // 建立一個包裹
                byte[] bys = new byte[1024];
                DatagramPacket dp = new DatagramPacket(bys, bys.length);

                // 接收資料
                ds.receive(dp);

                // 解析資料
                String ip = dp.getAddress().getHostAddress();
                String s = new String(dp.getData(), 0, dp.getLength());
                System.out.println("from " + ip + " data is : " + s);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

 

三:測試類

package cn.itcast_05;

import java.io.IOException;
import java.net.DatagramSocket;

/*
 * 通過多執行緒改進剛才的聊天程式,這樣我就可以實現在一個視窗傳送和接收資料了
 */
public class ChatRoom {
    public static void main(String[] args) throws IOException {
        //建立Socket物件---傳送和接收物件
        DatagramSocket dsSend = new DatagramSocket();
        DatagramSocket dsReceive = new DatagramSocket(12306);
  
        //建立物件---並使用構造引數傳遞其要傳送和接收的物件
        SendThread st = new SendThread(dsSend);
        ReceiveThread rt = new ReceiveThread(dsReceive);

        //建立執行緒物件並給出執行的物件
        Thread t1 = new Thread(st);
        Thread t2 = new Thread(rt);

        //啟動執行緒
        t1.start();
        t2.start();
    }
}