国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

網(wǎng)絡(luò)編程(JavaEE初階系列10)

這篇具有很好參考價(jià)值的文章主要介紹了網(wǎng)絡(luò)編程(JavaEE初階系列10)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

目錄

前言:

1.網(wǎng)絡(luò)編程的基礎(chǔ)

1.1為什么需要網(wǎng)絡(luò)編程

1.2什么是網(wǎng)絡(luò)編程

1.3網(wǎng)絡(luò)編程中的基本概念

1.3.1發(fā)送端和接收端

1.3.2請(qǐng)求和響應(yīng)

1.3.3客戶端和服務(wù)端

2.Socket套接字

2.1概念

2.2分類(lèi)

3.UDP數(shù)據(jù)報(bào)套接字編程

3.1DataGramSocket?API

3.2DatagramPacket?API

3.3基于UDP的回顯服務(wù)器(echo?server)

3.4簡(jiǎn)單的翻譯服務(wù)器

4.TCP流套接字

4.1ServerSocket?API

4.2Socket?API

4.3基于TCP的回顯程序

5.再談協(xié)議

結(jié)束語(yǔ):


前言:

在上一節(jié)中小編主要是與大家分享了一些有關(guān)于網(wǎng)絡(luò)的基礎(chǔ)知識(shí),但是里面的細(xì)節(jié)和基礎(chǔ)的編程還沒(méi)有給大家來(lái)交代,這節(jié)中小編就給大家倆交代一下有關(guān)于網(wǎng)絡(luò)基礎(chǔ)編程方面的一些基礎(chǔ)的編程吧,大家趕快跟上小編的步伐一起來(lái)往下看吧。如果還沒(méi)有看小編網(wǎng)絡(luò)基礎(chǔ)知識(shí)的部分的同學(xué)建議先去看看這篇博文吧:?http://t.csdn.cn/aj9ov

1.網(wǎng)絡(luò)編程的基礎(chǔ)

1.1為什么需要網(wǎng)絡(luò)編程

用戶在瀏覽器中,打開(kāi)在線視頻網(wǎng)站,比如抖音短視頻其實(shí)質(zhì)是通過(guò)網(wǎng)絡(luò),獲取到網(wǎng)絡(luò)上的一個(gè)視頻資源,與本地打開(kāi)視頻文件類(lèi)似,只是視頻文件這個(gè)資源的來(lái)源是網(wǎng)絡(luò),相比本地資源來(lái)說(shuō),網(wǎng)絡(luò)提供了更為豐富的網(wǎng)絡(luò)資源,所謂的網(wǎng)絡(luò)資源,其實(shí)就是在網(wǎng)絡(luò)中可以獲取的各種數(shù)據(jù)資源,而所有的網(wǎng)絡(luò)資源,都是通過(guò)網(wǎng)絡(luò)編程來(lái)進(jìn)行數(shù)據(jù)傳輸?shù)摹?/strong>

1.2什么是網(wǎng)絡(luò)編程

網(wǎng)絡(luò)編程:指網(wǎng)絡(luò)上的主機(jī),通過(guò)不同的進(jìn)程,以編程的方式實(shí)現(xiàn)網(wǎng)絡(luò)通信(網(wǎng)絡(luò)數(shù)據(jù)傳輸)。

當(dāng)然,我們只要滿足進(jìn)程不同就行,所以即便是同一個(gè)主機(jī),只要是不同進(jìn)程,基于網(wǎng)絡(luò)來(lái)傳輸數(shù)據(jù),也屬于網(wǎng)絡(luò)編程。

1.3網(wǎng)絡(luò)編程中的基本概念

1.3.1發(fā)送端和接收端

在一次網(wǎng)絡(luò)數(shù)據(jù)傳輸時(shí):

  • 發(fā)送端:數(shù)據(jù)的發(fā)送方進(jìn)程,稱(chēng)為發(fā)送端。發(fā)送端主機(jī)即網(wǎng)絡(luò)通信中的源主機(jī)。
  • 接收端:數(shù)據(jù)的接收方進(jìn)程,稱(chēng)為接收端。接收端主機(jī)即網(wǎng)絡(luò)通信中的目的主機(jī)。
  • 收發(fā)端:發(fā)送端和接收端兩端,也簡(jiǎn)稱(chēng)Wie收發(fā)端。

注意:發(fā)送端和接收端只是相對(duì)的概念,只是一次網(wǎng)絡(luò)數(shù)據(jù)傳輸產(chǎn)生數(shù)據(jù)流向后的概念。

1.3.2請(qǐng)求和響應(yīng)

一般來(lái)說(shuō),獲取一個(gè)網(wǎng)絡(luò)資源,涉及到兩次網(wǎng)絡(luò)數(shù)據(jù)傳輸。

  • 第一次:請(qǐng)求數(shù)據(jù)的發(fā)送。
  • 第二次:響應(yīng)數(shù)據(jù)的發(fā)送。

就像是在餐廳點(diǎn)飯一樣,先發(fā)起請(qǐng)求:點(diǎn)一份蛋炒飯。餐廳在給一個(gè)響應(yīng):提供一份蛋炒飯。

1.3.3客戶端和服務(wù)端

  • 服務(wù)端:在常見(jiàn)的網(wǎng)絡(luò)數(shù)據(jù)傳輸?shù)膱?chǎng)景下,把提供服務(wù)的這一方進(jìn)程,稱(chēng)為服務(wù)端,可以提供對(duì)外服務(wù)。
  • 客戶端:獲取服務(wù)的一方進(jìn)程,稱(chēng)為客戶端。

對(duì)于服務(wù)來(lái)說(shuō),一般是提供:

  • 客戶端獲取服務(wù)資源。
  • 客戶端保存資源在服務(wù)端。

就像是我們?cè)阢y行辦事:

  • 銀行提供存款服務(wù):用戶(客戶端)保存現(xiàn)金(資源)在銀行(服務(wù)端)。
  • 銀行提供取款服務(wù):用戶(客戶端)獲取服務(wù)端資源(銀行替用戶保管現(xiàn)金)。

2.Socket套接字

2.1概念

Socket套接字是操作系統(tǒng)提供給應(yīng)用程序的一組用于網(wǎng)絡(luò)編程的API。他是基于TCP/IP協(xié)議的通信的的基本操作單元。

注意:操作系統(tǒng)原生的Socket?API是C語(yǔ)言的但是這里我們學(xué)習(xí)的是Java封裝之后的版本。

2.2分類(lèi)

Socket套接字主要針對(duì)傳輸層協(xié)議劃分為如下三類(lèi):

  • 數(shù)據(jù)報(bào)套接字:使用傳輸層UDP協(xié)議。

UDP,即User?Datagram?Protocol(用戶數(shù)據(jù)報(bào)協(xié)議),傳輸層協(xié)議。它的特點(diǎn)是:無(wú)連接、不可靠傳輸、面向數(shù)據(jù)報(bào)、全雙工。

  • 流套接字:使用傳輸層TCP協(xié)議。

TCP,即Transmission?Control?Protocol(傳輸控制協(xié)議),傳輸層協(xié)議。它的特點(diǎn)是:有連接、可靠傳輸、面向字節(jié)流、全雙工。

對(duì)于字節(jié)流來(lái)說(shuō),可以簡(jiǎn)單理解為傳輸?shù)臄?shù)據(jù)是基于IO流的,流式數(shù)據(jù)的特征就是在IO流沒(méi)喲關(guān)閉的情況下,是無(wú)邊界的數(shù)據(jù),可以多次發(fā)送,也可以分開(kāi)多次接收。

  • 原始套接字:

原始套接字用于自定義傳出層協(xié)議,用于讀寫(xiě)內(nèi)核沒(méi)有處理的IP協(xié)議數(shù)據(jù),這里我們對(duì)此不做過(guò)多討論,我們重點(diǎn)是理解和應(yīng)用前兩個(gè)。

TCP特點(diǎn)vsUDP特點(diǎn):

UDP特點(diǎn) TCP特點(diǎn)
無(wú)連接:使用UDP通信雙方不需要刻意保存對(duì)方的相關(guān)信息 有連接:使用TCP通信雙方則需要刻意保存對(duì)方的相關(guān)信息
不可靠傳輸:消息發(fā)了就發(fā)了不關(guān)注結(jié)果 可靠傳輸:不是說(shuō)發(fā)送之后對(duì)方就可以100%能夠達(dá)到對(duì)方,這要求就太高了,只是說(shuō)盡可能的傳輸過(guò)去。
面向數(shù)據(jù)報(bào):以UDP數(shù)據(jù)報(bào)為基本單位。 面向字節(jié)流:以字節(jié)為傳輸?shù)幕締挝?,讀寫(xiě)方式非常靈活
全雙工:一條路徑,雙向通信 全雙工:一條路徑,全向通信。

解釋?zhuān)喝p工vs半雙工。

  • 全雙工:是一條路徑,全向通信,你可以理解為,一個(gè)雙向通道的馬路。
  • 半雙工:是一條路徑,只能由一側(cè)向另一側(cè)通信,你可理解為單向通道的馬路。

針對(duì)上述的TCP協(xié)議和UDP協(xié)議也給我們提供了兩組不同的API。下面我們來(lái)一步一步的了解一下。

3.UDP數(shù)據(jù)報(bào)套接字編程

3.1DataGramSocket?API

DataGramSocket?是UDP?Socket,用于發(fā)送和接收UDP數(shù)據(jù)報(bào),所謂Socket,是一個(gè)特殊的文件,是網(wǎng)卡這個(gè)硬件設(shè)備的抽象表示,你也可以理解為是一個(gè)遙控器,想要進(jìn)行網(wǎng)絡(luò)通信就需要有socket文件這樣的對(duì)象,借助這個(gè)socket文件對(duì)象,才能夠間接的操作網(wǎng)卡。

  • 往這個(gè)socket對(duì)象里寫(xiě)數(shù)據(jù),相當(dāng)于通過(guò)網(wǎng)卡發(fā)送消息。
  • 從這個(gè)socket對(duì)象中讀數(shù)據(jù),相當(dāng)于通過(guò)網(wǎng)卡接收消息。

DatagramSocket的構(gòu)造方法,可以綁定一個(gè)端口號(hào)(服務(wù)器),也可以不顯示指定客戶端。

方法簽名 方法說(shuō)明
DatagramSocket() 創(chuàng)建一個(gè)UDP數(shù)據(jù)報(bào)套接字的Socket,綁定到本機(jī)任意一個(gè)隨機(jī)端口(一般用于客戶端)
DatagramSocket(int port) 創(chuàng)建一個(gè)UDP數(shù)據(jù)報(bào)套接字的Socket,綁定到本機(jī)指定的端口(一般用于服務(wù)端)
  • 服務(wù)器這邊的socket往往要關(guān)聯(lián)一個(gè)具體的端口號(hào)。
  • 客戶端這邊則不需要手動(dòng)指定,系統(tǒng)會(huì)自動(dòng)分配一個(gè)閑置的端口號(hào)。

舉個(gè)例子:

比如現(xiàn)在我開(kāi)了一家餐廳,要發(fā)傳單,那么在傳單上面我這邊可定是要標(biāo)清楚我的餐廳的具體位置在哪,窗口號(hào)是多少,都得事先分配好,此時(shí)我開(kāi)的這家餐館就相當(dāng)于是服務(wù)器,確定的地址和窗口號(hào)就是服務(wù)器事先分配好的端口號(hào)。那么如果此時(shí)客人看到我發(fā)的傳單就來(lái)到我的餐館吃飯了,那么它點(diǎn)完餐之后,就會(huì)隨便找一個(gè)空著的位置坐下,等飯。此時(shí)客人就相當(dāng)于是客戶端,隨便找的位置就是系統(tǒng)給隨機(jī)分配的一個(gè)空閑的端口號(hào)。

?DatagramSocket方法

方法簽名 方法說(shuō)明
void?receive(DatagramPacket p) 從此套接字接收數(shù)據(jù)報(bào)(如果沒(méi)有接收到數(shù)據(jù)報(bào),該方法會(huì)阻塞等待)
void send(DatagramPacket p) 從此套接字發(fā)送數(shù)據(jù)報(bào)(不會(huì)阻塞等待,直接發(fā)送)
void close() 關(guān)閉數(shù)據(jù)報(bào)套接字(釋放資源)

注意:

  • DatagramPacket表示一個(gè)UDP數(shù)據(jù)報(bào)。
  • 在close的時(shí)候,到底啥時(shí)候調(diào)用close,一定是要socket/文件,確定一定以及肯定不再使用,此時(shí)才能調(diào)用close。

3.2DatagramPacket?API

DatagramPacket是UDPSocket發(fā)送和接收的數(shù)據(jù)報(bào)。

DatagramPacket構(gòu)造方法

方法簽名 方法說(shuō)明
DatagramPacket(byte[] buf, int length) 構(gòu)造一個(gè)DatagramPacket以用來(lái)接收數(shù)據(jù)報(bào),接收的數(shù)據(jù)保存在字節(jié)數(shù)組(第一個(gè)參數(shù)buf)中,接收指定長(zhǎng)度(第二個(gè)參數(shù)length)
DatagramPacket(byte[] buf, int offset, int lenght, SocketAddress address) 構(gòu)造一個(gè)DatagramPacket以用來(lái)發(fā)送數(shù)據(jù)報(bào),發(fā)送的數(shù)據(jù)為字節(jié)數(shù)組(第一個(gè)參數(shù)buf)中,從0到指定長(zhǎng)度(第二個(gè)參數(shù)length),address指定目的的主機(jī)的IP和端口號(hào)。

?DatagramPacket方法

方法簽名 方法說(shuō)明
InetAddress?getAddress() 從接收的數(shù)據(jù)報(bào)中,獲取發(fā)送端主機(jī)IP地址,或從發(fā)送的數(shù)據(jù)報(bào)中,獲取接收端主機(jī)IP地址。
int?getPort() 從接收的數(shù)據(jù)報(bào)中,獲取發(fā)送端主機(jī)的端口號(hào),或從發(fā)送的數(shù)據(jù)報(bào)中,獲取接收端主機(jī)端口號(hào)。
byte[] getData() 獲取數(shù)據(jù)報(bào)中的數(shù)據(jù)。

3.3基于UDP的回顯服務(wù)器(echo?server)

介紹了DatagramSocket?和?DatagramPacket?API之后,我們基于UDP?socket寫(xiě)一個(gè)簡(jiǎn)單的客戶端服務(wù)器程序。?也就是讓客戶端發(fā)一個(gè)請(qǐng)求,在服務(wù)器上返回一個(gè)一模一樣的響應(yīng)。

首先來(lái)明確一點(diǎn),一個(gè)服務(wù)器主要做的三個(gè)核心的工作:

  1. 讀取請(qǐng)求并解析。
  2. 根據(jù)請(qǐng)求并計(jì)算響應(yīng)。(代碼中省略了)
  3. 把響應(yīng)返回給客戶端。

服務(wù)端代碼:

package network;
//服務(wù)端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UdpEchoServer{
    //需要先定義一個(gè)Socket對(duì)象
    //通過(guò)網(wǎng)絡(luò)通信,必須要使用socket對(duì)象
    private DatagramSocket socket = null;
    //綁定一個(gè)端口,不一定能成功
    //如果某個(gè)端口已經(jīng)被別的進(jìn)程占用了,此時(shí)這里的綁定操作就會(huì)出錯(cuò)。
    //同一個(gè)主機(jī)上,一個(gè)端口,同一個(gè)時(shí)刻,只能被一個(gè)進(jìn)程綁定

    public UdpEchoServer(int port) throws SocketException {
        //構(gòu)造socket的同時(shí),指定要關(guān)聯(lián)/綁定的端口。
        socket = new DatagramSocket(port);
    }

    //啟動(dòng)服務(wù)器的主邏輯
    public void start() throws IOException {
        System.out.println("服務(wù)器啟動(dòng)成功!");
        while (true) {
            //每次循環(huán),要做三件事
            //1.讀取請(qǐng)求并解析
            //  構(gòu)造空飯盒
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
            // 食堂大媽給飯盒里打菜(飯從網(wǎng)卡上來(lái))
            //這里的receive會(huì)阻塞等待,等到客戶端那邊發(fā)送數(shù)據(jù)過(guò)來(lái)
            socket.receive(requestPacket);
            //為了方便處理這個(gè)請(qǐng)求,需要把數(shù)據(jù)報(bào)轉(zhuǎn)換成String
            String request = new String(requestPacket.getData(), 0, requestPacket.getLength());
            //2.根據(jù)請(qǐng)求計(jì)算響應(yīng)(此處省略這個(gè)步驟)
            String response = process(request);
            //3.把響應(yīng)結(jié)果寫(xiě)回到客戶端
            // 根據(jù)response 字符串,構(gòu)造一個(gè)DatagramPacket
            // 和請(qǐng)求packet 不同,此處構(gòu)造響應(yīng)的時(shí)候,需要指定這個(gè)包要發(fā)給誰(shuí),這里調(diào)用requestPacket.getSocketAddress()就可以得知了
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), response.getBytes().length,
                    requestPacket.getSocketAddress());
            socket.send(responsePacket);
            //打印一下請(qǐng)求的地址和請(qǐng)求的端口號(hào),以及請(qǐng)求的內(nèi)容和響應(yīng)的內(nèi)容
            System.out.printf("[%s:%d] req: %s, resp: %s\n", requestPacket.getAddress().toString(),
                    requestPacket.getPort(), request, response);
        }
    }


    //這個(gè)方法是希望我們根據(jù)請(qǐng)求計(jì)算響應(yīng)。
    //由于咱們寫(xiě)的是個(gè)回顯程序,請(qǐng)求是啥,響應(yīng)就是啥
    //如果后續(xù)寫(xiě)一個(gè)別的服務(wù)器,不再回顯了,而是具有具體的業(yè)務(wù)了,就可以修改process方法
    //根據(jù)需求來(lái)重新構(gòu)造響應(yīng)
    //之所以單獨(dú)列成一個(gè)方法,就是想讓大家知道這個(gè)是一個(gè)關(guān)鍵的環(huán)節(jié)。
    private String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        UdpEchoServer udpEchoServer = new UdpEchoServer(9090);
        udpEchoServer.start();
    }
}

客戶端代碼:

package network;
//客戶端
import java.io.IOException;
import java.net.*;
import java.util.Scanner;

public class UdpEchoClient {
    private DatagramSocket socket = null;
    private String serverIP;//服務(wù)器的地址
    private int serverPort;//服務(wù)器的端口

    //客戶端啟動(dòng),需要知道服務(wù)器在哪里
    public UdpEchoClient(String serverIP, int serverPort) throws SocketException {
        //對(duì)于客戶端來(lái)說(shuō),不需要顯示關(guān)聯(lián)空閑的端口
        //不代表沒(méi)有端口,而是系統(tǒng)自動(dòng)分配了一個(gè)空閑的端口
        socket = new DatagramSocket();
        this.serverIP = serverIP;
        this.serverPort = serverPort;
    }

    public void start() throws IOException {
        //通過(guò)這個(gè)客戶端可以多次和服務(wù)器進(jìn)行交互
        Scanner scanner = new Scanner(System.in);
        while (true) {
            //1.先從控制臺(tái),讀取一個(gè)字符串過(guò)來(lái)
            //先打印一個(gè)提示符,提示用戶要輸入內(nèi)容
            System.out.println("->");
            String request = scanner.next();
            //2.把字符串構(gòu)造成UDP packet,并進(jìn)行發(fā)送
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(), request.getBytes().length,
                    InetAddress.getByName(serverIP), serverPort);
            socket.send(requestPacket);
            //3.客戶端嘗試讀取服務(wù)器返回的響應(yīng)
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096], 4096);
            socket.receive(responsePacket);
            //4.把響應(yīng)數(shù)據(jù)轉(zhuǎn)換成String顯示出來(lái)
            String response = new String(responsePacket.getData(), 0, responsePacket.getLength());
            System.out.printf("req: %s, resp: %s\n", request, response);
        }
    }

    public static void main(String[] args) throws IOException {
        UdpEchoClient udpEchoClient = new UdpEchoClient("127.0.0.1", 9090);
        udpEchoClient.start();
    }
}


啟動(dòng)服務(wù)器和客戶端結(jié)果展示:
網(wǎng)絡(luò)編程(JavaEE初階系列10),JavaEE初階,網(wǎng)絡(luò)

網(wǎng)絡(luò)編程(JavaEE初階系列10),JavaEE初階,網(wǎng)絡(luò)?

注意:這里一定是先啟動(dòng)服務(wù)器,再啟動(dòng)客戶端?。?!

執(zhí)行流程如下所示:

網(wǎng)絡(luò)編程(JavaEE初階系列10),JavaEE初階,網(wǎng)絡(luò)?

網(wǎng)絡(luò)編程(JavaEE初階系列10),JavaEE初階,網(wǎng)絡(luò)

網(wǎng)絡(luò)編程(JavaEE初階系列10),JavaEE初階,網(wǎng)絡(luò)

注意:在上述過(guò)程中我們是客戶端和服務(wù)器在同一個(gè)主機(jī)上,使用的是127這個(gè)IP,不同主機(jī)則就寫(xiě)實(shí)際的IP即可。

在上述通信過(guò)程中,站在客戶端發(fā)送數(shù)據(jù)的角度:

  • 源IP是:127.0.0.1
  • 源端口是:64982,他是系統(tǒng)自動(dòng)分配的空閑端口。
  • 目的IP是:127.0.0.1
  • 目的端口是:9090

在上述過(guò)程中就有同學(xué)好奇了不是說(shuō)是要使用close來(lái)關(guān)閉資源的嗎?為什么在代碼中好像沒(méi)有看到釋放資源這一步,其實(shí)對(duì)于UdpEchoServer來(lái)說(shuō),這個(gè)socket對(duì)象是出了循環(huán)就不用了,但是循環(huán)結(jié)束,意味著start結(jié)束,意味著main方法結(jié)束,同時(shí)意味著進(jìn)程結(jié)束,那么此時(shí)進(jìn)程都結(jié)束了所以的資源也就自然釋放了,所以就不必顯示釋放資源了。

3.4簡(jiǎn)單的翻譯服務(wù)器

在上述中我們編寫(xiě)的是一個(gè)回顯服務(wù)器,它是沒(méi)有實(shí)際意義的。那么如何寫(xiě)一個(gè)提供實(shí)在價(jià)值的服務(wù)器呢?當(dāng)響應(yīng)和請(qǐng)求不一樣了,響應(yīng)是根據(jù)不同的請(qǐng)求計(jì)算得到的,這里就需要我們對(duì)上述過(guò)程沒(méi)有寫(xiě)的process方法來(lái)進(jìn)行編寫(xiě),那么下來(lái)我們就具體來(lái)實(shí)現(xiàn)一下。我們就來(lái)編寫(xiě)一個(gè)簡(jiǎn)單的英文單詞翻譯服務(wù)器,請(qǐng)求是一個(gè)英文單詞,響應(yīng)是這個(gè)單詞的中文翻譯。

服務(wù)端代碼展示:

package network;
//詞典查詢服務(wù)端
import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;

//使用繼承,是為了復(fù)用之前的代碼
public class UdpDicServer extends UdpEchoServer{
    private Map<String, String> dict = new HashMap<>();
    public UdpDicServer(int port) throws SocketException {
        super(port);
        dict.put("dog", "小狗");
        dict.put("cat", "小貓");
        dict.put("tiger", "老虎");
        //注意:這里可以無(wú)限添加很多個(gè)數(shù)據(jù)
    }
    @Override
    public String process(String request) {
        return dict.getOrDefault(request,"該單詞沒(méi)有查到!");
    }

    public static void main(String[] args) throws IOException {
        UdpDicServer udpDicServer = new UdpDicServer(9090);
        udpDicServer.start();
    }
}


客戶端代碼展示:

package network;
//客戶端
import java.io.IOException;
import java.net.*;
import java.util.Scanner;

public class UdpEchoClient {
    private DatagramSocket socket = null;
    private String serverIP;//服務(wù)器的地址
    private int serverPort;//服務(wù)器的端口

    //客戶端啟動(dòng),需要知道服務(wù)器在哪里
    public UdpEchoClient(String serverIP, int serverPort) throws SocketException {
        //對(duì)于客戶端來(lái)說(shuō),不需要顯示關(guān)聯(lián)空閑的端口
        //不代表沒(méi)有端口,而是系統(tǒng)自動(dòng)分配了一個(gè)空閑的端口
        socket = new DatagramSocket();
        this.serverIP = serverIP;
        this.serverPort = serverPort;
    }

    public void start() throws IOException {
        //通過(guò)這個(gè)客戶端可以多次和服務(wù)器進(jìn)行交互
        Scanner scanner = new Scanner(System.in);
        while (true) {
            //1.先從控制臺(tái),讀取一個(gè)字符串過(guò)來(lái)
            //先打印一個(gè)提示符,提示用戶要輸入內(nèi)容
            System.out.println("->");
            String request = scanner.next();
            //2.把字符串構(gòu)造成UDP packet,并進(jìn)行發(fā)送
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(), request.getBytes().length,
                    InetAddress.getByName(serverIP), serverPort);
            socket.send(requestPacket);
            //3.客戶端嘗試讀取服務(wù)器返回的響應(yīng)
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096], 4096);
            socket.receive(responsePacket);
            //4.把響應(yīng)數(shù)據(jù)轉(zhuǎn)換成String顯示出來(lái)
            String response = new String(responsePacket.getData(), 0, responsePacket.getLength());
            System.out.printf("req: %s, resp: %s\n", request, response);
        }
    }

    public static void main(String[] args) throws IOException {
        UdpEchoClient udpEchoClient = new UdpEchoClient("127.0.0.1", 9090);
        udpEchoClient.start();
    }
}


運(yùn)行結(jié)果展示:
網(wǎng)絡(luò)編程(JavaEE初階系列10),JavaEE初階,網(wǎng)絡(luò)

網(wǎng)絡(luò)編程(JavaEE初階系列10),JavaEE初階,網(wǎng)絡(luò)?

注意:在上述編寫(xiě)服務(wù)端代碼時(shí)我們是直接使用了繼承,重寫(xiě)了父類(lèi)的process方法。這樣就減少了我們的工作。

4.TCP流套接字

在TCP中有兩個(gè)核心的類(lèi):

  • ServerSocket:是給服務(wù)器使用的。
  • Socket:即會(huì)給客戶端使用,又會(huì)給服務(wù)器端使用。

下面我們就來(lái)分別看看ServerSocket和Socket的具體使用方法。

4.1ServerSocket?API

他是創(chuàng)建服務(wù)端使用的API。

SocketSocket構(gòu)造方法:

方法簽名 方法說(shuō)明
ServerSocket(int port) 創(chuàng)建一個(gè)服務(wù)流套接字Socket,并綁定到指定端口

SocketSocket方法:?

方法簽名 方法說(shuō)明
Socket?accept() 開(kāi)始監(jiān)聽(tīng)指定端口(創(chuàng)建時(shí)綁定的端口),有客戶端連接后,返回一個(gè)服務(wù)端Socket對(duì)象,并基于該Socket建立與客戶端的連接,否則阻塞等待。
void?close() 關(guān)閉此套接字

這里的accept意思就是接收,在客戶端主動(dòng)向服務(wù)器發(fā)起連接請(qǐng)求,服務(wù)器就得同意一下,但是實(shí)際上的這個(gè)accept又和我們上述給大家解釋的意思不太一樣,這里的accept只是在應(yīng)用層面的接收,實(shí)際的TCP連接的接受是在該內(nèi)核里已經(jīng)完成了。這個(gè)后面在將TCP的時(shí)候會(huì)給大家交代的。?

4.2Socket?API

Socket是客戶端Socket,或服務(wù)端中接收到客戶端建立連接(accept方法)的請(qǐng)求后,返回的服務(wù)端Socket。

不管是客戶端還是服務(wù)端Socket,都是雙方建立連接以后,保存的對(duì)端的信息,及用來(lái)與對(duì)方收發(fā)數(shù)據(jù)的。

Socket的構(gòu)造方法:

方法簽名 方法說(shuō)明
Socket(String?host,?int?port) 創(chuàng)建一個(gè)客戶端流套接字Socket,并與對(duì)應(yīng)IP的主機(jī)上,對(duì)應(yīng)端口的進(jìn)程建立連接。

這里的host和port指的是服務(wù)器的IP和端口,TCP是有連接的,在客戶端new?Socket對(duì)象的時(shí)候就會(huì)嘗試和指定IP端口的目標(biāo)建立連接了。?

Socket的方法:

方法簽名 方法說(shuō)明
InetAddress?getInetAddress() 返回套接字所連接的地址
InputStream?getInputStream() 返回此套接字的輸入流
OutPutStream?getOutStream() 返回此套接字的輸出流

?InputStream?getInputStream()和OutPutStream?getOutStream()是字節(jié)流,就可以通過(guò)上述字節(jié)流對(duì)象,進(jìn)行數(shù)據(jù)傳輸了。

  • 從?InputStream?這里讀數(shù)據(jù),就相當(dāng)于是從網(wǎng)卡接收。
  • 往?OutPutStream?這里寫(xiě)數(shù)據(jù),就相當(dāng)于從網(wǎng)卡發(fā)送。

注意:

這個(gè)Socket和DatagramSocket定位類(lèi)似,都是構(gòu)造的時(shí)候指定一個(gè)具體的端口,讓服務(wù)器綁定該端口,但是ServerSocket一定要綁定具體的端口。

4.3基于TCP的回顯程序

服務(wù)端代碼展示?:

package network;
//服務(wù)端
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TcpEchoServer {
    //serverSocket只有一個(gè),clientSocket會(huì)給每一個(gè)客戶都分配一個(gè)
    private ServerSocket severSocket = null;

    public TcpEchoServer(int port) throws IOException {
        severSocket = new ServerSocket(port);
    }

    public void start() throws IOException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        System.out.println("服務(wù)器啟動(dòng)成功!");
        while (true) {
            Socket clientSocket = severSocket.accept();
            //如果直接調(diào)用,該方法會(huì)影響這個(gè)循環(huán)的二次執(zhí)行,導(dǎo)致accept不及時(shí)了。
            //創(chuàng)建新的線程,用新線程來(lái)調(diào)用processConnection
            //每次來(lái)一個(gè)新的客戶端都搞一個(gè)新的線程即可!
//            Thread t = new Thread(() -> {
//                try {
//                    processConnection(clientSocket);
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            });
//            t.start();

            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        processConnection(clientSocket);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }

    //讀取這個(gè)方法來(lái)處理一個(gè)連接
    //讀取請(qǐng)求
    //根據(jù)請(qǐng)求計(jì)算響應(yīng)
    //把響應(yīng)返回給客戶端
    private void processConnection(Socket clientSocket) throws IOException {
        System.out.printf("[%s:%d] 客戶端上線!\n", clientSocket.getInetAddress().toString(), clientSocket.getPort());
        //使用try()這種寫(xiě)法,()中允許寫(xiě)多個(gè)流對(duì)象,使用;來(lái)分隔
        try(InputStream inputStream = clientSocket.getInputStream();
            OutputStream outputStream = clientSocket.getOutputStream()) {
            //沒(méi)有這個(gè)scanner和printWriter,完全可以,但是代價(jià)就是得一個(gè)字節(jié)一個(gè)字節(jié)扣,找到哪個(gè)是請(qǐng)求結(jié)束的標(biāo)記\n
            //不是不能做,而是代替代碼比較麻煩
            //為了簡(jiǎn)單,把字節(jié)流包裝成了更方便的字符流
            Scanner scanner = new Scanner(inputStream);
            PrintWriter printWriter = new PrintWriter(outputStream);
            while (true) {
                //1.讀取請(qǐng)求
                //采用hasNext判定接下來(lái)還有沒(méi)有數(shù)據(jù)了,如果對(duì)端關(guān)閉了連接(客戶端關(guān)閉連接),此時(shí)hasNext就會(huì)返回false,循環(huán)就結(jié)束
                if (!scanner.hasNext()) {
                    //讀取的流到了結(jié)尾了(對(duì)端關(guān)閉了)
                    System.out.printf("[%s:%d] 客戶端下線了!\n", clientSocket.getInetAddress().toString(), clientSocket.getPort());
                    break;
                }
                //直接使用scanner讀取一段字符串
                //next會(huì)一直往后讀,讀到空白符結(jié)束(空格、換行、制表符、翻頁(yè)符...都算空白符)
                //nextLine只是讀到換行符結(jié)束,所以這里沒(méi)有使用它
                String request = scanner.next();
                //2.根據(jù)請(qǐng)求計(jì)算響應(yīng)
                String response = process(request);
                //3.把響應(yīng)寫(xiě)回給客戶端,不要忘記了,響應(yīng)也是要帶上換行的
                //返回響應(yīng)的時(shí)候要把換行符加回來(lái),方便客戶端那邊來(lái)區(qū)分從哪里到哪里是一個(gè)完整的響應(yīng)。
                printWriter.println(response);
                //flush當(dāng)數(shù)據(jù)不夠大的時(shí)候直接進(jìn)行強(qiáng)制刷新,將緩沖區(qū)中的數(shù)據(jù)發(fā)給客戶端
                printWriter.flush();
                System.out.printf("[%s:%d] req: %s; resp: %s\n", clientSocket.getInetAddress().toString(), clientSocket.getPort(), request, response);
            }
        }catch (IOException e) {
            e.printStackTrace();
        }finally {
            //clientSocket只是一個(gè)連接提供服務(wù)的,這個(gè)還是要進(jìn)行關(guān)閉的
            clientSocket.close();
        }
    }

    private String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        TcpEchoServer tcpEchoServer = new TcpEchoServer(9090);
        tcpEchoServer.start();
    }
}


客戶端代碼展示:

package network;
//客戶端
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class TcpEchoClient {
    private Socket socket = null;

    public TcpEchoClient(String serverIP, int port) throws IOException {
        //這個(gè)操作相當(dāng)于讓客戶端和服務(wù)器建立TCP連接
        //這里的連接連上了,服務(wù)器的accept就會(huì)返回
        socket = new Socket(serverIP, port);
    }

    public void start() throws IOException {
        Scanner scanner = new Scanner(System.in);
        try (InputStream inputStream = socket.getInputStream();
             OutputStream outputStream = socket.getOutputStream()) {
            PrintWriter printWriter = new PrintWriter(outputStream);
            Scanner scannerFromSocket = new Scanner(inputStream);
            while (true) {
                //1.從鍵盤(pán)上讀取用戶輸入的內(nèi)容
                System.out.println("->");
                String request = scanner.next();
                //2.把讀取到的內(nèi)容構(gòu)造成請(qǐng)求,發(fā)送給服務(wù)器
                //注意,這里的發(fā)送,是帶有換行的。
                printWriter.println(request);
                printWriter.flush();
                //3.從服務(wù)器讀取響應(yīng)的內(nèi)容
                String response = scannerFromSocket.next();
                //4.把響應(yīng)結(jié)果顯示到控制臺(tái)上
                System.out.printf("req: %s; resp: %s\n", request, response);
            }
        }
    }

    public static void main(String[] args) throws IOException {
        TcpEchoClient client = new TcpEchoClient("127.0.0.1", 9090);
        client.start();
    }
}

結(jié)果展示:

網(wǎng)絡(luò)編程(JavaEE初階系列10),JavaEE初階,網(wǎng)絡(luò)

網(wǎng)絡(luò)編程(JavaEE初階系列10),JavaEE初階,網(wǎng)絡(luò)

執(zhí)行流程如下所示:

網(wǎng)絡(luò)編程(JavaEE初階系列10),JavaEE初階,網(wǎng)絡(luò)

網(wǎng)絡(luò)編程(JavaEE初階系列10),JavaEE初階,網(wǎng)絡(luò)?

那么這里我們只是啟動(dòng)了一個(gè)客戶端,在實(shí)際中不可能是一個(gè)服務(wù)器只給一個(gè)客戶端進(jìn)行服務(wù),那么如何啟動(dòng)多個(gè)客戶端呢?這里在idea中是默認(rèn)下只能啟動(dòng)一個(gè)的,那么這里我們需要打開(kāi)idea配置一下。配置過(guò)程如下所示:

網(wǎng)絡(luò)編程(JavaEE初階系列10),JavaEE初階,網(wǎng)絡(luò)?

網(wǎng)絡(luò)編程(JavaEE初階系列10),JavaEE初階,網(wǎng)絡(luò)?

此時(shí)當(dāng)我們?cè)俅吸c(diǎn)擊上述的三角形就可以再次啟動(dòng)另一個(gè)客戶端了。

網(wǎng)絡(luò)編程(JavaEE初階系列10),JavaEE初階,網(wǎng)絡(luò)?

網(wǎng)絡(luò)編程(JavaEE初階系列10),JavaEE初階,網(wǎng)絡(luò)?

5.再談協(xié)議

回顧并理解我們?yōu)槭残枰獏f(xié)議

以上我們實(shí)現(xiàn)的UDP和TCP數(shù)據(jù)傳輸,除了UDP和TCP之外,程序還存在應(yīng)用層定義協(xié)議,可以想想分別都是什么樣的協(xié)議格式。

對(duì)于客戶端及服務(wù)端應(yīng)用程序來(lái)說(shuō),請(qǐng)求和響應(yīng),需要約定一致的數(shù)據(jù)格式:

  • 客戶端發(fā)送請(qǐng)求和服務(wù)端解析請(qǐng)求和要使用相同的數(shù)據(jù)格式。
  • 服務(wù)端返回響應(yīng)和客戶端解析響應(yīng)也要使用相同的數(shù)據(jù)格式。
  • 請(qǐng)求格式和響應(yīng)格式可以相同,也可以不同。
  • 約定相同的數(shù)據(jù)格式,主要目的是為了讓接收端在解析的時(shí)候明確如何解析數(shù)據(jù)中的各個(gè)字段。
  • 可以使用知名協(xié)議(廣泛使用的協(xié)議格式),如果想自己約定數(shù)據(jù)格式,就屬于自定義協(xié)議。

結(jié)束語(yǔ):

這節(jié)中小編主要是和大家分享了網(wǎng)絡(luò)編程中的兩個(gè)重要的編程UDP和TCP,后期小編還會(huì)繼續(xù)出有關(guān)于網(wǎng)絡(luò)方面的知識(shí)的,希望這節(jié)對(duì)大家了解網(wǎng)絡(luò)有一定幫助,想要學(xué)習(xí)的同學(xué)記得關(guān)注小編和小編一起學(xué)習(xí)吧!如果文章中有任何錯(cuò)誤也歡迎各位大佬及時(shí)為小編指點(diǎn)迷津(在此小編先謝過(guò)各位大佬啦?。?span toymoban-style="hidden">文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-646514.html

到了這里,關(guān)于網(wǎng)絡(luò)編程(JavaEE初階系列10)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • [JAVAee]網(wǎng)絡(luò)編程-套接字Socket

    [JAVAee]網(wǎng)絡(luò)編程-套接字Socket

    目錄 基本概念 發(fā)送端與接收端 請(qǐng)求與響應(yīng) ?編輯客戶端與服務(wù)器 Socket套接字? 分類(lèi) 數(shù)據(jù)報(bào)套接字 流套接字傳輸模型?? UDP數(shù)據(jù)報(bào)套接字編程 DatagramSocket API DatagramPacket API InetSocketAddress API 示例一: 示例二: TCP流數(shù)據(jù)報(bào)套接字編程 ServerSocket API Socket API 示例一: ? 網(wǎng)絡(luò)編程指的

    2024年02月13日
    瀏覽(127)
  • 初識(shí)網(wǎng)絡(luò)(JavaEE初階系列9)

    初識(shí)網(wǎng)絡(luò)(JavaEE初階系列9)

    目錄 前言: 1.網(wǎng)絡(luò)的發(fā)展史 1.1獨(dú)立模式 1.2網(wǎng)絡(luò)互聯(lián) 1.3局域網(wǎng)LAN 1.4廣域網(wǎng)WAN 2.網(wǎng)絡(luò)通信基礎(chǔ) 2.1IP地址 2.2端口號(hào) 3.認(rèn)識(shí)協(xié)議 3.1協(xié)議分層 3.2分層的作用 3.3TCP/IP五層(或四層)模型 3.4OSI七層模型 3.5網(wǎng)絡(luò)設(shè)備所在分層 4.封裝和分用 結(jié)束語(yǔ): 網(wǎng)絡(luò)的主要發(fā)展大體可以分為這四個(gè)階

    2024年02月14日
    瀏覽(20)
  • 網(wǎng)絡(luò)原理(JavaEE初階系列11)

    網(wǎng)絡(luò)原理(JavaEE初階系列11)

    目錄 前言: 1.網(wǎng)絡(luò)原理的理解 2.應(yīng)用層 2.1自定義協(xié)議的約定 2.1.1確定要傳輸?shù)男畔?2.1.2確定數(shù)據(jù)的格式 3.傳輸層 3.1UDP 3.1.1UDP報(bào)文格式 3.2TCP 3.2.1確認(rèn)應(yīng)答 3.2.2超時(shí)重傳 3.2.3連接管理 3.2.3.1三次握手 3.2.3.2四次揮手 3.2.4滑動(dòng)窗口 3.2.5流量控制 3.2.6擁塞控制 3.2.7延時(shí)應(yīng)答 3.2.8捎帶

    2024年02月13日
    瀏覽(44)
  • JavaEE-網(wǎng)絡(luò)編程套接字(UDP/TCP)

    JavaEE-網(wǎng)絡(luò)編程套接字(UDP/TCP)

    下面寫(xiě)一個(gè)簡(jiǎn)單的UDP客戶端服務(wù)器流程 思路: 對(duì)于服務(wù)器端:讀取請(qǐng)求,并解析– 根據(jù)解析出的請(qǐng)求,做出響應(yīng)(這里是一個(gè)回顯,)–把響應(yīng)寫(xiě)回客戶端 對(duì)于客戶端:從控制臺(tái)讀取用戶輸入的內(nèi)容–從控制臺(tái)讀取用戶輸入的內(nèi)容–從控制臺(tái)讀取用戶輸入的內(nèi)容–將其顯示在

    2024年02月07日
    瀏覽(91)
  • 【JavaEE】網(wǎng)絡(luò)編程之TCP套接字、UDP套接字

    【JavaEE】網(wǎng)絡(luò)編程之TCP套接字、UDP套接字

    目錄 1.網(wǎng)絡(luò)編程的基本概念 1.1為什么需要網(wǎng)絡(luò)編程? 1.2服務(wù)端與用戶端 1.3網(wǎng)絡(luò)編程五元組? 1.4套接字的概念 2.UDP套接字編程 2.1UDP套接字的特點(diǎn) ?2.2UDP套接字API 2.2.1DatagramSocket類(lèi) 2.2.2DatagramPacket類(lèi)? 2.2.3基于UDP的回顯程序 2.2.4基于UDP的單詞查詢? 3.TCP套接字編程 3.1TCP套接字的特

    2023年04月20日
    瀏覽(120)
  • 【JavaEE初階系列】——網(wǎng)絡(luò)初識(shí)—TCP/IP五層網(wǎng)絡(luò)模型

    【JavaEE初階系列】——網(wǎng)絡(luò)初識(shí)—TCP/IP五層網(wǎng)絡(luò)模型

    目錄 ??網(wǎng)絡(luò)的發(fā)展史 ??局域網(wǎng)LAN? ??廣域網(wǎng)WAN ??網(wǎng)絡(luò)通信基礎(chǔ) ??IP地址 ??端口號(hào) ??協(xié)議類(lèi)型? ??五元組 ??協(xié)議分層? ??什么是協(xié)議分層 ??協(xié)議分層的好處 ??OSI七層網(wǎng)絡(luò)模型 ??TCP/IP五層網(wǎng)絡(luò)模型 ??物理層 ??數(shù)據(jù)鏈路層 ??網(wǎng)絡(luò)層 ??傳輸層? ??應(yīng)用層 ??網(wǎng)絡(luò)

    2024年04月15日
    瀏覽(17)
  • 【Java EE初階十五】網(wǎng)絡(luò)編程TCP/IP協(xié)議(二)

    【Java EE初階十五】網(wǎng)絡(luò)編程TCP/IP協(xié)議(二)

    ? ? ? ? tcp的socket api和U大片的socket api差異很大,但是和前面所講的文件操作很密切的聯(lián)系 ? ? ? ? 下面主要講解兩個(gè)關(guān)鍵的類(lèi): ? ? ? ? 1、ServerSocket:給服務(wù)器使用的類(lèi),使用這個(gè)類(lèi)來(lái)綁定端口號(hào) ? ? ? ? 2、Socket:即會(huì)給服務(wù)器使用,又會(huì)給客戶端使用; ????????

    2024年02月20日
    瀏覽(34)
  • 【網(wǎng)絡(luò)編程系列】網(wǎng)絡(luò)編程實(shí)戰(zhàn)

    【網(wǎng)絡(luò)編程系列】網(wǎng)絡(luò)編程實(shí)戰(zhàn)

    ??????歡迎來(lái)到我的博客,很高興能夠在這里和您見(jiàn)面!希望您在這里可以感受到一份輕松愉快的氛圍,不僅可以獲得有趣的內(nèi)容和知識(shí),也可以暢所欲言、分享您的想法和見(jiàn)解。 推薦:kuan 的首頁(yè),持續(xù)學(xué)習(xí),不斷總結(jié),共同進(jìn)步,活到老學(xué)到老 導(dǎo)航 檀越劍指大廠系列:全面總

    2024年02月10日
    瀏覽(24)
  • JavaEE & UDP簡(jiǎn)易翻譯服務(wù)器 & 網(wǎng)絡(luò)編程示例2 & CTP回顯服務(wù)器,回顯客戶端

    JavaEE & UDP簡(jiǎn)易翻譯服務(wù)器 & 網(wǎng)絡(luò)編程示例2 & CTP回顯服務(wù)器,回顯客戶端

    禁止白嫖 T T 點(diǎn)點(diǎn)贊唄 這個(gè)翻譯器主要是在上一章的回顯服務(wù)器和回顯客戶端上進(jìn)行修改 修改了計(jì)算響應(yīng)的過(guò)程, 即process方法 1.1 重寫(xiě)方法 重寫(xiě)方法是Java中的一種重要手段 指在一個(gè)類(lèi)的子類(lèi)里,對(duì)父類(lèi)的一個(gè)方法進(jìn)行重新定義! 而父類(lèi)的權(quán)限級(jí)別要大于等于子類(lèi)~ 【除了

    2023年04月16日
    瀏覽(47)
  • JavaEE & UDP簡(jiǎn)易翻譯服務(wù)器 & 網(wǎng)絡(luò)編程示例2 & TCP回顯服務(wù)器,回顯客戶端

    JavaEE & UDP簡(jiǎn)易翻譯服務(wù)器 & 網(wǎng)絡(luò)編程示例2 & TCP回顯服務(wù)器,回顯客戶端

    禁止白嫖 T T 點(diǎn)點(diǎn)贊唄 這個(gè)翻譯器主要是在上一章的回顯服務(wù)器和回顯客戶端上進(jìn)行修改 修改了計(jì)算響應(yīng)的過(guò)程, 即process方法 1.1 重寫(xiě)方法 重寫(xiě)方法是Java中的一種重要手段 指在一個(gè)類(lèi)的子類(lèi)里,對(duì)父類(lèi)的一個(gè)方法進(jìn)行重新定義! 而父類(lèi)的權(quán)限級(jí)別要大于等于子類(lèi)~ 【除了

    2023年04月16日
    瀏覽(20)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包