第十四章:Java_网络编程
網(wǎng)絡(luò)編程概述:
Java是 Internet 上的語言,它從語言級上提供了對網(wǎng)絡(luò)應用程序的支持,程序員能夠很容易開發(fā)常見的網(wǎng)絡(luò)應用程序。
Java提供的網(wǎng)絡(luò)類庫,可以實現(xiàn)無痛的網(wǎng)絡(luò)連接,聯(lián)網(wǎng)的底層細節(jié)被隱藏在 Java 的本機安裝系統(tǒng)里,由 JVM 進行控制。并且 Java 實現(xiàn)了一個跨平臺的網(wǎng)絡(luò)庫,程序員面對的是一個統(tǒng)一的網(wǎng)絡(luò)編程環(huán)境。
1.要想實現(xiàn)網(wǎng)絡(luò)傳輸,需要考慮的問題有哪些?
1.1 如何才能準確的定位網(wǎng)絡(luò)上的一臺主機?
1.2 如何才能進行可靠的、高效的數(shù)據(jù)傳輸?
2.Java如何實現(xiàn)的網(wǎng)絡(luò)通信
2.1使用IP地址—定位一臺主機 使用端口號—定位一個應用 ===>InetAddress類
①如何創(chuàng)建一個InetAddress的對象?getByName(“”); 比如:InetAddress inet = InetAddress.getByName(“192.168.10.165”);
②如何獲取本機的一個InetAddress的對象?getLocalHost()
③域名:getHostName() ip:getHostAddress()2.2對應有協(xié)議
通訊要素1:IP 和 端口號
IP 地址:InetAddress
唯一的標識 Internet 上的計算機
本地回環(huán)地址(hostAddress):127.0.0.1 主機名(hostName):localhost
不易記憶
端口號標識正在計算機上運行的進程(程序)
不同的進程有不同的端口號
被規(guī)定為一個 16 位的整數(shù) 0~65535。其中,0~1023被預先定義的服務通信占用(如MySql占用端口3306,http占用端口80等)。除非我們需要訪問這些特定服務,否則,就應該使用 1024~65535 這些端口中的某一個進行通信,以免發(fā)生端口沖突。
端口號與IP地址的組合得出一個網(wǎng)絡(luò)套接字。
通訊要素2:網(wǎng)絡(luò)通信協(xié)議
網(wǎng)絡(luò)通信協(xié)議
計算機網(wǎng)絡(luò)中實現(xiàn)通信必須有一些約定,即通信協(xié)議,對速率、傳輸代碼、代碼結(jié)構(gòu)、傳輸控制步驟、出錯控制等制定標準。
通信協(xié)議分層的思想
由于結(jié)點之間聯(lián)系很復雜,在制定協(xié)議時,把復雜成份分解成一些簡單的成份,再將它們復合起來。最常用的復合方式是層次方式,即同層間可以通信、上一層可以調(diào)用下一層,而與再下一層不發(fā)生關(guān)系。各層互不影響,利于系統(tǒng)的開發(fā)和擴展。
TCP/IP協(xié)議簇
- 傳輸層協(xié)議中有兩個非常重要的協(xié)議:
傳輸控制協(xié)議TCP(Transmission Control Protocol)
用戶數(shù)據(jù)報協(xié)議UDP(User Datagram Protocol)。 - TCP/IP 以其兩個主要協(xié)議:傳輸控制協(xié)議(TCP)和網(wǎng)絡(luò)互聯(lián)協(xié)議(IP)而得名,實際上是一組協(xié)議,包括多個具有不同功能且互為關(guān)聯(lián)的協(xié)議。
- IP(Internet Protocol)協(xié)議是網(wǎng)絡(luò)層的主要協(xié)議,支持網(wǎng)間互連的數(shù)據(jù)通信。
- TCP/IP協(xié)議模型從更實用的角度出發(fā),形成了高效的四層體系結(jié)構(gòu),即物理鏈路層、IP層、傳輸層和應用層。
TCP和UDP
- TCP協(xié)議:
使用TCP協(xié)議前,須先建立TCP連接,形成傳輸數(shù)據(jù)通道
傳輸前,采用“三次握手”方式,是可靠的
TCP協(xié)議進行通信的兩個應用進程:客戶端、服務端
在連接中可進行大數(shù)據(jù)量的傳輸
傳輸完畢,需釋放已建立的連接,效率低 - UDP協(xié)議:
將數(shù)據(jù)、源、目的封裝成數(shù)據(jù)包,不需要建立連接
每個數(shù)據(jù)報的大小限制在64K內(nèi)
因無需連接,故是不可靠的
發(fā)送數(shù)據(jù)結(jié)束時無需釋放資源,速度快
TCP的編程: Socket ServerSocket
例子:
1.客戶端發(fā)送內(nèi)容給服務端,服務端將內(nèi)容打印到控制臺上。
2.客戶端發(fā)送內(nèi)容給服務端,服務端給予反饋。
//TCP編程例二:客戶端給服務端發(fā)送信息,服務端將信息打印到控制臺上,同時發(fā)送“已收到信息”給客戶端 public class TestTCP2 {//客戶端@Testpublic void client(){Socket socket = null;OutputStream os = null;InputStream is = null;try {socket = new Socket(InetAddress.getByName("127.0.0.1"),8989);os = socket.getOutputStream();os.write("我是客戶端".getBytes());//shutdownOutput():執(zhí)行此方法,顯式的告訴服務端發(fā)送完畢!socket.shutdownOutput();is = socket.getInputStream();byte[] b = new byte[20];int len;while((len = is.read(b)) != -1){String str = new String(b,0,len);System.out.print(str);}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{if(is != null){try {is.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(os != null){try {os.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(socket != null){try {socket.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}//服務端@Testpublic void server(){ServerSocket ss = null;Socket s = null;InputStream is = null;OutputStream os = null;try {ss = new ServerSocket(8989);s = ss.accept();is = s.getInputStream();byte[] b = new byte[20];int len;while((len = is.read(b)) != -1){String str = new String(b,0,len);System.out.print(str);}os = s.getOutputStream();os.write("我已收到你的情意".getBytes());} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{if(os != null){try {os.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(is != null){try {is.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(s != null){try {s.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(ss != null){try {ss.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}} }3.從客戶端發(fā)送文件給服務端,服務端保存到本地。并返回“發(fā)送成功”給客戶端。并關(guān)閉相應的連接。
//TCP編程例三:從客戶端發(fā)送文件給服務端,服務端保存到本地。并返回“發(fā)送成功”給客戶端。并關(guān)閉相應的連接。 //如下的程序,處理異常時,要使用try-catch-finally!!本例僅為了書寫方便~ public class TestTCP3 {@Testpublic void client()throws Exception{//1.創(chuàng)建Socket的對象Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9898);//2.從本地獲取一個文件發(fā)送給服務端OutputStream os = socket.getOutputStream();FileInputStream fis = new FileInputStream(new File("1.jpg"));byte[] b = new byte[1024];int len;while((len = fis.read(b)) != -1){os.write(b,0,len);}socket.shutdownOutput();//3.接收來自于服務端的信息InputStream is = socket.getInputStream();byte[] b1 = new byte[1024];int len1;while((len1 = is.read(b1)) != -1){String str = new String(b1,0,len1);System.out.print(str);}//4.關(guān)閉相應的流和Socket對象is.close();os.close();fis.close();socket.close();}@Testpublic void server() throws Exception{//1.創(chuàng)建一個ServerSocket的對象ServerSocket ss = new ServerSocket(9898);//2.調(diào)用其accept()方法,返回一個Socket的對象Socket s = ss.accept();//3.將從客戶端發(fā)送來的信息保存到本地InputStream is = s.getInputStream();FileOutputStream fos = new FileOutputStream(new File("3.jpg"));byte[] b = new byte[1024];int len;while((len = is.read(b)) != -1){fos.write(b, 0, len);}System.out.println("收到來自于" + s.getInetAddress().getHostAddress() + "的文件");//4.發(fā)送"接收成功"的信息反饋給客戶端OutputStream os = s.getOutputStream();os.write("你發(fā)送的圖片我已接收成功!".getBytes());//5.關(guān)閉相應的流和Socket及ServerSocket的對象os.close();fos.close();is.close();s.close();ss.close();} }UDP的編程: DatagramSocket DatagramPacket
//UDP編程的實現(xiàn) public class TestUDP {// 發(fā)送端@Testpublic void send() {DatagramSocket ds = null;try {ds = new DatagramSocket();byte[] b = "你好,我是要發(fā)送的數(shù)據(jù)".getBytes();//創(chuàng)建一個數(shù)據(jù)報:每一個數(shù)據(jù)報不能大于64k,都記錄著數(shù)據(jù)信息,發(fā)送端的IP、端口號,以及要發(fā)送到//的接收端的IP、端口號。DatagramPacket pack = new DatagramPacket(b, 0, b.length,InetAddress.getByName("127.0.0.1"), 9090);ds.send(pack);}catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{if(ds != null){ds.close();}}}// 接收端@Testpublic void rceive() {DatagramSocket ds = null;try {ds = new DatagramSocket(9090);byte[] b = new byte[1024];DatagramPacket pack = new DatagramPacket(b, 0, b.length);ds.receive(pack);String str = new String(pack.getData(), 0, pack.getLength());System.out.println(str);}catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{if(ds != null){ds.close();}}} }URL的編程:統(tǒng)一資源定位符一個URL的對象,對應著互聯(lián)網(wǎng)上一個資源。
我們可以通過URL的對象調(diào)用其相應的方法,將此資源讀取(“下載”)
//URL:統(tǒng)一資源定位符,一個URL的對象,對應著互聯(lián)網(wǎng)上一個資源。 //我們可以通過URL的對象調(diào)用其相應的方法,將此資源讀取(“下載”) public class TestURL {public static void main(String[] args) throws Exception {//1.創(chuàng)建一個URL的對象URL url = new URL("http://127.0.0.1:8080/examples/HelloWorld.txt?a=b");//File file = new File("文件的路徑");/** public String getProtocol( ) 獲取該URL的協(xié)議名public String getHost( ) 獲取該URL的主機名public String getPort( ) 獲取該URL的端口號public String getPath( ) 獲取該URL的文件路徑public String getFile( ) 獲取該URL的文件名public String getRef( ) 獲取該URL在文件中的相對位置public String getQuery( ) 獲取該URL的查詢名*/ // System.out.println(url.getProtocol()); // System.out.println(url.getHost()); // System.out.println(url.getPort()); // System.out.println(url.getFile()); // System.out.println(url.getRef()); // System.out.println(url.getQuery());//如何將服務端的資源讀取進來:openStream()InputStream is = url.openStream();byte[] b = new byte[20];int len;while((len = is.read(b)) != -1){String str = new String(b,0,len);System.out.print(str);}is.close();//如果既有數(shù)據(jù)的輸入,又有數(shù)據(jù)的輸出,則考慮使用URLConnectionURLConnection urlConn = url.openConnection();InputStream is1 = urlConn.getInputStream();FileOutputStream fos = new FileOutputStream(new File("abc.txt"));byte[] b1 = new byte[20];int len1;while((len1 = is1.read(b1)) != -1){fos.write(b1, 0, len1);}fos.close();is1.close();} }小結(jié)
位于網(wǎng)絡(luò)中的計算機具有唯一的IP地址,這樣不同的主機可以互相區(qū)分。
客戶端-服務器是一種最常見的網(wǎng)絡(luò)應用程序模型。服務器是一個為其客戶端提供某種特定服務的硬件或軟件。客戶機是一個用戶應用程序,用于訪問某臺服務器提供的服務。端口號是對一個服務的訪問場所,它用于區(qū)分同一物理計算機上的多個服務。套接字用于連接客戶端和服務器,客戶端和服務器之間的每個通信會話使用一個不同的套接字。TCP協(xié)議用于實現(xiàn)面向連接的會話。
Java 中有關(guān)網(wǎng)絡(luò)方面的功能都定義在 java.net 程序包中。Java 用 InetAddress 對象表示 IP 地址,該對象里有兩個字段:主機名(String) 和 IP 地址(int)。
Java 中有關(guān)網(wǎng)絡(luò)方面的功能都定義在 java.net 程序包中。Java 用 InetAddress 對象表示 IP 地址,該對象里有兩個字段:主機名(String) 和 IP 地址(int)。
類 URL 和 URLConnection 提供了最高級網(wǎng)絡(luò)應用。URL 的網(wǎng)絡(luò)資源的位置來同一表示 Internet 上各種網(wǎng)絡(luò)資源。通過URL對象可以創(chuàng)建當前應用程序和 URL 表示的網(wǎng)絡(luò)資源之間的連接,這樣當前程序就可以讀取網(wǎng)絡(luò)資源數(shù)據(jù),或者把自己的數(shù)據(jù)傳送到網(wǎng)絡(luò)上去。
總結(jié)
以上是生活随笔為你收集整理的第十四章:Java_网络编程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 方立勋_30天掌握JavaWeb_XML
- 下一篇: 第一章:Java语言概述