【DAY23】
文章目錄
- 【DAY23】
- 一.網絡編程
- 1)三要素
- 1.1)IP
- InetAddress類的使用
- 1.2)端口號
- 1.3)協議
- 2.1)UDP協議發送數據
- 2.2)UDP協議接收數據
- 2.3)UDP的三種通信方式
- 3.1)TCP協議的發送和接收
- 3.2)中文亂碼問題
- 3.3)三次握手四次揮手
- 二.反射
- 1)概述
- 2)獲取class對象的三種方式
- 3)反射獲取構造方法
- 4)反射獲取成員變量
- 5)反射獲取成員方法
- 三.動態代理
一.網絡編程
在通信協議下不同計算機上運行的程序,進行的數據傳輸
應用場景:計算機跟計算機之間通過網絡
Java中使用java.net包下的技術輕松開發出常見的網絡應用程序
常見的軟件架構:
- CS:Client/Server 在用戶本地需要下載并安裝客戶端程序,在遠程有一個服務端程序 eg:QQ
- 優點:畫面精美,用戶體驗好
- 缺點:需要開發客戶端也需要開發服務端。用戶需要下載和更新
- BS:Browser/Server 只需要一個瀏覽器,用戶通過不同網址,客戶訪問不同的服務器 eg:淘寶
- 優點:不需要開發客戶端,只需要頁面+服務端,用戶不需要下載打卡瀏覽器就能使用
- 缺點:如果應用過大,用戶體驗受到影響
1)三要素
IP:設備在網絡中的地址,是唯一的表示
端口號:應用程序在設備中的唯一表示
協議:數據在網絡中傳輸的規則,常見的協議有UDP,TCP,http,ftp
1.1)IP
互聯網協議地址,上網設備在網絡中的地址是分配給上網設備的數字標簽
分類:
-
IPv4互聯網通信協議第四版
采用32位地址長度,分為4組,最多只有2^32個IP,2019年11.26全部分配完畢
可以用局域網解決IP不夠的問題
-
IPv6互聯網通信協議第六版
采用128位地址長度,分為8組 ,最多有2^128個IP
IPv4的細節
1.分類:公網地址(萬維網使用)和私有地址(區域網使用)
192.168開頭的就是私有地址,范圍為192.168.0.0—192.168.255.255,專門為組織機構內部使用
2.特殊IP地址:127.0.0.1,也可以是localhost:是回送地址也稱本地回送地址,也稱本機IP,永遠只會尋找當前所在本機
常用的CMD
- ipconfig:查看本機IP地址
- ping:檢查網絡是否連通
InetAddress類的使用
表示IP地址
方法 | 說明 |
---|---|
static InetAddress getByName(String host) | 確定主機名稱的IP地址,主機名稱可以是機器名稱也可以是IP地址 |
String getHostName() | 獲取此IP地址的主機名 |
String getHostAddress() | 返回文本顯示的IP地址字符串 |
public class t1 {public static void main(String[] args) throws UnknownHostException {//1.獲取InetAddress的對象InetAddress address = InetAddress.getByName("LAPTOP-K3EOH2DK");//"設備名"System.out.println(address);//LAPTOP-K3EOH2DK/192.168.1.32String name = address.getHostName();System.out.println(name);//LAPTOP-K3EOH2DKString ip = address.getHostAddress();System.out.println(ip);//192.168.1.32}
}
1.2)端口號
應用程序在設備中唯一的標識
有兩個字節表示的整數,取值范圍:065535,其中01023之間的端口號用于一些知名的網絡訪問或者應用
一個端口號只能被一個應用程序使用
1.3)協議
計算機網絡中連接和通信的規則被稱為網絡通信協議
- OSI參考模型:世界互聯協議標準,全球通信規范,單模型過于理想化,未能在因特網上進行廣泛推廣
- TCP/IP參考模型(或TCP/IP協議):事實上的國際標準
UDP協議:
- 用戶數據報協議
- UDP是面向無連接通信協議,速度快,有大小限制一次最多發送64K,數據不安全,易丟失數據
TCP協議:
- 傳輸控制協議
- TCP是面向連接通信協議,速度慢,沒有大小限制,數據安全
2.1)UDP協議發送數據
public class t1 {public static void main(String[] args) throws IOException {//1.創建對象//綁定端口號,通過這個端口往外發送//空參:所有可能的端口中隨機一個進行使用//有參:指定端口號進行綁定DatagramSocket ds = new DatagramSocket();//2.打包數據String str = "你好你好你好你好你好";byte[] bytes = str.getBytes();InetAddress address = InetAddress.getByName("192.168.1.32");int port = 10086;//端口號DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);//3.發送數據ds.send(dp);//4.釋放數據ds.close();}
}
2.2)UDP協議接收數據
public class T2 {public static void main(String[] args) throws IOException {//1.創建DatagramSocketDatagramSocket ds = new DatagramSocket(10086);//2.接收數據包byte[] bytes = new byte[1024];DatagramPacket dp = new DatagramPacket(bytes, bytes.length);ds.receive(dp);//3.解析數據包byte[] data = dp.getData();int len = dp.getLength();InetAddress address = dp.getAddress();int port = dp.getPort();System.out.println("接收到數據" + new String(data,0,len));System.out.println("該數據是從" + address + "這臺電腦中的" + port + "這個接口發出的");//4.釋放數據ds.close();}
}
先運行接收端再運行發送端
2.3)UDP的三種通信方式
-
單播
一對一
-
組播
一對組
組播地址:224.0.0.0~239.255.255.255 其中224.0.0.0~224.0.0.255為預留的組播地址
-
廣播
一對局域網中的所有設備
廣播地址:255.255.255.255
組播
public class t1 {public static void main(String[] args) throws IOException {//組播//1.創建對象MulticastSocket ms = new MulticastSocket();//2.打包數據String str = "你好你好你好你好你好";byte[] bytes = str.getBytes();InetAddress address = InetAddress.getByName("224.0.0.1");int port = 10000;//端口號DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);//3.發送數據ms.send(dp);//4.釋放數據ms.close();}
}
public class T2 {public static void main(String[] args) throws IOException {//1.創建對象MulticastSocket ms = new MulticastSocket(10000);//2.將當前本機添加到224.0.0.1的這一組中InetAddress adress = InetAddress.getByName("224.0.0.1");ms.joinGroup(adress);//3.接收數據包byte[] bytes = new byte[1024];DatagramPacket dp = new DatagramPacket(bytes, bytes.length);ms.receive(dp);//4.解析數據包byte[] data = dp.getData();int len = dp.getLength();InetAddress address = dp.getAddress();int port = dp.getPort();System.out.println("接收到數據" + new String(data,0,len));System.out.println("該數據是從" + address + "這臺電腦中的" + port + "這個接口發出的");//5.釋放數據ms.close();}
}
廣播
public class t1 {public static void main(String[] args) throws IOException {//組播//1.創建對象MulticastSocket ms = new MulticastSocket();//2.打包數據String str = "你好你好你好你好你好";byte[] bytes = str.getBytes();InetAddress address = InetAddress.getByName("255.255.255.255");int port = 10000;//端口號DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);//3.發送數據ms.send(dp);//4.釋放數據ms.close();}
}
3.1)TCP協議的發送和接收
客戶端
-
創建客戶端的對象Socket對象(Socket)與自動服務器端連接
Socket(String host,int port)
-
獲取輸出流,寫數據
OutputStream getOutputStream()
-
釋放數據
void close()
服務器
-
創建服務器端的Socket對象(ServerSocket)
ServerSocket(int port)
-
監聽客戶端連接,返回一個Socket對象
Socket accept()
-
獲取輸入流,讀數據,并把數據顯示在控制臺
InputStream getInputStream()
-
釋放資源
void close()
客戶端
public class t1 {public static void main(String[] args) throws IOException {//1.創建對象Socket socket = new Socket("192.168.1.32",10086);//2.從連接通道中獲取輸出流OutputStream os = socket.getOutputStream();//寫出數據os.write("你好你好你好你好你好".getBytes());//3.釋放數據os.close();socket.close();}
}
服務端
public class T2 {public static void main(String[] args) throws IOException {//1.創建對象ServerSocket ss = new ServerSocket(10086);//2.監聽客戶端的連接Socket socket = ss.accept();//3.從連接通道中獲取輸入流讀取數據InputStream is = socket.getInputStream();int b;while((b = is.read()) != -1) {System.out.println((char)b);}//4.釋放資源socket.close();ss.close();}
}
3.2)中文亂碼問題
亂碼原因:一個中文三個字節,InputStream字節流一個一個字節讀所有造成亂碼
解決方法:用轉換流把字節流轉換為字符流
public class T2 {public static void main(String[] args) throws IOException {//1.創建對象ServerSocket ss = new ServerSocket(10086);//2.監聽客戶端的連接Socket socket = ss.accept();//3.從連接通道中獲取輸入流讀取數據InputStream is = socket.getInputStream();InputStreamReader isr = new InputStreamReader(is);int b;while((b = isr.read()) != -1) {System.out.print((char)b);}//4.釋放資源isr.close()socket.close();ss.close();}
}
3.3)三次握手四次揮手
二.反射
1)概述
反射允許對封裝類的字段,方法和構造函數的信息進行編程訪問
2)獲取class對象的三種方式
-
Class.forName(“全類名”);
最常用
-
類名.class
一般更多是當做參數進行傳遞
-
類名.getClass();
當已經有了這個類的對象時才能使用
public class t1 {public static void main(String[] args) throws IOException, ClassNotFoundException {//1.法一//全類名:包名 + 類名Class clazz1 = Class.forName("T1.Student");//2.法二Class clazz2 = Student.class;//3.法三Student s = new Student();Class clazz3 = s.getClass();}
}
3)反射獲取構造方法
public class t1 {public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException {//1.獲取class字節碼文件對象Class clazz = Class.forName("T1.Student");//2.獲取構造方法Constructor[] cons = clazz.getConstructors();for (Constructor con : cons) {System.out.println(con);}Constructor[] cons2 = clazz.getDeclaredConstructors();for (Constructor con2 : cons2) {System.out.println(con2);}//獲取單個Constructor con1 = clazz.getDeclaredConstructor();System.out.println(con1);Constructor con2 = clazz.getDeclaredConstructor(String.class);System.out.println(con2);}
}
4)反射獲取成員變量
public class t1 {public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, NoSuchFieldException {//1.獲取class字節碼文件對象Class clazz = Class.forName("T1.Student");//2.獲取成員變量Field[] fields = clazz.getFields();for (Field field : fields) {System.out.println(field);}Field[] fields2 = clazz.getDeclaredFields();for (Field field2 : fields2) {System.out.println(field2);}//獲取單個Field name = clazz.getDeclaredField("name");//獲取權限修飾符int modifiers = name.getModifiers();System.out.println(modifiers);}
}
5)反射獲取成員方法
三.動態代理
特點:無侵入式的給代碼增加額外的功能
為什么需要代理對象如果要干的事情太多可以通過代理轉移部分職責
代理長什么樣對象有什么方法想被代理,代理就一定要有相應的方法