網路程式設計(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(); } }