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

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

這篇具有很好參考價值的文章主要介紹了【JaveEE】網(wǎng)絡(luò)編程之TCP套接字、UDP套接字。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

目錄

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類

2.2.2DatagramPacket類?

2.2.3基于UDP的回顯程序

2.2.4基于UDP的單詞查詢?

3.TCP套接字編程

3.1TCP套接字的特點(diǎn)

3.2TCP中的長短連接

3.3TCP套接字的API

3.3.2Socket類

3.3.3基于TCP的回顯程序

3.3.4對TCP回顯程序的優(yōu)化


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

網(wǎng)絡(luò)編程,指網(wǎng)絡(luò)上的主機(jī),通過不同的進(jìn)程,以編程的方式實(shí)現(xiàn)網(wǎng)絡(luò)通信(或稱為網(wǎng)絡(luò)數(shù)據(jù)傳輸)。對于我們程序員來說,我們比較關(guān)注應(yīng)用層到傳輸層這一操作,我們代碼的書寫是發(fā)生在應(yīng)用層的,然后通過傳輸層提供的API(UDP和TCP)進(jìn)行包裝,再由應(yīng)用層發(fā)送給傳輸層。

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

?這個最為直接的說話莫過于人民需要他了,哪里有需求,哪里就提供響應(yīng)嘛。

相比于本地的資源,網(wǎng)絡(luò)上有這更為豐富的資源,而網(wǎng)絡(luò)上的資源又需要通過網(wǎng)絡(luò)編程來上傳,因此就相互督促相互促進(jìn)了對方的發(fā)展。

1.2服務(wù)端與用戶端

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

簡單的說,客戶端會接收到客戶的請求,再將客戶的請求發(fā)送給服務(wù)端;服務(wù)端將請求按照業(yè)務(wù)邏輯完成響應(yīng),再將響應(yīng)返回給客戶端,客戶端再將響應(yīng)按照操作顯示或者運(yùn)作。

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

1.3網(wǎng)絡(luò)編程五元組?

  1. 源IP:就是發(fā)送方IP.
  2. 源端口:發(fā)送方端口號, 服務(wù)器需要手動指定, 客戶端讓系統(tǒng)隨機(jī)分配即可.
  3. 目的IP: 接收方IP, 包含在拿到的數(shù)據(jù)報中, 服務(wù)器響應(yīng)時的目的IP就在客戶端發(fā)來的數(shù)據(jù)報中, 客戶端發(fā)送請求時的目的IP就是服務(wù)器的IP.
  4. 目的端口: 接收方端口號包含在數(shù)據(jù)報中, 服務(wù)器響應(yīng)時的目的端口就在客戶端發(fā)來的數(shù)據(jù)報中, 客戶端發(fā)送請求時的目的端口就是服務(wù)器的端口號.
  5. 協(xié)議類型:如UDP/TCP.

1.4套接字的概念

Socket(套接字)可以看成是兩個網(wǎng)絡(luò)應(yīng)用程序進(jìn)行通信時,各自通信連接中的端點(diǎn),這是一個邏輯上的概念。Socket是由IP地址和端口結(jié)合的,提供向應(yīng)用層進(jìn)程傳送數(shù)據(jù)包的機(jī)制?

套接字的表示方法:Socket=Ip接口:端口號

2.UDP套接字編程

2.1UDP套接字的特點(diǎn)

特點(diǎn)如下:

  • 無連接:不關(guān)心和誰對話,也不會刻意留意對方。
  • 不可靠的:不關(guān)心他收沒收到。
  • 面向數(shù)據(jù)報:以一個UDP數(shù)據(jù)報為單位。
  • 全雙工通信:一條路徑,但是路徑兩方都可以對話。(雙向?qū)υ挘?/li>

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

?2.2UDP套接字API

UDP套接字的API中主要包括兩個類?:1.DatagramSocket 2.DatagramPacket。

下面就開始介紹這兩個類

2.2.1DatagramSocket類

?DatagramSocket類就是實(shí)例一個UDP版本的套接字也是就數(shù)據(jù)包套接字。Socket對象對應(yīng)到系統(tǒng)中的一個特殊文件(socket文件),socket文件不是數(shù)據(jù)存儲區(qū)域的一部分,而是對應(yīng)到網(wǎng)卡這個硬件設(shè)備,為什么對應(yīng)到網(wǎng)卡呢?因?yàn)榫W(wǎng)卡是一個硬件,對于代碼而已,不好直接操作,因此將它抽象成了一個文件進(jìn)行間接操作。

DatagramSocket類構(gòu)造方法:

方法簽名 方法說明
DatagramSocket() 創(chuàng)建一個UDP數(shù)據(jù)報套接字的Socket,綁定到本機(jī)任意一個隨機(jī)端口
(一般用于客戶端)
DatagramSocket(int
port)
創(chuàng)建一個UDP數(shù)據(jù)報套接字的Socket,綁定到本機(jī)指定的端口(一般用
于服務(wù)端)

我們一般使用第二個方法,我們知道端口號是在一個計算機(jī)中尋找一個程序的“門牌號”。實(shí)際操作時,如果端口號是系統(tǒng)隨機(jī)綁定的話,我們就不知道我們服務(wù)端服務(wù)于哪一個客戶端了,就沒有辦法找到客戶端的家了。

DatagramSocket類方法:

方法簽名 方法說明
void
receive(DatagramPacket p)
從此套接字接收數(shù)據(jù)報(如果沒有接收到數(shù)據(jù)報,該方法會阻
塞等待)
void send(DatagramPacket
p)
從此套接字發(fā)送數(shù)據(jù)報包(不會阻塞等待,直接發(fā)送)
void close() 關(guān)閉此數(shù)據(jù)報套接字

第一個receive方法它的參數(shù)需要準(zhǔn)備一個空的DatagramPacket對象(對象需要給予存儲空間),它把DatagramPacket實(shí)例對象再裝入到準(zhǔn)備好的空的DatagramPacket對象中去 ,為什么這樣做呢?就像我們平常接收東西時,我們需要一個載體來承接這個物件,舉個例子吧,當(dāng)我們盛飯時,我們不能夠直接用手去捧著飯,而是需要一個空飯盒去接打的飯。

第二個send方法他是DatagramPacket實(shí)例對象載入到接收緩沖區(qū)。

第三個close方法,因?yàn)镈atagramSocket類屬于文件資源,當(dāng)我們不用的時候,我們需要將它給手動關(guān)閉了。

2.2.2DatagramPacket類?

DatagramPacket是UDP Socket發(fā)送和接收的數(shù)據(jù)報。?

DatagramPacket類構(gòu)造方法

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

這兩個構(gòu)造方法都會使用到,第一個構(gòu)造方法:他就是我們上方說的空的DatagramPacket對象也就是我們舉例說的“空飯盒”,第二個構(gòu)造方法是在我們將接收到的請求進(jìn)行封裝時使用的,假設(shè)我們接收到的請求是字符串,我們就要將它轉(zhuǎn)化成byte數(shù)組,再算出長度,并且需要指定它要發(fā)送到那里去也就是SockerAddress類的一個子類InetSocketAddress類它里面包含目的ip和目的端口號。

DatagramPacket類方法:

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

2.2.3基于UDP的回顯程序

UDP服務(wù)端:

服務(wù)器設(shè)計邏輯:?

  1. ?創(chuàng)建DatagramSocket對象,指定服務(wù)器端口號。
  2. 服務(wù)器啟動了,我們需要一個DatagramPacket實(shí)例運(yùn)來當(dāng)作載體,當(dāng)沒有請求時,在這里就會發(fā)生阻塞,有請求時,就寫入到DatagramPacket實(shí)例好的載體中。
  3. 接收到數(shù)據(jù)后,我們將數(shù)據(jù)拆分成我們需要的格式,因?yàn)槲覀兪且粋€回顯,故我們只需將它改成字符串就行了,再調(diào)用process方法,在這里完成業(yè)務(wù)需求,我們這里只需返回字符串就像了。
  4. 將處理好的請求,再封裝一下,封裝成DatagramPacket實(shí)例對象,將這個響應(yīng)發(fā)生使用send方法發(fā)送給客戶端即可。
package UdpNetWork;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

//服務(wù)器端
public class UdpEchoServer {

    private DatagramSocket socket=null;
    public UdpEchoServer(int port) throws SocketException {
        this.socket=new DatagramSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服務(wù)器啟動");
        while (true) {
            //requestPacket是一個載體,receive方法會將發(fā)送過來的數(shù)據(jù)放入到這個載體中
            DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4096);
            socket.receive(requestPacket);
            //將發(fā)來的數(shù)據(jù)拆解
            String request=new String(requestPacket.getData(),0, requestPacket.getLength());
            //做出響應(yīng)
            String response=process(request);
            //將做出的響應(yīng)包裝起來,發(fā)給客戶端
            DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),response.getBytes().length,
                    requestPacket.getSocketAddress());
            socket.send(responsePacket);
            //打印日志
            System.out.printf("[%s:%d] req:%s,resp:%s\n",requestPacket.getAddress().toString(),requestPacket.getPort(),
                    request,response);
        }
    }

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

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

?UDP客戶端:

?客戶端設(shè)計邏輯:

  1. ?客戶端需要知道服務(wù)端的位置,因此我們需要服務(wù)端的ip地址和端口號,故成員變量包含Ipserver、serverPort以及一個DatagramSocket對象(可以理解為整合ip和端口號)。
  2. 開始運(yùn)行客戶端,通過Scaner接收客戶的請求。
  3. 拿到請求后,我們需要將它封裝成DatagramPacket對象,發(fā)送給服務(wù)端。
  4. 發(fā)送完就等待服務(wù)端返回響應(yīng)。
  5. 等到拿到響應(yīng)之后,我們就可以對響應(yīng)做出操作了,因?yàn)槲覀冞@里是回顯,我們只需將返回過來的字符串打印出來即可。
package UdpNetWork;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;

//客戶端
public class UdpEchoClient {
    private DatagramSocket socket=null;
    private int serverPort;
    private String IpServer;

    public UdpEchoClient(int port, String ipServer) throws SocketException {
        socket=new DatagramSocket();
        this.serverPort=port;
        this.IpServer=ipServer;
    }
    public void start() throws IOException {
        Scanner sc=new Scanner(System.in);
        while (true) {
            System.out.print("輸入字符->");
            String request=sc.next();
            //將輸入的指令打包
            DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length,
                    InetAddress.getByName(IpServer),serverPort);
            //發(fā)送給服務(wù)器端
            socket.send(requestPacket);
            DatagramPacket responsePacket=new DatagramPacket(new byte[4096], 4096);
            //接收服務(wù)器端的響應(yīng)結(jié)果
            socket.receive(responsePacket);
            //打印服務(wù)端的響應(yīng)
            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(9090,"127.0.0.1");
        udpEchoClient.start();
    }
}

2.2.4基于UDP的單詞查詢?

對于這個服務(wù)端,我們不需要再寫一邊start方法了,我們可以直接讓它繼承udpEchoServer類,并且,我們在上方服務(wù)端,我們將對請求處理的部分拿出來當(dāng)作了一個單獨(dú)的函數(shù),我們在將上方的函數(shù)進(jìn)行重寫就行了,還有就是,我們需要一個存儲單詞,并且它還方便查詢的東西,我們就想到一個數(shù)據(jù)結(jié)構(gòu)就是Map,剛好可以適合這個系統(tǒng)。

package UdpNetWork;

import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;

public class UdpDictServer extends UdpEchoServer{
    //字典表
    private Map<String, String> dict = new HashMap<>();

    public UdpDictServer(int port) throws SocketException {
        super(port);

        dict.put("dog", "小狗");
        dict.put("cat", "小貓");
        dict.put("fuck", "臥槽");
        // ........... 可以無限的添加很多很多數(shù)據(jù). 有道詞典和咱們相比, 就是人家的這個表更大!!
    }

    @Override
    public String process(String request) {
        return dict.getOrDefault(request, "該單詞沒有查到!");
    }

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

3.TCP套接字編程

3.1TCP套接字的特點(diǎn)

特點(diǎn)如下:

  1. 有鏈接:雙方通信,都需要可以留意對方信息。
  2. 可靠傳輸:盡可能的將數(shù)據(jù)傳輸給對方,但也不能保證100%。
  3. 面向字節(jié)流:以一個字節(jié)傳輸為基本單位。
  4. 全雙工:雙方都可以向?qū)Ψ桨l(fā)送信息。

3.2TCP中的長短連接

TCP發(fā)送數(shù)據(jù)時,需要先建立連接,什么時候關(guān)閉連接就決定是短連接還是長連接
短連接:每次接收到數(shù)據(jù)并返回響應(yīng)后,都關(guān)閉連接,即是短連接。也就是說,短連接只能一次收發(fā)數(shù)據(jù)。
長連接:不關(guān)閉連接,一直保持連接狀態(tài),雙方不停的收發(fā)數(shù)據(jù),即是長連接。也就是說,長連接可以多次收發(fā)數(shù)據(jù)。

長連接與短鏈接的區(qū)別:

  • 建立連接、關(guān)閉連接的耗時:短連接每次請求、響應(yīng)都需要建立連接,關(guān)閉連接;而長連接只需要第一次建立連接,之后的請求、響應(yīng)都可以直接傳輸。相對來說建立連接,關(guān)閉連接也是要耗時的,長連接效率更高。
  • 主動發(fā)送請求不同:短連接一般是客戶端主動向服務(wù)端發(fā)送請求;而長連接可以是客戶端主動發(fā)送請求,也可以是服務(wù)端主動發(fā)。
  • 兩者的使用場景有不同:短連接適用于客戶端請求頻率不高的場景,如瀏覽網(wǎng)頁等。長連接適用于客戶端與服務(wù)端通信頻繁的場景,如聊天室,實(shí)時游戲等。

3.3TCP套接字的API

TCP套接字的API中主要包含兩個類:1.ServerSocket 2.Socket

下面介紹這兩個類

3.3.1ServerSocket類

這個類是在看名字就很好理解,它主要用于服務(wù)端,它的作用是創(chuàng)建一個服務(wù)端套接字。

?ServerSocket類構(gòu)造方法:

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

在實(shí)例對象時,我們就將端口號傳進(jìn)來,完成實(shí)例。

?ServerSocket類方法:

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

?第一個accept方法它是接收客戶端的信息,如果客戶端沒有請求,那它就會阻塞等待,如果有請求,就會建立連接,它的返回值是一個套接字。

3.3.2Socket類

?這個類就是創(chuàng)建一個套接字實(shí)例對象,他的成員變量有兩個:IP與端口號。

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

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

Socket類方法:

方法簽名 方法說明
InetAddress getInetAddress() 返回套接字所連接的地址
InputStream getInputStream() 返回此套接字的輸入流
OutputStream getOutputStream() 返回此套接字的輸出流

?3.3.3基于TCP的回顯程序

服務(wù)端?

?服務(wù)器設(shè)計邏輯:

  1. 創(chuàng)建一個ServerSocket類對象,指定服務(wù)器端口號。
  2. 開始運(yùn)行服務(wù)端;通過第一步實(shí)例好的對象調(diào)用accept方法,如果有無請求,就阻塞,如果有請求,就發(fā)到下面進(jìn)行處理。
  3. 進(jìn)入處理請求方法,將請求通過讀接收緩沖區(qū)寫入,再將寫入的請求發(fā)給處理程序進(jìn)行處理。
  4. 處理完畢后,將響應(yīng)發(fā)給客服端。
package TcpNetWork;

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;

public class TcpEchoServer {
    private ServerSocket serverSocket=null;

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

    public void start() throws IOException {
        System.out.println("服務(wù)器啟動");
        while (true) {
            //接收到客服端請求
            Socket clientSocket=serverSocket.accept();
            //將請求發(fā)給解決請求的方法
            processConnection(clientSocket);
        }
    }

    private void processConnection(Socket clientSocket) throws IOException {
        System.out.printf("[%s:%d] 客戶端上線了\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());
        try (InputStream inputStream=clientSocket.getInputStream();
             OutputStream outputStream=clientSocket.getOutputStream()){
            // 沒有這個 scanner 和 printWriter, 完全可以!! 但是代價就是得一個字節(jié)一個字節(jié)扣, 找到哪個是請求的結(jié)束標(biāo)記 \n
            // 不是不能做, 而是代碼比較麻煩.
            // 為了簡單, 把字節(jié)流包裝好了更方便的字符流~~
            Scanner sc=new Scanner(inputStream);
            PrintWriter printWriter=new PrintWriter(outputStream);
            while (true) {
                //1.接到客服端請求
                if (!sc.hasNext()) {
                    System.out.printf("[%s:%d] 客戶端下線了\n", clientSocket.getInetAddress().toString(), clientSocket.getPort());
                    break;
                }
                String request=sc.next();
                //2.對請求做出響應(yīng)
                String response=process(request);
                //3.把響應(yīng)返回給客戶端
                printWriter.println(response);
                printWriter.flush();
                System.out.printf("[%s:%d] request:%s response:%s ",clientSocket.getInetAddress().toString(),
                        clientSocket.getPort(),request,response);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            clientSocket.close();
        }
    }

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

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

客戶端

客戶端設(shè)計邏輯:

  1. 創(chuàng)建一個Socket實(shí)例,指定服務(wù)器的ip和端口號。
  2. 開啟客戶端,輸入請求,并刷新接收緩存區(qū)。
  3. 等到服務(wù)端給出響應(yīng),接收響應(yīng),對響應(yīng)做出動作。
package TcpNetWork;


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(int port, String serverIp) throws IOException {
        socket=new Socket(serverIp,port);
    }

    public void start() {
        Scanner sc=new Scanner(System.in);
        try(InputStream inputStream=socket.getInputStream();
            OutputStream outputStream=socket.getOutputStream()) {
            Scanner scannerFromSocket=new Scanner(inputStream);
            PrintWriter printWriter=new PrintWriter(outputStream);
            while (true) {
                //1.從鍵盤上讀取請求
                System.out.print("輸入指令->");
                String request=sc.next();
                //2.將請求發(fā)送給服務(wù)器端,并刷新接收緩存區(qū)
                printWriter.println(request);
                printWriter.flush();
                //3.接收服務(wù)器端的信息
                String response=scannerFromSocket.next();
                //4.把信息打印到控制臺
                System.out.printf("request:%s response:%s\n",request,response);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

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

3.3.4對TCP回顯程序的優(yōu)化

在上方的程序中,我們只能對一個客戶端進(jìn)行提供服務(wù),這是因?yàn)槲覀冊诮邮盏牟糠纸o寫成了死循環(huán),如果出現(xiàn)第二個客戶端時,第二個客戶端只能進(jìn)行等待。我們?nèi)绾涡薷倪@個程序呢?這是我們就不得不提到多線程了,如果寫成多線程的話,就可以處理多個程序了。

程序代碼如下(服務(wù)端):?

package TcpNetWork;

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;

public class TcpEchoServer {
    private ServerSocket serverSocket=null;

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

    public void start() throws IOException {
        System.out.println("服務(wù)器啟動");
        while (true) {
            //接收到客服端請求
            Socket clientSocket=serverSocket.accept();
            //將請求發(fā)給解決請求的方法
            Thread t=new Thread(()->{
                try {
                    processConnection(clientSocket);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
        }
    }

    private void processConnection(Socket clientSocket) throws IOException {
        System.out.printf("[%s:%d] 客戶端上線了\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());
        try (InputStream inputStream=clientSocket.getInputStream();
             OutputStream outputStream=clientSocket.getOutputStream()){
            // 沒有這個 scanner 和 printWriter, 完全可以!! 但是代價就是得一個字節(jié)一個字節(jié)扣, 找到哪個是請求的結(jié)束標(biāo)記 \n
            // 不是不能做, 而是代碼比較麻煩.
            // 為了簡單, 把字節(jié)流包裝好了更方便的字符流~~
            Scanner sc=new Scanner(inputStream);
            PrintWriter printWriter=new PrintWriter(outputStream);
            while (true) {
                //1.接到客服端請求
                if (!sc.hasNext()) {
                    System.out.printf("[%s:%d] 客戶端下線了\n", clientSocket.getInetAddress().toString(), clientSocket.getPort());
                    break;
                }
                String request=sc.next();
                //2.對請求做出響應(yīng)
                String response=process(request);
                //3.把響應(yīng)返回給客戶端
                printWriter.println(response);
                printWriter.flush();
                System.out.printf("[%s:%d] request:%s response:%s ",clientSocket.getInetAddress().toString(),
                        clientSocket.getPort(),request,response);
                System.out.println();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            clientSocket.close();
        }
    }

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

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

如果我們想要去驗(yàn)證這個程序是否可以對多個客戶端提供服務(wù),我們還需要對其修改一點(diǎn)配置,不然我們不能將同一個類運(yùn)行兩次。

?1.右鍵鼠標(biāo),選擇修改運(yùn)行配置?

【JaveEE】網(wǎng)絡(luò)編程之TCP套接字、UDP套接字?2.點(diǎn)開之后,點(diǎn)擊修改選項(xiàng)?

【JaveEE】網(wǎng)絡(luò)編程之TCP套接字、UDP套接字?3.將允許多個實(shí)例打勾,這一我們就可以同時運(yùn)行多個實(shí)例了。

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


寫在最后:

??????以上就是本文全部內(nèi)容,如果對你有所幫助,希望能留下你的點(diǎn)贊+關(guān)注,我會更加努力的更新內(nèi)容!非常感謝??????

若本篇文章有錯誤的地方,歡迎大佬們指正!

【JaveEE】網(wǎng)絡(luò)編程之TCP套接字、UDP套接字文章來源地址http://www.zghlxwxcb.cn/news/detail-412227.html

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

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

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

相關(guān)文章

  • 【Linux網(wǎng)絡(luò)】網(wǎng)絡(luò)編程套接字(TCP)

    【Linux網(wǎng)絡(luò)】網(wǎng)絡(luò)編程套接字(TCP)

    目錄 地址轉(zhuǎn)換函數(shù) 字符串IP轉(zhuǎn)整數(shù)IP 整數(shù)IP轉(zhuǎn)字符串IP 關(guān)于inet_ntoa 簡單的單執(zhí)行流TCP網(wǎng)絡(luò)程序 TCP socket API 詳解及封裝TCP socket? 服務(wù)端創(chuàng)建套接字? 服務(wù)端綁定? 服務(wù)端監(jiān)聽? 服務(wù)端獲取連接? 服務(wù)端處理請求 客戶端創(chuàng)建套接字 客戶端連接服務(wù)器 客戶端發(fā)起請求 服務(wù)器測試

    2024年03月21日
    瀏覽(113)
  • 【Linux】網(wǎng)絡(luò)---->套接字編程(TCP)

    【Linux】網(wǎng)絡(luò)---->套接字編程(TCP)

    TCP的編程流程:大致可以分為五個過程,分別是準(zhǔn)備過程、連接建立過程、獲取新連接過程、消息收發(fā)過程和斷開過程。 1.準(zhǔn)備過程:服務(wù)端和客戶端需要創(chuàng)建各自的套接字,除此之外服務(wù)端還需要綁定自己的地址信息和進(jìn)行監(jiān)聽。注意:服務(wù)端調(diào)用listen函數(shù)后,處理監(jiān)聽狀

    2024年02月04日
    瀏覽(101)
  • Linux網(wǎng)絡(luò)編程——tcp套接字

    Linux網(wǎng)絡(luò)編程——tcp套接字

    本章Gitee倉庫:tcp套接字 客戶端: 客戶端: 關(guān)于構(gòu)造和初始化,可以直接在構(gòu)造的時候,將服務(wù)器初始化,那為什么還要寫到 init 初始化函數(shù)里面呢? 構(gòu)造盡量簡單一點(diǎn),不要做一些“有風(fēng)險”的操作。 tcp 是面向連接的,通信之前要建立連接,服務(wù)器處于等待連接到來的

    2024年02月20日
    瀏覽(96)
  • 網(wǎng)絡(luò)編程套接字之三【TCP】

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

    目錄 1. ServerSocket API(給服務(wù)器端使用的類) 2. Socket API(既給服務(wù)器使用,也給客戶端使用) 3. 寫TCP回顯—服務(wù)器 4. 使用線程池后的TCP服務(wù)器代碼(最終) 5. 寫回顯-客戶端 6. TCP回顯—客戶端代碼 7. 運(yùn)行回顯服務(wù)器和客戶端 TCP流套接字編程 ?ServerSocket 是創(chuàng)建TCP服務(wù)端Socket的

    2024年01月19日
    瀏覽(92)
  • 網(wǎng)絡(luò)編程套接字(2)——簡單的TCP網(wǎng)絡(luò)程序

    網(wǎng)絡(luò)編程套接字(2)——簡單的TCP網(wǎng)絡(luò)程序

    我們將TCP服務(wù)器封裝成一個類,當(dāng)我們定義出一個服務(wù)器對象后需要馬上對服務(wù)器進(jìn)行初始化,而初始化TCP服務(wù)器要做的第一件事就是創(chuàng)建套接字。 TCP服務(wù)器在調(diào)用socket函數(shù)創(chuàng)建套接字時,參數(shù)設(shè)置如下: 協(xié)議家族選擇 AF_INET ,因?yàn)槲覀円M(jìn)行的是網(wǎng)絡(luò)通信。 創(chuàng)建套接字時

    2024年02月06日
    瀏覽(93)
  • 【Linux網(wǎng)絡(luò)編程】網(wǎng)絡(luò)編程套接字(TCP服務(wù)器)

    【Linux網(wǎng)絡(luò)編程】網(wǎng)絡(luò)編程套接字(TCP服務(wù)器)

    作者:愛寫代碼的剛子 時間:2024.4.4 前言:本篇博客主要介紹TCP及其服務(wù)器編碼 只介紹基于IPv4的socket網(wǎng)絡(luò)編程,sockaddr_in中的成員struct in_addr sin_addr表示32位 的IP地址 但是我們通常用點(diǎn)分十進(jìn)制的字符串表示IP地址,以下函數(shù)可以在字符串表示和in_addr表示之間轉(zhuǎn)換 字符串轉(zhuǎn)in

    2024年04月14日
    瀏覽(108)
  • TCP/IP網(wǎng)絡(luò)編程(一) 理解網(wǎng)絡(luò)編程和套接字

    網(wǎng)絡(luò)編程和套接字概要 網(wǎng)絡(luò)編程就是編寫程序使兩臺聯(lián)網(wǎng)的計算機(jī)相互交換數(shù)據(jù) 為了與遠(yuǎn)程計算機(jī)進(jìn)行數(shù)據(jù)傳輸,需要連接因特網(wǎng),而編程種的套接字就是用來連接該網(wǎng)絡(luò)的工具。 構(gòu)建套接字 1.調(diào)用soecket函數(shù)創(chuàng)建套接字 2.調(diào)用bind函數(shù)給套接字分配地址 3.調(diào)用listen函數(shù)將套

    2024年02月11日
    瀏覽(857)
  • 【網(wǎng)絡(luò)通信】socket編程——TCP套接字

    【網(wǎng)絡(luò)通信】socket編程——TCP套接字

    TCP依舊使用代碼來熟悉對應(yīng)的套接字,很多接口都是在udp中使用過的 所以就不會單獨(dú)把他們拿出來作為標(biāo)題了,只會把第一次出現(xiàn)的接口作為標(biāo)題 通過TCP的套接字 ,來把數(shù)據(jù)交付給對方的應(yīng)用層,完成雙方進(jìn)程的通信 在 tcpServer.hpp 中,創(chuàng)建一個命名空間 yzq 用于封裝 在命名

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

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

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

    2024年02月07日
    瀏覽(91)
  • C++網(wǎng)絡(luò)編程 TCP套接字基礎(chǔ)知識,利用TCP套接字實(shí)現(xiàn)客戶端-服務(wù)端通信

    C++網(wǎng)絡(luò)編程 TCP套接字基礎(chǔ)知識,利用TCP套接字實(shí)現(xiàn)客戶端-服務(wù)端通信

    流式套接字編程針對TCP協(xié)議通信,即是面向?qū)ο蟮耐ㄐ牛譃榉?wù)端和客戶端兩部分。 1)加載套接字庫( 使用函數(shù)WSAStartup() ),創(chuàng)建套接字( 使用socket() ) 2)綁定套接字到一個IP地址和一個端口上( 使用函數(shù)bind() ) 3)將套接字設(shè)置為監(jiān)聽模式等待連接請求( 使用函數(shù)

    2024年02月03日
    瀏覽(103)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包