---------- android培訓(xùn)、java培訓(xùn)、期待與您交流! ----------
一、網(wǎng)絡(luò)模型概述
網(wǎng)絡(luò)模型示意圖:

說明:
(1)數(shù)據(jù)的傳輸:在用戶端,應(yīng)用層的數(shù)據(jù),經(jīng)過層層封包,最后到物理層,通過網(wǎng)絡(luò)發(fā)送到網(wǎng)絡(luò)的另一端,再從物理層到應(yīng)用層進(jìn)行層層解包。
(2)常用層的協(xié)議,包括:應(yīng)用層的FTP和HTTP協(xié)議等;傳輸層的UDP和TCP等;網(wǎng)際層的ip等。
(3)對于開發(fā)者來講,一般處于傳輸層和網(wǎng)際層。對于用戶,通常停留在應(yīng)用層。
二、網(wǎng)絡(luò)通訊要素
網(wǎng)絡(luò)通訊要素,包括:IP地址、端口號 以及 傳輸協(xié)議。
(一)IP地址
1、IP地址概述
(1)它是網(wǎng)絡(luò)設(shè)備標(biāo)識;
(2)可用主機(jī)名表示;
(3)localhost:回路網(wǎng)絡(luò)接口的標(biāo)準(zhǔn)主機(jī)名;
(4)本機(jī)回環(huán)地址:127.0.0.1。
2、IP地址對象——InetAddress類
(1)IP地址:在java中對應(yīng)的是InetAddress類,存在于java.net包中。
(2)InetAddress類:無構(gòu)造函數(shù)。
(3)可通過getLocalHost()方法獲取InetAddress對象,此方法是靜態(tài)的,返回本類對象。InetAddress ip = InetAddress.getLocalHost();
(4)InetAddress常用方法:
① static InetAddress getByName(String host):獲取指定主機(jī)的IP和主機(jī)名。
② String getHostAddress():返回IP地址字符串文本形式,以IP地址為主。
③ String getHostName():返回IP地址主機(jī)名。
④ static InetAddress[] getAllByName(String host):在給定主機(jī)名的情況下,根據(jù)系統(tǒng)上配置的名稱服務(wù)返回IP地址所組成的數(shù)組,返回ip地址不唯一。
(5)如何獲取其他主機(jī)的IP地址對象:
① 功能:返回InetAddress對象
② 對于任意主機(jī),需要指定傳入主機(jī)名的參數(shù)
注意:如果IP地址和對應(yīng)的主機(jī)名,這種映射關(guān)系沒有在網(wǎng)絡(luò)上,就不會解析成功,返回的還是指定的IP。
(6)示例代碼:
// 1、獲取本地主機(jī)地址對象
InetAddress ip = InetAddress.getLocalHost();
System.out.PRintln(ip.getHostAddress() + ip.getHostName());
// 2、獲取其他主機(jī)的ip地址對象
ip = InetAddress.getByName(“ip地址或者DNS”);
System.out.println(ip.getHostAddress);
// 3、獲取百度域名的ip地址群
InetAddress[] ips = InetAddress.getAllByName(“www.baidu.com”);
for( InetAddress ip : ips ){
System.out.println(ip.getHostAddress())
}
(二)端口號
1、用于標(biāo)識進(jìn)程的邏輯地址,不用進(jìn)程的標(biāo)識。
2、有效端口:0 ~65535,其中0~ 1024是系統(tǒng)使用或保留的端口。
(三)傳輸協(xié)議
傳輸協(xié)議:即通信規(guī)則,常見的有UDP協(xié)議、TCP協(xié)議。
1、UDP協(xié)議:是面向無連接,明確了對方的端口,無論在不在網(wǎng)上,只管傳輸,不在就會丟失數(shù)據(jù)。只求速度,應(yīng)用于網(wǎng)絡(luò)視頻會議和聊天等應(yīng)用程序中。其特點(diǎn)有:
(1)將數(shù)據(jù)和源、目的封裝成包,不需要建立鏈接;
(2)每個(gè)數(shù)據(jù)包的大小限制在64K之內(nèi);
(3)因無連接,是不可靠的協(xié)議;
(4)不需建立連接,速度快;
2、TCP協(xié)議:是面向連接的,必須連接成功才能傳輸數(shù)據(jù),應(yīng)用于下載等程序上。其特點(diǎn)是:
(1)建立連接,形成傳輸數(shù)據(jù)通道;
(2)在連接中進(jìn)行大數(shù)據(jù)量傳輸;
(3)通過三次握手完成連接,是可靠的協(xié)議;
(4)必須建立連接,效率會低一些;
三、網(wǎng)絡(luò)傳輸協(xié)議
(一)Socket:Socket是為網(wǎng)絡(luò)服務(wù)提供的一種機(jī)制。
1、通信兩端都要有Socket;
2、網(wǎng)絡(luò)通信,其實(shí)就是Socket間的通信;
3、數(shù)據(jù)在兩個(gè)Socket間通過IO傳輸;
(二)UDP傳輸
1、概述
UDP傳輸是通過DatagramSocket類來實(shí)現(xiàn)的,此類表示用來發(fā)送和接收數(shù)據(jù)包的套接字,存在java.net包中。
2、常用方法:
① DatagramSocket():創(chuàng)建 UDPSocket發(fā)送服務(wù)對象,不指定端口號。
② DatagramSocket(int port):創(chuàng)建 UDPSocket發(fā)送服務(wù)對象,指定端口號。
③ void send(DatagramPacket p):發(fā)送數(shù)據(jù)報(bào)包。
④ void receive(DatagramPacket p):接收數(shù)據(jù)報(bào)包。
3、創(chuàng)建UDP發(fā)送端、UDP接收端步驟:
(1)UDP發(fā)送端
① 建立UDP的Socket服務(wù)。
② 將要發(fā)送的數(shù)據(jù)封裝到數(shù)據(jù)包中。
③ 用UDP的socket服務(wù)將數(shù)據(jù)包發(fā)送出去。
④ 關(guān)閉Socket服務(wù)。
(2)UDP接收端
① 建立UDP Socket服務(wù),因?yàn)橐邮諗?shù)據(jù),必須要明確一個(gè)端口號。
② 定義一個(gè)數(shù)據(jù)包,用來存儲接收到的字節(jié)數(shù)據(jù),因?yàn)閿?shù)據(jù)包對象中有更多功能可以提取字節(jié)數(shù)據(jù)中的不同數(shù)據(jù)信息。
③ 通過socket服務(wù)的receive方法,將接收到的數(shù)據(jù)存入已定義好的數(shù)據(jù)包中。
④ 通過數(shù)據(jù)包對象的特有功能,將這些不同的數(shù)據(jù)取出,打印在控制臺上。
⑤ 關(guān)閉Socket服務(wù)。
(3)注意事項(xiàng):
(1)發(fā)送端與接收端是兩個(gè)獨(dú)立的運(yùn)行程序。
(2)在發(fā)送端,要在數(shù)據(jù)包對象中明確目的地IP及端口。
(3)在接收端,要指定監(jiān)聽的端口。
4、UDP發(fā)送端、UDP接收端代碼示例
1 //(1)UDP發(fā)送端代碼: 2 import java.net.*; 3 class UDPSend{ 4 public static void main(String[] args)throws Exception{ 5 //1、創(chuàng)建UDP服務(wù),使用DatagramSocket對象。 6 DatagramSocket ds = new DatagramSocket(8888); 7 //2、將要發(fā)送的數(shù)據(jù)封裝到數(shù)據(jù)包中,用到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 //3、通過Socket服務(wù),將已有的數(shù)據(jù)包發(fā)送出去。通過send方法11 ds.send(dp);12 //4、關(guān)閉資源13 ds.close();14 }15 }16 //(2)UDP接收端代碼:17 class UDPReceive{18 public static void main(String[] args)throws Exception{19 //一直處于接收狀態(tài)20 while(true)21 {22 // 1. 創(chuàng)建udp Socket服務(wù),建立端點(diǎn)23 DatagramSocket ds = new DatagramSocket(10000);24 // 2. 定義數(shù)據(jù)包。用于存儲數(shù)據(jù)25 byte[] buf = new byte[1024];26 DatagramPacket dp = new DatagramPacket(buf,buf.length);27 // 3. 通過Socket服務(wù)的receive方法將接收到的數(shù)據(jù)存入數(shù)據(jù)包中28 ds.receive(dp);//阻塞式方法29 // 4. 通過數(shù)據(jù)包的方法獲取其中的數(shù)據(jù)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. 關(guān)閉資源35 ds.close();36 }37 }38 }5、練習(xí)題:
(1)用鍵盤錄入的方式,來發(fā)送數(shù)據(jù)。
(2)編寫一個(gè)聊天程序,有收數(shù)據(jù)的部分和發(fā)數(shù)據(jù)的部分。
(三)TCP傳輸
1、概述
TCP傳輸分為“客戶端”和“服務(wù)端”。客戶端對應(yīng)的對象是Socket,服務(wù)端對應(yīng)的對象是ServerSocket。
2、常用方法:
(1)客戶端Socket
構(gòu)造函數(shù):
① Socket():創(chuàng)建未連接套接字。
② Socket(InetAddress address , tin port):創(chuàng)建連接到IP指定端口的套接字。
③ Socket( String host , int port ):創(chuàng)建流套接字并將其連接到指定主機(jī)上的指定端口號。
特有方法:
① getInputStream():返回此套接字的輸入流。
② getOutputStream():返回此套接字的輸出流。
③ void shutdownInput():此套接字的輸入流至于“流的末尾”。
④ void shutdownOutput():禁用此套接字的輸出流。
(2)服務(wù)端ServerSocket
① 構(gòu)造函數(shù):ServerSocket(int port):創(chuàng)建綁定到特定端口的服務(wù)器套接字。
② 特有方法:Socket accept():監(jiān)聽并接受到此套接字的連接,是阻塞式方法。
3、創(chuàng)建TCP客戶端、TCP服務(wù)端步驟:
TCP是面向連接的,在建立Socket服務(wù)時(shí),需要有服務(wù)端存在并連接成功,形成通路,再通過連接好的通路進(jìn)行數(shù)據(jù)傳輸。
(1)TCP客戶端創(chuàng)建步驟
① 創(chuàng)建Socket服務(wù),明確要連接的主機(jī)端口。
② 為了發(fā)送數(shù)據(jù),應(yīng)獲取Socket中的輸出流。如果要接收服務(wù)端的反饋信息,還需要獲取Socket的輸入流。
③ 通過輸出流的write()方法,將要發(fā)送的數(shù)據(jù)寫入到流中。
④ 關(guān)閉Socket流資源。
(2)TCP服務(wù)端創(chuàng)建步驟
① 建立服務(wù)端的Socket服務(wù),并監(jiān)聽一個(gè)端口。通過ServerSocet帶端口參數(shù)的構(gòu)造函數(shù)完成。
② 獲取連接過來的客戶端對象,通過ServerSocket的阻塞式方法accept()接收客戶端對象。
③ 客戶端如果發(fā)過來數(shù)據(jù),則服務(wù)端要使用對應(yīng)的客戶端對象,并獲取到該客戶端對象的讀取流讀取發(fā)過來的數(shù)據(jù),并輸出到指定目的地。
④ 關(guān)閉資源。(關(guān)閉客戶端,一般不關(guān)服務(wù)端)
4、TCP客戶端和服務(wù)端代碼示例
1 /* 需求:客戶端給服務(wù)端發(fā)送數(shù)據(jù),服務(wù)端收到后,給客戶端反饋信息。 */ 2 import java.net.*; 3 import java.io.*; 4 //(1)客戶端代碼示例 5 class TcpClient{ 6 public static void main(String[] args) throws Exception{ 7 //1、創(chuàng)建客戶端的Socket服務(wù)。指定目的主機(jī)和端口 8 Socket s = new Socket("127.0.0.1",10000); 9 //2、獲取Socket流中輸出流,發(fā)送數(shù)據(jù)10 OutputStream out = s.getOutputStream();11 out.write("你好!".getBytes());12 //3、獲取Socket流中的輸入流,用來接收服務(wù)端的反饋信息并打印13 InputStream in = s.getInputStream();14 byte[] buf = new byte[1024];15 int len = in.read(buf);//讀取反饋的數(shù)據(jù)16 //輸出接收的數(shù)據(jù)17 System.out.println(new String(buf,0,len));18 s.close();//關(guān)閉資源19 }20 }21 //(2)服務(wù)端代碼示例22 class TcpServer{23 public static void main(String[] args)throws Exception{24 //1、創(chuàng)建服務(wù)端的Socket服務(wù),并監(jiān)聽一個(gè)端口25 ServerSocket ss = new ServerSocket(10000);26 //2、通過accept方法獲取連接過來的客戶端對象。27 Socket s = ss.accept();28 //獲取客戶端ip29 String ip = s.getInetAddress().getHostName();30 System.out.println(ip+"connected....");31 //3、獲取對應(yīng)客戶端對象的讀取流讀取發(fā)過來的數(shù)據(jù),并打印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 //4、調(diào)用對應(yīng)的客戶端的輸出流寫入返回?cái)?shù)據(jù)37 OutputStream out = s.getOutputStream();38 out.write("哥們,收到!".getBytes()); 39 //關(guān)閉資源40 s.close();41 ss.close();//可選操作42 }43 }5、練習(xí)題:
(1)需求:建立一個(gè)文本轉(zhuǎn)換服務(wù)器 ,客戶端給服務(wù)端發(fā)送文本,服務(wù)端會將文本轉(zhuǎn)成大寫再返回給客戶端,而且客戶端可以不斷的進(jìn)行文本轉(zhuǎn)換。當(dāng)客戶端輸入over時(shí),轉(zhuǎn)換結(jié)束。
(2)需求:向服務(wù)器上傳一個(gè)文件,服務(wù)返回一條“上傳成功”的信息。
(四)應(yīng)用示例
需求:通過利用TCP傳輸,實(shí)現(xiàn)并發(fā)上傳圖片
1 import java.io.*; 2 import java.net.*; 3 //客戶端 4 class PicClient { 5 public static void main(String[] args) throws Exception{ 6 //對傳入的值進(jìn)行判斷 7 if (args.length!=1) { 8 System.out.println("請指定一個(gè)圖片文件!"); 9 return; 10 } 11 File file = new File(args[0]); 12 //對文件路徑進(jìn)行判斷 13 if (!(file.exists()&&file.isFile())){ 14 System.out.println("你上傳的文件有問題,非文件或者不存在!"); 15 return; 16 } 17 //判斷是否是圖片文件 18 if (!file.getName().endsWith(".jpg")){ 19 System.out.println("圖片格式錯(cuò)誤,請重新選擇!"); 20 return; 21 } 22 //對文件大小進(jìn)行判斷 23 if (file.length()>1024*1024*5){ 24 System.out.println("你上傳的文件過大,居心叵測!"); 25 return; 26 } 27 //創(chuàng)建服務(wù) 28 Socket s = new Socket("localhost",10000); 29 //讀取圖片數(shù)據(jù) 30 FileInputStream fis = new FileInputStream(file); 31 //用Socket服務(wù)輸出流寫入數(shù)據(jù) 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 //結(jié)束標(biāo)記,表示文件數(shù)據(jù)已經(jīng)上傳完了 40 s.shutdownOutput(); 41 String info=in.readLine();//讀取返回信息 42 System.out.println(info); 43 fis.close();//關(guān)流 44 s.close(); 45 } 46 } 47 48 //服務(wù)端 49 class PicServer{ 50 public static void main(String[] args)throws Exception{ 51 //創(chuàng)建服務(wù),監(jiān)聽端口 52 ServerSocket ss = new ServerSocket(10000); 53 while (true){ 54 //獲取客戶端對象 55 Socket s = ss.accept(); 56 //客戶端執(zhí)行線程 57 new Thread(new PicThread(s)).start(); 58 } 59 //ss.close(); 60 } 61 } 62 63 //利用多線程實(shí)現(xiàn)并發(fā)上傳 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 //通過客戶端的讀取流讀取數(shù)據(jù) 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 //將數(shù)據(jù)寫入到指定文件中 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 //將收到圖片數(shù)據(jù)的信息返回給客戶端 93 OutputStream out = s.getOutputStream(); 94 out.write("上傳成功!".getBytes()); 95 fos.close();//關(guān)流 96 s.close(); 97 }catch (Exception e){ 98 throw new RuntimeException(ip+"圖片上傳失敗"); 99 }100 }101 }四、URL&URLConnection
(一)概述
1、URI:表示一個(gè)統(tǒng)一資源標(biāo)識符 (URI) 引用。
2、URL:代表一個(gè)統(tǒng)一資源定位符,它是指向互聯(lián)網(wǎng)“資源”的指針。
3、URN:統(tǒng)一資源名稱。
(二)常用方法
(1)構(gòu)造函數(shù):
URL(String protocol,String host,int port,String file):根據(jù)指定 protocol、host、port號和 file 創(chuàng)建 URL對象。
(2)InputStream openStream() :打開到此 URL 的連接并返回一個(gè)用于從該連接讀入的 InputStream。
(3)String getProtocol():獲取協(xié)議名稱。
(4)String getHost():獲取主機(jī)名。
(5)int getPort():獲取端口號。
(6)String getFile():獲取URL文件名。
(7)String getPath():獲取此URL的路徑部分。
(8)String getQuery():獲取此URL的查詢部,客戶端傳輸?shù)奶囟ㄐ畔ⅰ?/p>
(三)URLConnection
(1)URLConnection openConnection():用URL調(diào)用此方法,返回一個(gè) URLConnection 對象,它表示到 URL 所引用的遠(yuǎn)程對象的連接。
(2)InputStream getInputStream():獲取輸入流
(3)OutputStream getOutputStream():獲取輸出流
注:openStream的底層是通過openConnection()實(shí)現(xiàn)的。url.openStream()的可以用以下代碼來代替實(shí)現(xiàn):
1 URL url = new URL(“str_rul”);//str_url是表示“ip地址+端口+路徑文件+參數(shù)”的字符串。2 URLConcetion conn = url.openConnection();3 InputStream in = conn.getInputStream();
(四)URL應(yīng)用示例
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中內(nèi)置的可以解析的具體協(xié)議的對象+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 }五、常見網(wǎng)路結(jié)構(gòu)
(一)C/S結(jié)構(gòu)(client/server)
1、特點(diǎn):
該結(jié)構(gòu)的軟件,客戶端和服務(wù)端都需要編寫。
可發(fā)成本較高,維護(hù)較為麻煩。
2、好處:
客戶端在本地可以分擔(dān)一部分運(yùn)算。
(二)B/S結(jié)構(gòu)(browser/server)
1、特點(diǎn):
該結(jié)構(gòu)的軟件,只開發(fā)服務(wù)器端,不開發(fā)客戶端,因?yàn)榭蛻舳酥苯佑蔀g覽器取代。
開發(fā)成本相對低,維護(hù)更為簡單。
2、缺點(diǎn):
所有運(yùn)算都要在服務(wù)端完成。
---------- android培訓(xùn)、java培訓(xùn)、期待與您交流! ----------
新聞熱點(diǎn)
疑難解答
圖片精選