---------- android培訓、java培訓、期待與您交流! ---------- html
1、網絡模型概述java
網絡模型示意圖:android
說明:web
(1)數據的傳輸:在用戶端,應用層的數據,通過層層封包,最後到物理層,經過網絡發送到網絡的另外一端,再從物理層到應用層進行層層解包。數組
(2)經常使用層的協議,包括:應用層的FTP和HTTP協議等;傳輸層的UDP和TCP等;網際層的IP等。瀏覽器
(3)對於開發者來說,通常處於傳輸層和網際層。對於用戶,一般停留在應用層。服務器
2、網絡通信要素網絡
網絡通信要素,包括:IP地址、端口號 以及 傳輸協議。多線程
(一)IP地址併發
1、IP地址概述
(1)它是網絡設備標識;
(2)可用主機名錶示;
(3)localhost:迴路網絡接口的標準主機名;
(4)本機迴環地址:127.0.0.1。
2、IP地址對象——InetAddress類
(1)IP地址:在java中對應的是InetAddress類,存在於java.net包中。
(2)InetAddress類:無構造函數。
(3)可經過getLocalHost()方法獲取InetAddress對象,此方法是靜態的,返回本類對象。InetAddress ip = InetAddress.getLocalHost();
(4)InetAddress經常使用方法:
① static InetAddress getByName(String host):獲取指定主機的IP和主機名。
② String getHostAddress():返回IP地址字符串文本形式,以IP地址爲主。
③ String getHostName():返回IP地址主機名。
④ static InetAddress[] getAllByName(String host):在給定主機名的狀況下,根據系統上配置的名稱服務返回IP地址所組成的數組,返回ip地址不惟一。
(5)如何獲取其餘主機的IP地址對象:
① 功能:返回InetAddress對象
② 對於任意主機,須要指定傳入主機名的參數
注意:若是IP地址和對應的主機名,這種映射關係沒有在網絡上,就不會解析成功,返回的仍是指定的IP。
(6)示例代碼:
// 一、獲取本地主機地址對象
InetAddress ip = InetAddress.getLocalHost();
System.out.println(ip.getHostAddress() + ip.getHostName());
// 二、獲取其餘主機的ip地址對象
ip = InetAddress.getByName(「ip地址或者DNS」);
System.out.println(ip.getHostAddress);
// 三、獲取百度域名的ip地址羣
InetAddress[] ips = InetAddress.getAllByName(「www.baidu.com」);
for( InetAddress ip : ips ){
System.out.println(ip.getHostAddress())
}
(二)端口號
一、用於標識進程的邏輯地址,不用進程的標識。
二、有效端口:0 ~65535,其中0~ 1024是系統使用或保留的端口。
(三)傳輸協議
傳輸協議:即通訊規則,常見的有UDP協議、TCP協議。
一、UDP協議:是面向無鏈接,明確了對方的端口,不管在不在網上,只管傳輸,不在就會丟失數據。只求速度,應用於網絡視頻會議和聊天等應用程序中。其特色有:
(1)將數據和源、目的封裝成包,不須要創建連接;
(2)每一個數據包的大小限制在64K以內;
(3)因無鏈接,是不可靠的協議;
(4)不需創建鏈接,速度快;
二、TCP協議:是面向鏈接的,必須鏈接成功才能傳輸數據,應用於下載等程序上。其特色是:
(1)創建鏈接,造成傳輸數據通道;
(2)在鏈接中進行大數據量傳輸;
(3)經過三次握手完成鏈接,是可靠的協議;
(4)必須創建鏈接,效率會低一些;
3、網絡傳輸協議
(一)Socket:Socket是爲網絡服務提供的一種機制。
一、通訊兩端都要有Socket;
二、網絡通訊,其實就是Socket間的通訊;
三、數據在兩個Socket間經過IO傳輸;
(二)UDP傳輸
1、概述
UDP傳輸是經過DatagramSocket類來實現的,此類表示用來發送和接收數據包的套接字,存在java.net包中。
2、經常使用方法:
① DatagramSocket():建立 UDPSocket發送服務對象,不指定端口號。
② DatagramSocket(int port):建立 UDPSocket發送服務對象,指定端口號。
③ void send(DatagramPacket p):發送數據報包。
④ void receive(DatagramPacket p):接收數據報包。
3、建立UDP發送端、UDP接收端步驟:
(1)UDP發送端
① 創建UDP的Socket服務。
② 將要發送的數據封裝到數據包中。
③ 用UDP的socket服務將數據包發送出去。
④ 關閉Socket服務。
(2)UDP接收端
① 創建UDP Socket服務,由於要接收數據,必需要明確一個端口號。
② 定義一個數據包,用來存儲接收到的字節數據,由於數據包對象中有更多功能能夠提取字節數據中的不一樣數據信息。
③ 經過socket服務的receive方法,將接收到的數據存入已定義好的數據包中。
④ 經過數據包對象的特有功能,將這些不一樣的數據取出,打印在控制檯上。
⑤ 關閉Socket服務。
(3)注意事項:
(1)發送端與接收端是兩個獨立的運行程序。
(2)在發送端,要在數據包對象中明確目的地IP及端口。
(3)在接收端,要指定監聽的端口。
4、UDP發送端、UDP接收端代碼示例
1 //(1)UDP發送端代碼:
2 import java.net.*; 3 class UDPSend{ 4 public static void main(String[] args)throws Exception{ 5 //一、建立UDP服務,使用DatagramSocket對象。
6 DatagramSocket ds = new DatagramSocket(8888); 7 //二、將要發送的數據封裝到數據包中,用到DatagramPacket(byte[] buf, int length, InetAddress address, int port)
8 byte[] buf = "udp shi shen ma".getBytes(); 9 DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("127.0.0.1"),10000); 10 //三、經過Socket服務,將已有的數據包發送出去。經過send方法
11 ds.send(dp); 12 //四、關閉資源
13 ds.close(); 14 } 15 } 16 //(2)UDP接收端代碼:
17 class UDPReceive{ 18 public static void main(String[] args)throws Exception{ 19 //一直處於接收狀態
20 while(true) 21 { 22 // 1. 建立udp Socket服務,創建端點
23 DatagramSocket ds = new DatagramSocket(10000); 24 // 2. 定義數據包。用於存儲數據
25 byte[] buf = new byte[1024]; 26 DatagramPacket dp = new DatagramPacket(buf,buf.length); 27 // 3. 經過Socket服務的receive方法將接收到的數據存入數據包中
28 ds.receive(dp);//阻塞式方法 29 // 4. 經過數據包的方法獲取其中的數據
30 String ip = dp.getAddress().getHostName(); 31 String text = new String(dp.getData(),0,dp.getLength()); 32 int port = dp.getPort(); 33 System.out.println(ip+"::"+text+"::"+port); 34 // 5. 關閉資源
35 ds.close(); 36 } 37 } 38 }
5、練習題:
(1)用鍵盤錄入的方式,來發送數據。
(2)編寫一個聊天程序,有收數據的部分和發數據的部分。
(三)TCP傳輸
1、概述
TCP傳輸分爲「客戶端」和「服務端」。客戶端對應的對象是Socket,服務端對應的對象是ServerSocket。
2、經常使用方法:
(1)客戶端Socket
構造函數:
① Socket():建立未鏈接套接字。
② Socket(InetAddress address , tin port):建立鏈接到IP指定端口的套接字。
③ Socket( String host , int port ):建立流套接字並將其鏈接到指定主機上的指定端口號。
特有方法:
① getInputStream():返回此套接字的輸入流。
② getOutputStream():返回此套接字的輸出流。
③ void shutdownInput():此套接字的輸入流至於「流的末尾」。
④ void shutdownOutput():禁用此套接字的輸出流。
(2)服務端ServerSocket
① 構造函數:ServerSocket(int port):建立綁定到特定端口的服務器套接字。
② 特有方法:Socket accept():監聽並接受到此套接字的鏈接,是阻塞式方法。
3、建立TCP客戶端、TCP服務端步驟:
TCP是面向鏈接的,在創建Socket服務時,須要有服務端存在並鏈接成功,造成通路,再經過鏈接好的通路進行數據傳輸。
(1)TCP客戶端建立步驟
① 建立Socket服務,明確要鏈接的主機端口。
② 爲了發送數據,應獲取Socket中的輸出流。若是要接收服務端的反饋信息,還須要獲取Socket的輸入流。
③ 經過輸出流的write()方法,將要發送的數據寫入到流中。
④ 關閉Socket流資源。
(2)TCP服務端建立步驟
① 創建服務端的Socket服務,並監聽一個端口。經過ServerSocet帶端口參數的構造函數完成。
② 獲取鏈接過來的客戶端對象,經過ServerSocket的阻塞式方法accept()接收客戶端對象。
③ 客戶端若是發過來數據,則服務端要使用對應的客戶端對象,並獲取到該客戶端對象的讀取流讀取發過來的數據,並輸出到指定目的地。
④ 關閉資源。(關閉客戶端,通常不關服務端)
4、TCP客戶端和服務端代碼示例
1 /* 需求:客戶端給服務端發送數據,服務端收到後,給客戶端反饋信息。 */
2 import java.net.*; 3 import java.io.*; 4 //(1)客戶端代碼示例
5 class TcpClient{ 6 public static void main(String[] args) throws Exception{ 7 //一、建立客戶端的Socket服務。指定目的主機和端口
8 Socket s = new Socket("127.0.0.1",10000); 9 //二、獲取Socket流中輸出流,發送數據
10 OutputStream out = s.getOutputStream(); 11 out.write("你好!".getBytes()); 12 //三、獲取Socket流中的輸入流,用來接收服務端的反饋信息並打印
13 InputStream in = s.getInputStream(); 14 byte[] buf = new byte[1024]; 15 int len = in.read(buf);//讀取反饋的數據 16 //輸出接收的數據
17 System.out.println(new String(buf,0,len)); 18 s.close();//關閉資源
19 } 20 } 21 //(2)服務端代碼示例
22 class TcpServer{ 23 public static void main(String[] args)throws Exception{ 24 //一、建立服務端的Socket服務,並監聽一個端口
25 ServerSocket ss = new ServerSocket(10000); 26 //二、經過accept方法獲取鏈接過來的客戶端對象。
27 Socket s = ss.accept(); 28 //獲取客戶端ip
29 String ip = s.getInetAddress().getHostName(); 30 System.out.println(ip+"connected...."); 31 //三、獲取對應客戶端對象的讀取流讀取發過來的數據,並打印
32 InputStream in = s.getInputStream(); 33 byte[] buf = new byte[1024]; 34 int len = in.read(buf); 35 System.out.println(new String(buf,0,len)); 36 //四、調用對應的客戶端的輸出流寫入返回數據
37 OutputStream out = s.getOutputStream(); 38 out.write("哥們,收到!".getBytes()); 39 //關閉資源
40 s.close(); 41 ss.close();//可選操做
42 } 43 }
5、練習題:
(1)需求:創建一個文本轉換服務器 ,客戶端給服務端發送文本,服務端會將文本轉成大寫再返回給客戶端,並且客戶端能夠不斷的進行文本轉換。當客戶端輸入over時,轉換結束。
(2)需求:向服務器上傳一個文件,服務返回一條「上傳成功」的信息。
(四)應用示例
需求:經過利用TCP傳輸,實現併發上傳圖片
1 import java.io.*; 2 import java.net.*; 3 //客戶端
4 class PicClient { 5 public static void main(String[] args) throws Exception{ 6 //對傳入的值進行判斷
7 if (args.length!=1) { 8 System.out.println("請指定一個圖片文件!"); 9 return; 10 } 11 File file = new File(args[0]); 12 //對文件路徑進行判斷
13 if (!(file.exists()&&file.isFile())){ 14 System.out.println("你上傳的文件有問題,非文件或者不存在!"); 15 return; 16 } 17 //判斷是不是圖片文件
18 if (!file.getName().endsWith(".jpg")){ 19 System.out.println("圖片格式錯誤,請從新選擇!"); 20 return; 21 } 22 //對文件大小進行判斷
23 if (file.length()>1024*1024*5){ 24 System.out.println("你上傳的文件過大,居心叵測!"); 25 return; 26 } 27 //建立服務
28 Socket s = new Socket("localhost",10000); 29 //讀取圖片數據
30 FileInputStream fis = new FileInputStream(file); 31 //用Socket服務輸出流寫入數據
32 OutputStream out = s.getOutputStream(); 33 BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); 34 byte[] buf = new byte[1024]; 35 int len = 0; 36 while ((len = fis.read(buf))! = -1){ 37 out.write(buf,0,len); 38 } 39 //結束標記,表示文件數據已經上傳完了
40 s.shutdownOutput(); 41 String info=in.readLine();//讀取返回信息
42 System.out.println(info); 43 fis.close();//關流
44 s.close(); 45 } 46 } 47
48 //服務端
49 class PicServer{ 50 public static void main(String[] args)throws Exception{ 51 //建立服務,監聽端口
52 ServerSocket ss = new ServerSocket(10000); 53 while (true){ 54 //獲取客戶端對象
55 Socket s = ss.accept(); 56 //客戶端執行線程
57 new Thread(new PicThread(s)).start(); 58 } 59 //ss.close();
60 } 61 } 62
63 //利用多線程實現併發上傳
64 class PicThread implements Runnable{ 65 private Socket s; 66 PicThread(Socket s){ 67 this.s = s; 68 } 69 public void run(){ 70 int count = 1; 71 //獲取客戶端ip
72 String ip = s.getInetAddress().getHostAddress(); 73 try{ 74 System.out.println(ip+" connected....."); 75 //經過客戶端的讀取流讀取數據
76 InputStream in = s.getInputStream(); 77 //文件保存路徑
78 File dir = new File("C:\\Users\\asus\\Desktop"); 79 //文件名
80 File file = new File(dir,ip+".jpg"); 81 //判斷文件是否存在
82 while(file.exists()){ 83 file = new File(dir,ip+"("+(count++)+").jpg"); 84 } 85 //將數據寫入到指定文件中
86 FileOutputStream fos = new FileOutputStream(file); 87 byte[] buf = new byte[1024]; 88 int len = 0; 89 while ((len = in.read(buf))! = -1){ 90 fos.write(buf,0,len); 91 } 92 //將收到圖片數據的信息返回給客戶端
93 OutputStream out = s.getOutputStream(); 94 out.write("上傳成功!".getBytes()); 95 fos.close();//關流
96 s.close(); 97 }catch (Exception e){ 98 throw new RuntimeException(ip+"圖片上傳失敗"); 99 } 100 } 101 }
4、URL&URLConnection
(一)概述
一、URI:表示一個統一資源標識符 (URI) 引用。
二、URL:表明一個統一資源定位符,它是指向互聯網「資源」的指針。
三、URN:統一資源名稱。
(二)經常使用方法
(1)構造函數:
URL(String protocol,String host,int port,String file):根據指定 protocol、host、port號和 file 建立 URL對象。
(2)InputStream openStream() :打開到此 URL 的鏈接並返回一個用於從該鏈接讀入的 InputStream。
(3)String getProtocol():獲取協議名稱。
(4)String getHost():獲取主機名。
(5)int getPort():獲取端口號。
(6)String getFile():獲取URL文件名。
(7)String getPath():獲取此URL的路徑部分。
(8)String getQuery():獲取此URL的查詢部,客戶端傳輸的特定信息。
(三)URLConnection
(1)URLConnection openConnection():用URL調用此方法,返回一個 URLConnection 對象,它表示到 URL 所引用的遠程對象的鏈接。
(2)InputStream getInputStream():獲取輸入流
(3)OutputStream getOutputStream():獲取輸出流
注:openStream的底層是經過openConnection()實現的。url.openStream()的能夠用如下代碼來代替實現:
1 URL url = new URL(「str_rul」);//str_url是表示「ip地址+端口+路徑文件+參數」的字符串。
2 URLConcetion conn = url.openConnection(); 3 InputStream in = conn.getInputStream();
(四)URL應用示例
1 import java.io.IOException; 2 import java.io.InputStream; 3 import java.net.URL; 4 import java.net.URLConnection; 5 public class URLDemo { 6 public static void main(String[] args) throws IOException { 7 String str_url = "http://127.0.0.1:8080/myweb/1.html"; 8 URL url = new URL(str_url); 9 System.out.println("getProtocol:"+url.getProtocol()); 10 System.out.println("getHost:"+url.getHost()); 11 System.out.println("getPort:"+url.getPort()); 12 System.out.println("getFile:"+url.getFile()); 13 System.out.println("getPath:"+url.getPath()); 14 System.out.println("getQuery:"+url.getQuery()); 15 InputStream in = url.openStream(); 16 //獲取url對象的Url鏈接器對象。將鏈接封裝成了對象:java中內置的能夠解析的具體協議的對象+socket.
17 URLConnection conn = url.openConnection(); 18 String value = conn.getHeaderField("Content-Type"); 19 System.out.println(value); 20 System.out.println(conn); 21 InputStream in = conn.getInputStream(); 22 byte[] buf = new byte[1024]; 23 int len = in.read(buf); 24 String text = new String(buf,0,len); 25 System.out.println(text); 26 in.close(); 27 } 28 }
5、常見網路結構
(一)C/S結構(client/server)
一、特色:
該結構的軟件,客戶端和服務端都須要編寫。
可發成本較高,維護較爲麻煩。
二、好處:
客戶端在本地能夠分擔一部分運算。
(二)B/S結構(browser/server)
一、特色:
該結構的軟件,只開發服務器端,不開發客戶端,由於客戶端直接由瀏覽器取代。
開發成本相對低,維護更爲簡單。
二、缺點:
全部運算都要在服務端完成。