溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java網(wǎng)絡(luò)編程的示例分析

發(fā)布時(shí)間:2021-06-11 09:15:06 來源:億速云 閱讀:176 作者:小新 欄目:開發(fā)技術(shù)

小編給大家分享一下Java網(wǎng)絡(luò)編程的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

一、網(wǎng)絡(luò)編程

1.1、概述

1、計(jì)算機(jī)網(wǎng)絡(luò)是通過傳輸介質(zhì)、通信設(shè)施和網(wǎng)絡(luò)通信協(xié)議,把分散在不同地點(diǎn)的計(jì)算機(jī)設(shè)備互連起來,實(shí)現(xiàn)資源共享和數(shù)據(jù)傳輸?shù)南到y(tǒng)。網(wǎng)絡(luò)編程就就是編寫程序使聯(lián)網(wǎng)的兩個(gè)(或多個(gè))設(shè)備(例如計(jì)算機(jī))之間進(jìn)行數(shù)據(jù)傳輸。Java語(yǔ)言對(duì)網(wǎng)絡(luò)編程提供了良好的支持,通過其提供的接口我們可以很方便地進(jìn)行網(wǎng)絡(luò)編程。

2、Java是 Internet 上的語(yǔ)言,它從語(yǔ)言級(jí)上提供了對(duì)網(wǎng)絡(luò)應(yīng)用程 序的支持,程序員能夠很容易開發(fā)常見的網(wǎng)絡(luò)應(yīng)用程序。

3、Java提供的網(wǎng)絡(luò)類庫(kù),可以實(shí)現(xiàn)無痛的網(wǎng)絡(luò)連接,聯(lián)網(wǎng)的底層細(xì)節(jié)被隱藏在 Java 的本機(jī)安裝系統(tǒng)里,由 JVM 進(jìn)行控制。并 且 Java 實(shí)現(xiàn)了一個(gè)跨平臺(tái)的網(wǎng)絡(luò)庫(kù),程序員面對(duì)的是一個(gè)統(tǒng)一的網(wǎng)絡(luò)編程環(huán)境。

1.2、計(jì)算機(jī)網(wǎng)絡(luò)基礎(chǔ)

1、概念

把分布在不同地理區(qū)域的計(jì)算機(jī)與專門的外部設(shè)備用通信線路互連成一個(gè)規(guī)模大、功能強(qiáng)的網(wǎng)絡(luò)系統(tǒng),從而使眾多的計(jì)算機(jī)可以方便地互相傳遞信息、 共享硬件、軟件、數(shù)據(jù)信息等資源。

計(jì)算機(jī)網(wǎng)絡(luò)是計(jì)算機(jī)專業(yè)必修的一門學(xué)科!里面涉及到計(jì)算機(jī)之間的通信、網(wǎng)絡(luò)安全等方方面面,有時(shí)間可以自行去學(xué)習(xí),關(guān)于更多的網(wǎng)絡(luò)基礎(chǔ)知識(shí)這里就不一一介紹了。

2、網(wǎng)絡(luò)編程的目的

直接或間接地通過網(wǎng)絡(luò)協(xié)議與其它計(jì)算機(jī)實(shí)現(xiàn)數(shù)據(jù)交換,進(jìn)行通訊。

3、網(wǎng)絡(luò)編程中有兩個(gè)主要的問題

①如何準(zhǔn)確地定位網(wǎng)絡(luò)上一臺(tái)或多臺(tái)主機(jī);定位主機(jī)上的特定的應(yīng)用

②找到主機(jī)后如何可靠高效地進(jìn)行數(shù)據(jù)傳輸

1.3、網(wǎng)絡(luò)通信要素概述

1、我們需要知道的是主機(jī)間通過網(wǎng)絡(luò)進(jìn)行通信是需要遵循網(wǎng)絡(luò)通信協(xié)議,是通過IP地址準(zhǔn)確定位主機(jī),通過端口號(hào)準(zhǔn)確定位主機(jī)上的應(yīng)用。

IP地址和端口號(hào)

網(wǎng)絡(luò)通信協(xié)議

2、如何實(shí)現(xiàn)網(wǎng)絡(luò)中的主機(jī)互相通信?

① 通信雙方地址:IP和端口號(hào)

② 一定的規(guī)則(即:網(wǎng)絡(luò)通信協(xié)議。有兩套參考模型)

OSI參考模型:模型過于理想化,未能在因特網(wǎng)上進(jìn)行廣泛推廣。

TCP/IP參考模型(或TCP/IP協(xié)議):事實(shí)上的國(guó)際標(biāo)準(zhǔn)。

3、網(wǎng)絡(luò)通信協(xié)議(以TCP/IP模型為例)

TCP/IP,即Transmission Control Protocol/Internet Protocol的簡(jiǎn)寫,中譯名為傳輸控制協(xié)議/因特網(wǎng)互聯(lián)協(xié)議,是Internet最基本的協(xié)議、Internet國(guó)際互聯(lián)網(wǎng)絡(luò)的基礎(chǔ)。

Java網(wǎng)絡(luò)編程的示例分析

1.4、IP地址和端口號(hào)(組合就是網(wǎng)絡(luò)套接字)

我們知道IP地址和端口號(hào)是通信要素之一,它們可以唯一確定某一臺(tái)主機(jī)的某個(gè)應(yīng)用,并為主機(jī)之間通信提供了可能!那么什么是IP地址和端口號(hào)呢?

1、IP 地址:InetAddress(在Java中使用InetAddress類代表IP)

  • 一的標(biāo)識(shí) Internet 上的計(jì)算機(jī)(通信實(shí)體)

  • 本地回環(huán)地址(hostAddress):127.0.0.1 主機(jī)名(hostName):localhost

  • P地址分類方式1:IPV4 和 IPV6

  • IPV4:4個(gè)字節(jié)組成,4個(gè)0-255。大概42億,30億都在北美,亞洲4億。2011年初已 經(jīng)用盡。以點(diǎn)分十進(jìn)制表示,如192.168.0.1

  • IPV6:128位(16個(gè)字節(jié)),寫成8個(gè)無符號(hào)整數(shù),每個(gè)整數(shù)用四個(gè)十六進(jìn)制位表示, 數(shù)之間用冒號(hào)(:)分開,如:3ffe:3201:1401:1280:c8ff:fe4d:db39:1984

  • IP地址分類方式2:公網(wǎng)地址(萬維網(wǎng)使用)和私有地址(局域網(wǎng)使用)。192.168. 開頭的就是私有址址,范圍即為192.168.0.0–192.168.255.255,專門為組織機(jī) 構(gòu)內(nèi)部使用

  • 特點(diǎn):不易記憶

2、InetAddress類

Internet上的主機(jī)有兩種方式表示地址:

①域名(hostName):www.baidu.com

②IP 地址(hostAddress):14.215.177.38

InetAddress類主要表示IP地址,兩個(gè)子類:Inet4Address、Inet6Address

InetAddress 類對(duì)象含有一個(gè) Internet 主機(jī)地址的域名和IP地址:www.baidu.com 和 14.215.177.38

域名容易記憶,當(dāng)在連接網(wǎng)絡(luò)時(shí)輸入一個(gè)主機(jī)的域名后,域名服務(wù)器(DNS) 負(fù)責(zé)將域名轉(zhuǎn)化成IP地址,這樣才能和主機(jī)建立連接。 -------域名解析

/*
1 java中使用InetAddress代表IP
2 IP的分類:IPV4和IPV6     萬維網(wǎng)和局域網(wǎng)

3 域名:www.baidu.com www.cnblogs.com

4 本地回路地址:127.0.0.1 對(duì)應(yīng)著:localhost

5 如何實(shí)例化InetAddress類的對(duì)象,兩個(gè)靜態(tài)方法:
    InetAddress getByName(String host)
    InetAddress getLocalHost()

6 兩個(gè)常用方法
    getHostName()
    getHostAddress()

7 端口號(hào):正在計(jì)算機(jī)上運(yùn)行的進(jìn)程
 */
public class InetAddressTest {
    public static void main(String[] args){
        try {
            // File file = new File("test.txt");
            InetAddress IP1 = InetAddress.getByName("192.168.3.2");
            System.out.println(IP1);

            InetAddress IP2 = InetAddress.getByName("www.baidu.com");
            System.out.println(IP2);
            // 獲取本地IP
            InetAddress localHost = InetAddress.getLocalHost();
            System.out.println(localHost);

            // getHostName()
            System.out.println(IP2.getHostName());
            // getHostAddress()
            System.out.println(IP2.getHostAddress());


        } catch(UnknownHostException e){
            e.printStackTrace();
        }
    }
}

3、端口號(hào)

  • 端口號(hào)就是標(biāo)識(shí)正在計(jì)算機(jī)上運(yùn)行的進(jìn)程(程序)

  • 不同的進(jìn)程有不同的端口號(hào)

  • 被規(guī)定為一個(gè) 16 位的整數(shù) 0~65535。

端口分類:

① 公認(rèn)端口:0~1023。被預(yù)先定義的服務(wù)通信占用(如:HTTP占用端口 80,F(xiàn)TP占用端口21,Telnet占用端口23)

② 注冊(cè)端口:1024~49151。分配給用戶進(jìn)程或應(yīng)用程序。(如:Tomcat占 用端口8080,MySQL占用端口3306,Oracle占用端口1521等)。

③ 動(dòng)態(tài)/私有端口:49152~65535

Java網(wǎng)絡(luò)編程的示例分析

4、端口號(hào)與IP地址的組合得出一個(gè)網(wǎng)絡(luò)套接字:Socket

1.5、網(wǎng)絡(luò)協(xié)議

1、網(wǎng)絡(luò)通信協(xié)議

計(jì)算機(jī)網(wǎng)絡(luò)中實(shí)現(xiàn)通信必須有一些約定,即通信協(xié)議,對(duì)速率、傳輸代碼、代 碼結(jié)構(gòu)、傳輸控制步驟、出錯(cuò)控制等制定標(biāo)準(zhǔn)。

2、問題:網(wǎng)絡(luò)協(xié)議太復(fù)雜

計(jì)算機(jī)網(wǎng)絡(luò)通信涉及內(nèi)容很多,比如指定源地址和目標(biāo)地址,加密解密,壓縮 解壓縮,差錯(cuò)控制,流量控制,路由控制,如何實(shí)現(xiàn)如此復(fù)雜的網(wǎng)絡(luò)協(xié)議呢?

3、通信協(xié)議分層的思想

在制定協(xié)議時(shí),把復(fù)雜成份分解成一些簡(jiǎn)單的成份,再將它們復(fù)合起來。最常 用的復(fù)合方式是層次方式,即同層間可以通信、上一層可以調(diào)用下一層,而與 再下一層不發(fā)生關(guān)系。各層互不影響,利于系統(tǒng)的開發(fā)和擴(kuò)展。

4、TCP/IP協(xié)議簇

傳輸層協(xié)議中有兩個(gè)非常重要的協(xié)議:

  • 傳輸控制協(xié)議TCP(Transmission Control Protocol)

  • 戶數(shù)據(jù)報(bào)協(xié)議UDP(User Datagram Protocol)

TCP/IP 以其兩個(gè)主要協(xié)議:傳輸控制協(xié)議(TCP)和網(wǎng)絡(luò)互聯(lián)協(xié)議(IP)而得 名,實(shí)際上是一組協(xié)議,包括多個(gè)具有不同功能且互為關(guān)聯(lián)的協(xié)議。

IP(Internet Protocol)協(xié)議是網(wǎng)絡(luò)層的主要協(xié)議,支持網(wǎng)間互連的數(shù)據(jù)通信。

TCP/IP協(xié)議模型從更實(shí)用的角度出發(fā),形成了高效的四層體系結(jié)構(gòu),即物理鏈路層、IP層、傳輸層和應(yīng)用層。

5、TCP 和 UDP

TCP協(xié)議:

? 使用TCP協(xié)議前,須先建立TCP連接,形成傳輸數(shù)據(jù)通道

? 傳輸前,采用“三次握手”方式,點(diǎn)對(duì)點(diǎn)通信,是可靠的

? TCP協(xié)議進(jìn)行通信的兩個(gè)應(yīng)用進(jìn)程:客戶端、服務(wù)端。

? 在連接中可進(jìn)行大數(shù)據(jù)量的傳輸

? 傳輸完畢,需釋放已建立的連接,效率低

UDP協(xié)議:

? 將數(shù)據(jù)、源、目的封裝成數(shù)據(jù)包,不需要建立連接

? 每個(gè)數(shù)據(jù)報(bào)的大小限制在64K內(nèi)

? 發(fā)送不管對(duì)方是否準(zhǔn)備好,接收方收到也不確認(rèn),故是不可靠的

? 可以廣播發(fā)送

? 發(fā)送數(shù)據(jù)結(jié)束時(shí)無需釋放資源,開銷小,速度快

1.6、三次握手與四次揮手

1、三次握手

Java網(wǎng)絡(luò)編程的示例分析

第一步,請(qǐng)求端(客戶端)發(fā)送一個(gè)包含SYN標(biāo)志的TCP報(bào)文,SYN即同步(Synchronize),同步報(bào)文會(huì)指明客戶端使用的端口以及TCP連接的初始序號(hào);

第二步,服務(wù)器在收到客戶端的SYN報(bào)文后,將返回一個(gè)SYN+ACK的報(bào)文,表示客戶端的請(qǐng)求被接受,同時(shí)TCP序號(hào)被加一,ACK即確認(rèn)(Acknowledgment)。

第三步,客戶端也返回一個(gè)確認(rèn)報(bào)文ACK給服務(wù)器端,同樣TCP序列號(hào)被加一,到此一個(gè)TCP連接完成。

2、四次揮手

Java網(wǎng)絡(luò)編程的示例分析

由于TCP連接是全雙工的,因此每個(gè)方向都必須單獨(dú)進(jìn)行關(guān)閉。這原則是當(dāng)一方完成它的數(shù)據(jù)發(fā)送任務(wù)后就能發(fā)送一個(gè)FIN來終止這個(gè)方向的連接。收到一個(gè) FIN只意味著這一方向上沒有數(shù)據(jù)流動(dòng),一個(gè)TCP連接在收到一個(gè)FIN后仍能發(fā)送數(shù)據(jù)。首先進(jìn)行關(guān)閉的一方將執(zhí)行主動(dòng)關(guān)閉,而另一方執(zhí)行被動(dòng)關(guān)閉。

1.TCP客戶端發(fā)送一個(gè)FIN,用來關(guān)閉客戶到服務(wù)器的數(shù)據(jù)傳送。

2.服務(wù)器收到這個(gè)FIN,它發(fā)回一個(gè)ACK,確認(rèn)序號(hào)為收到的序號(hào)加1。和SYN一樣,一個(gè)FIN將占用一個(gè)序號(hào)。

3.服務(wù)器關(guān)閉客戶端的連接,發(fā)送一個(gè)FIN給客戶端。

4.客戶端發(fā)回ACK報(bào)文確認(rèn),并將確認(rèn)序號(hào)設(shè)置為收到序號(hào)加1。

二、TCP網(wǎng)絡(luò)編程

2.1、Socket介紹

1、利用套接字(Socket)開發(fā)網(wǎng)絡(luò)應(yīng)用程序早已被廣泛的采用,以至于成為事實(shí) 上的標(biāo)準(zhǔn)。

2、網(wǎng)絡(luò)上具有唯一標(biāo)識(shí)的IP地址和端口號(hào)組合在一起才能構(gòu)成唯一能識(shí)別的標(biāo)識(shí)符套接字。

3、通信的兩端都要有Socket,是兩臺(tái)機(jī)器間通信的端點(diǎn)。

4、網(wǎng)絡(luò)通信其實(shí)就是Socket間的通信。

5、Socket允許程序把網(wǎng)絡(luò)連接當(dāng)成一個(gè)流,數(shù)據(jù)在兩個(gè)Socket間通過IO傳輸。

6、一般主動(dòng)發(fā)起通信的應(yīng)用程序?qū)倏蛻舳?,等待通信?qǐng)求的為服務(wù)端。

7、Socket分類:

  • 流套接字(stream socket):使用TCP提供可依賴的字節(jié)流服務(wù)

  • 數(shù)據(jù)報(bào)套接字(datagram socket):使用UDP提供“盡力而為”的數(shù)據(jù)報(bào)服務(wù)

2.2、基于Socket的TCP編程

1、Java語(yǔ)言的基于套接字編程分為服務(wù)端編程和客戶端編程,其通信模型如圖所示

Java網(wǎng)絡(luò)編程的示例分析

2、客戶端Socket的工作過程包含以下四個(gè)基本的步驟:

  • 創(chuàng)建 Socket:根據(jù)指定服務(wù)端的 IP 地址或端口號(hào)構(gòu)造 Socket 類對(duì)象。若服務(wù)器端響應(yīng),則建立客戶端到服務(wù)端的通信路線。若連接失敗,則會(huì)出現(xiàn)異常。

  • 打開連接到 Socket 的輸入/出流: 使用 getInputStream()方法獲得輸入流,使用 getOutputStream()方法獲得輸出流,進(jìn)行數(shù)據(jù)傳輸

  • 按照一定的協(xié)議對(duì) Socket 進(jìn)行讀/寫操作:通過輸入流讀取服務(wù)器放入線路的信息(但不能讀取自己放入路線的信息),通過輸出流將信息寫入線程

  • 關(guān)閉 Socket:斷開客戶端到服務(wù)器的連接,釋放線路

3、客戶端創(chuàng)建Socket對(duì)象:

客戶端程序可以使用Socket類創(chuàng)建對(duì)象,創(chuàng)建的同時(shí)會(huì)自動(dòng)向服務(wù)器方發(fā)起連 接。Socket的構(gòu)造器是:

// 構(gòu)造器一
Socket(String host,int port)throws UnknownHostException,IOException
/* 向服務(wù)器(域名是 host。端口號(hào)為port)發(fā)起TCP連接,若成功,則創(chuàng)建Socket對(duì)象,否則拋出異常。*/

// 構(gòu)造器二
Socket(InetAddress address,int port)throws IOException
/* 根據(jù)InetAddress對(duì)象所表示的 IP地址以及端口號(hào)port發(fā)起連接。*/

客戶端建立socketAtClient對(duì)象的過程就是向服務(wù)器發(fā)出套接字連接請(qǐng),簡(jiǎn)要步驟如下

Socket s = new Socket("192.168.40.165",9999); // 1、創(chuàng)建Socket對(duì)象,指明服務(wù)端的IP和端口號(hào)
OutputStream out = s.getOutputStream(); // 2、獲取一個(gè)輸出流,用于輸出數(shù)據(jù)
out.write("hello".getBytes()); // 3、寫出數(shù)據(jù)
s.close(); // 4、回收資源

4、服務(wù)器(服務(wù)端)程序的工作過程包含以下四個(gè)基本的步驟:

  • 調(diào)用 ServerSocket(int port) :創(chuàng)建一個(gè)服務(wù)器端套接字,并綁定到指定端口 上。用于監(jiān)聽客戶端的請(qǐng)求。

  • 調(diào)用 accept():監(jiān)聽連接請(qǐng)求,如果客戶端請(qǐng)求連接,則接受連接,返回通信 套接字對(duì)象。

  • 調(diào)用 該Socket類對(duì)象的 getOutputStream() 和 getInputStream ():獲取輸出 流和輸入流,開始網(wǎng)絡(luò)數(shù)據(jù)的發(fā)送和接收。

  • 關(guān)閉ServerSocket和Socket對(duì)象:客戶端訪問結(jié)束,關(guān)閉通信套接字。

5、服務(wù)器建立 ServerSocket 對(duì)象

ServerSocket 對(duì)象負(fù)責(zé)等待客戶端請(qǐng)求建立套接字連接,類似郵局某個(gè)窗口 中的業(yè)務(wù)員。也就是說,服務(wù)器必須事先建立一個(gè)等待客戶請(qǐng)求建立套接字 連接的ServerSocket對(duì)象。

所謂“接收”客戶的套接字請(qǐng)求,就是accept()方法會(huì)返回一個(gè) Socket 對(duì)象

ServerSocket ss = new ServerSocket(9999); // 1、創(chuàng)建服務(wù)端的ServerSocket,指明自己的端口號(hào)
Socket s = ss.accept (); // 2、調(diào)用accept()監(jiān)聽來自客戶端的連接
InputStream in = s.getInputStream(); // 3、獲取輸入流,讀取輸入流的數(shù)據(jù)
byte[] buf = new byte[1024]; 
int num = in.read(buf); 
String str = new String(buf,0,num); 
System.out.println(s.getInetAddress().toString()+":"+str); 
s.close(); // 4、回收資源
ss.close();

2.3、TCP編程簡(jiǎn)單C/S通信示例

/**
 * @description: TCP編程,模擬基于C/S架構(gòu)客戶端與服務(wù)端間的通信
 */
public class SocketTest {
    /* 客戶端 */
    @Test
    public void client(){
        OutputStream output = null;
        Socket socket = null;
        try {
            InetAddress localHost = InetAddress.getByName("127.0.0.1");
            socket = new Socket(localHost,8848);
            output = socket.getOutputStream();
            output.write("hello I'm the client".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(output != null){
                try {
                    output.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    /* 服務(wù)端 */
    @Test
    public void server() {
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream input = null;
        ByteArrayOutputStream out = null;
        try {
            serverSocket = new ServerSocket(8848);
            socket = serverSocket.accept();
            System.out.println("client IP: " + socket.getInetAddress());
            input = socket.getInputStream();
            /*
            一般不建議這樣書寫,數(shù)據(jù)傳輸時(shí)可能會(huì)出現(xiàn)亂碼??!
            byte[] buffer = new byte[1024];
            int len;
            while((len = input.read(buffer)) != -1){
                String data = new String(buffer,0,len);
                System.out.println(data);
            }*/

            out = new ByteArrayOutputStream();
            byte[] buffer = new byte[10];
            int len;
            while((len = input.read(buffer)) != -1){
                out.write(buffer,0,len);
            }
            System.out.println(out.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(input != null){
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(serverSocket != null){
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

2.4、TCP編程實(shí)現(xiàn)C/S文件傳輸

實(shí)現(xiàn)功能:客戶端發(fā)送文件給服務(wù)端,服務(wù)端將文件保存在本地。

/**
 * @description: TCP編程,客戶端發(fā)送文件給服務(wù)端,服務(wù)端將文件保存在本地。
 */
public class TCPSocketTest {
	/* 客戶端 */
    @Test
    public void client() {
        Socket socket = null;
        OutputStream writer = null;
        BufferedInputStream bis = null;
        try {
            socket = new Socket(InetAddress.getByName("127.0.0.1"),8089);
            writer = socket.getOutputStream();

            bis = new BufferedInputStream(new FileInputStream(new File("me.jpg")));
            byte[] buffer = new byte[1024];
            int len;
            while((len = bis.read(buffer)) != -1){
                writer.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(writer != null){
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(bis != null){
                try {
                    bis.close();
                    System.out.println("發(fā)送成功!");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
	/* 服務(wù)端 */
    @Test
    public void server() throws IOException { // 這里異常應(yīng)該使用try-catch-finally
        ServerSocket socket = new ServerSocket(8089);
        System.out.println("正在等待客戶端連接...");
        Socket clientSocket = socket.accept();

        System.out.println("客戶端已連接IP地址為:"+clientSocket.getInetAddress().getHostName());
        InputStream is = clientSocket.getInputStream();
        BufferedOutputStream reader = new BufferedOutputStream(new FileOutputStream(new File("new_me.jpg")));

        byte[] buffer = new byte[1024];
        int len;
        while((len = is.read(buffer)) != -1){
            reader.write(buffer,0,len);
        }
        System.out.println("接收成功");

        socket.close();
        clientSocket.close();
        is.close();
        reader.close();
    }
}

2.5、TCP編程實(shí)現(xiàn)C/S信息反饋

實(shí)現(xiàn)功能:從客戶端發(fā)送文件給服務(wù)端,服務(wù)端保存到本地。并返回“發(fā)送成功”給 客戶端。并關(guān)閉相應(yīng)的連接。

/**
 * @description: TCP編程,從客戶端發(fā)送文件給服務(wù)端,服務(wù)端保存到本地。并返回“發(fā)送成功”給 客戶端。并關(guān)閉相應(yīng)的連接。
 */
public class TCPSocketTest2 {
	/* 客戶端 */
    @Test
    public void client() {
        Socket socket = null;
        OutputStream writer = null;
        BufferedInputStream bis = null;
        try {
            socket = new Socket(InetAddress.getByName("127.0.0.1"),8089);
            writer = socket.getOutputStream();

            bis = new BufferedInputStream(new FileInputStream(new File("me.jpg")));
            byte[] buffer = new byte[1024];
            int len;
            while((len = bis.read(buffer)) != -1){
                writer.write(buffer,0,len);
            }
            // 關(guān)閉數(shù)據(jù)的輸出
            socket.shutdownOutput();

            // 接收服務(wù)端反饋的信息并輸出到控制臺(tái)
            InputStream is = socket.getInputStream();
            ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
            byte[] buf = new byte[10];
            int l;
            while((l = is.read(buf)) != -1){
                byteArray.write(buf,0,l);
            }
            System.out.println(byteArray.toString());
            is.close();
            byteArray.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(writer != null){
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(bis != null){
                try {
                    bis.close();
                    System.out.println("發(fā)送成功!");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
	/* 服務(wù)端 */
    @Test
    public void server() throws IOException { // 這里異常應(yīng)該使用try-catch-finally
        ServerSocket socket = new ServerSocket(8089);
        System.out.println("正在等待客戶端連接...");
        Socket clientSocket = socket.accept();

        System.out.println("客戶端已連接IP地址為:"+clientSocket.getInetAddress().getHostName());
        InputStream is = clientSocket.getInputStream();
        BufferedOutputStream reader = new BufferedOutputStream(new FileOutputStream(new File("new_me.jpg")));

        byte[] buffer = new byte[1024];
        int len;
        while((len = is.read(buffer)) != -1){
            reader.write(buffer,0,len);
        }
        System.out.println("接收成功");

        // 服務(wù)端給客戶端反饋信息
        OutputStream os = clientSocket.getOutputStream();
        os.write("你好客戶端,照片已經(jīng)收到".getBytes());

        socket.close();
        clientSocket.close();
        is.close();
        reader.close();
        os.close();
    }
}

三、UDP網(wǎng)絡(luò)編程

3.1、UDP網(wǎng)絡(luò)通信

1、類 DatagramSocket 和 DatagramPacket 實(shí)現(xiàn)了基于 UDP 協(xié)議網(wǎng)絡(luò)程序。

2、UDP數(shù)據(jù)報(bào)通過數(shù)據(jù)報(bào)套接字 DatagramSocket 發(fā)送和接收,系統(tǒng)不保證 UDP數(shù)據(jù)報(bào)一定能夠安全送到目的地,也不能確定什么時(shí)候可以抵達(dá)。

3、DatagramPacket 對(duì)象封裝了UDP數(shù)據(jù)報(bào),在數(shù)據(jù)報(bào)中包含了發(fā)送端的IP地址和端口號(hào)以及接收端的IP地址和端口號(hào)。

4、UDP協(xié)議中每個(gè)數(shù)據(jù)報(bào)都給出了完整的地址信息,因此無須建立發(fā)送方和接收方的連接。如同發(fā)快遞包裹一樣。

3.2、UDP網(wǎng)絡(luò)通信流程

1、DatagramSocket與DatagramPacket

2、建立發(fā)送端,接收端

3、建立數(shù)據(jù)包

4、調(diào)用Socket的發(fā)送、接收方法

5、關(guān)閉Socket

注意:發(fā)送端與接收端是兩個(gè)獨(dú)立的運(yùn)行程序

3.3、UDP網(wǎng)絡(luò)通信代碼實(shí)現(xiàn)

/*
UDP網(wǎng)絡(luò)編程:
    ? 將數(shù)據(jù)、源、目的封裝成數(shù)據(jù)包,不需要建立連接
    ? 每個(gè)數(shù)據(jù)報(bào)的大小限制在64K內(nèi)
    ? 發(fā)送不管對(duì)方是否準(zhǔn)備好,接收方收到也不確認(rèn),故是不可靠的
    ? 可以廣播發(fā)送
    ? 發(fā)送數(shù)據(jù)結(jié)束時(shí)無需釋放資源,開銷小,速度快
 */
public class UDPSocketTest {
    @Test // 發(fā)送端
    public void send() throws IOException {
        DatagramSocket socket = new DatagramSocket();

        byte[] data = "hello world".getBytes();
        DatagramPacket packet = new DatagramPacket(data,0,data.length, InetAddress.getLocalHost(),8080);

        socket.send(packet);

        socket.close();
    }

    @Test // 接收端
    public void receiver() throws IOException {
        DatagramSocket socket = new DatagramSocket(8080);

        byte[] buffer = new byte[100];
        DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);

        socket.receive(packet);

        System.out.println(new String(packet.getData(),0,packet.getLength()));

        socket.close();
    }
}

四、URL網(wǎng)絡(luò)編程

4.1、URL介紹

1、URL(Uniform Resource Locator):統(tǒng)一資源定位符,它表示 Internet 上某一 資源的地址。

2、它是一種具體的URI,即URL可以用來標(biāo)識(shí)一個(gè)資源,而且還指明了如何locate 這個(gè)資源。

3、通過 URL 我們可以訪問 Internet 上的各種網(wǎng)絡(luò)資源,比如最常見的 www,ftp 站點(diǎn)。瀏覽器通過解析給定的 URL 可以在網(wǎng)絡(luò)上查找相應(yīng)的文件或其他資源。

4、URL的基本結(jié)構(gòu)由5部分組成: <傳輸協(xié)議>://<主機(jī)名>:<端口號(hào)>/<文件名>#片段名?參數(shù)列表

  • 例如: http://192.168.1.100:8080/helloworld/index.jsp#a?username=shkstart&password=123

  • #片段名:即錨點(diǎn),例如看小說,直接定位到章節(jié)

  • 參數(shù)列表格式:參數(shù)名=參數(shù)值&參數(shù)名=參數(shù)值…

5、Restful風(fēng)格

一種軟件架構(gòu)風(fēng)格、設(shè)計(jì)風(fēng)格,而不是標(biāo)準(zhǔn),只是提供了一組設(shè)計(jì)原則和約束條件。它主要用于客戶端和服務(wù)器交互類的軟件?;谶@個(gè)風(fēng)格設(shè)計(jì)的軟件可以更簡(jiǎn)潔,更有層次,更易于實(shí)現(xiàn)緩存等機(jī)制。restful風(fēng)格在實(shí)際開發(fā)中使用較多,對(duì)于URL地址有全新的使用方式,可以自行了解restful風(fēng)格的使用!

4.2、URL類與類的構(gòu)造器

1、為了表示URL,java.net 中實(shí)現(xiàn)了類 URL。我們可以通過下面的構(gòu)造器來初 始化一個(gè) URL 對(duì)象:

  • public URL (String spec):通過一個(gè)表示URL地址的字符串可以構(gòu)造一個(gè)URL對(duì)象。例如:URL url = new URL ("https://www.baidu.com/");

  • public URL(URL context, String spec):通過基 URL 和相對(duì) URL 構(gòu)造一個(gè) URL 對(duì)象。 例如:URL downloadUrl = new URL(url, “download.html");

  • public URL(String protocol, String host, String file); 例如:new URL(“http”, “www.atguigu.com”, “download. html");

  • public URL(String protocol, String host, int port, String file); 例如: URL gamelan = new URL(“http”, “www.atguigu.com”, 80, “download.html");

2、URL類的構(gòu)造器都聲明拋出非運(yùn)行時(shí)異常,必須要對(duì)這一異常進(jìn)行處理,通 常是用 try-catch 語(yǔ)句進(jìn)行捕。

4.3、URL類常用方法

一個(gè)URL對(duì)象生成后,其屬性是不能被改變的,但可以通過它給定的方法來獲取這些屬性:

  • public String getProtocol( ) 獲取該URL的協(xié)議名

  • public String getHost( ) 獲取該URL的主機(jī)名

  • public String getPort( ) 獲取該URL的端口號(hào)

  • public String getPath( ) 獲取該URL的文件路徑

  • public String getFile( ) 獲取該URL的文件名

  • public String getQuery( ) 獲取該URL的查詢名

以上是“Java網(wǎng)絡(luò)編程的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI