* 如果一個類沒有構造方法: * A:成員全部是靜態的(Math,Arrays,Collections) * B:單例設計模式(Runtime) * C:類中有靜態方法返回該類的對象(InetAddress) * class Demo { * private Demo(){} * * public ...
* 如果一個類沒有構造方法:
* 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(); } }