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

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

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

目錄

TCP流套接字編程

1.ServerSocket API

2.Socket API

3.TCP中的長短連接

4.回顯程序(短連接)

5.服務(wù)器和客戶端它們的交互過程

6.運行結(jié)果及修改代碼


?文章來源地址http://www.zghlxwxcb.cn/news/detail-411177.html

TCP流套接字編程

??兩個核心:ServerSocket? ? ?Socket

1.ServerSocket API

?ServerSocket 是創(chuàng)建?TCP服務(wù)端Socket的API

ServerSocket 構(gòu)造方法:

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

ServerSocket 方法

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

2.Socket API

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

Socket 構(gòu)造方法:

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

Socket 方法:

InetAddress getInetAddress() 返回套接字所連接的地址
InputStream getInputStream() 返回此套接字的輸入流
OutputStream getOutputStream() 返回此套接字的輸出流

3.TCP中的長短連接

??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ù)。
?

4.回顯程序(短連接)

1??TCP 客戶端

package io;

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 {
        // 這個操作相當于讓客戶端和服務(wù)器建立 tcp 連接.
        // 這里的連接連上了, 服務(wù)器的 accept 就會返回.
        socket = new Socket(serverIp, port);
    }

    //啟動客戶端程序
    public void start() {
        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. 從鍵盤上讀取用戶輸入的內(nèi)容.
                System.out.print("-> ");
                String request = scanner.next();
                // 2. 把讀取的內(nèi)容構(gòu)造成請求, 發(fā)送給服務(wù)器.
                //    注意, 這里的發(fā)送, 是帶有換行的!!
                printWriter.println(request);//這里只是把數(shù)據(jù)寫入內(nèi)存的緩沖區(qū)中,等待緩沖區(qū)滿了,才會真正寫網(wǎng)卡
                // 3. 從服務(wù)器讀取響應(yīng)內(nèi)容
                String response = scannerFromSocket.next();
                // 4. 把響應(yīng)結(jié)果顯示到控制臺上.
                System.out.printf("req: %s; resp: %s\n", request, response);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

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

2??TCP 服務(wù)端

package io;

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 {
    // serverSocket 就是外場拉客的小哥
    // clientSocket 就是內(nèi)場服務(wù)的小姐姐.
    // serverSocket 只有一個. clientSocket 會給每個客戶端都分配一個~
    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();
            processConnection(clientSocket);
        }
    }

    // 通過這個方法來處理一個連接.
    // 讀取請求
    // 根據(jù)請求計算響應(yīng)
    // 把響應(yīng)返回給客戶端
    private void processConnection(Socket clientSocket) throws IOException {
        System.out.printf("[%s:%d] 客戶端上線!\n", clientSocket.getInetAddress().toString(),
                clientSocket.getPort());
        // try () 這種寫法, ( ) 中允許寫多個流對象. 使用 ; 來分割
        try (InputStream inputStream = clientSocket.getInputStream();
             OutputStream outputStream = clientSocket.getOutputStream()) {
            // 沒有這個 scanner 和 printWriter, 完全可以!! 但是代價就是得一個字節(jié)一個字節(jié)扣, 找到哪個是請求的結(jié)束標記 \n
            // 不是不能做, 而是代碼比較麻煩.為了簡單, 把字節(jié)流包裝秤了更方便的字符流~~
            Scanner scanner = new Scanner(inputStream);
            //Scanner 相當于 字符流,上述約定了請求是字符串,所以就可以使用字符流來處理

            PrintWriter printWriter = new PrintWriter(outputStream);
            while (true) {
                // 1. 讀取請求:
                //hasNext 判定接下來還有沒有數(shù)據(jù)了,如果對端關(guān)閉連接(客戶端關(guān)閉連接),此時 hasNext 就會返回 false,循環(huán)就讓它結(jié)束
                //如果對端有數(shù)據(jù),hasNxet 返回 true,進一步就可以使用 next 方法來讀出這一段字符串的內(nèi)容了

                if (!scanner.hasNext()) {
                    // 讀取的流到了結(jié)尾了 (對端關(guān)閉了)
                    System.out.printf("[%s:%d] 客戶端下線!\n", clientSocket.getInetAddress().toString(),
                            clientSocket.getPort());
                    break;
                }
                // 直接使用 scanner 讀取一段字符串.
                String request = scanner.next();
                //next:一直往后讀,讀到空白符結(jié)束——空格,換行,制表符,翻頁符..都算空白符
                //nextLine 只是讀到換行符結(jié)束
                //這里不要用nextLine


                // 2. 根據(jù)請求計算響應(yīng)
                String response = process(request);
                // 3. 把響應(yīng)寫回給客戶端. 不要忘了, 響應(yīng)里也是要帶上換行的.
                printWriter.println(response);
                System.out.printf("[%s:%d] req: %s; resp: %s\n", clientSocket.getInetAddress().toString(),
                        clientSocket.getPort(), request, response);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            clientSocket.close();//clientSocket 只是給一個連接提供服務(wù)的,還是要能夠進行關(guān)閉
        }
    }

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

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

5.服務(wù)器和客戶端它們的交互過程

1??啟動服務(wù)器

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

?2??客戶端啟動

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

當客戶端和服務(wù)器連接建立好之后,服務(wù)器這邊的 accept 就返回了

3??服務(wù)器就進入 processConnection 了,嘗試從客戶端讀取請(由于此時客戶端還沒有發(fā)送請求,此時讀取操作也會阻塞)

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

?與此同時:

用戶端往下執(zhí)行到,從控制臺讀取用戶輸入——也會阻塞

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

?4??當用戶真的輸入內(nèi)容,客戶端真正發(fā)送了請求出去;同時往下執(zhí)行到,讀取服務(wù)器響應(yīng),再次阻塞

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

?5??服務(wù)器收到客戶端的請求之后,從 next 這里返回,執(zhí)行 process 執(zhí)行 println ,把響應(yīng)寫回到客戶端

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

?6??服務(wù)器重新回到上述開頭位置,繼續(xù)嘗試讀取請求,并阻塞

? ? ? 客戶端收到服務(wù)器的響應(yīng)就可以把結(jié)果顯示出來了;同時進入下次循環(huán),再次等待用戶的輸入了

6.運行結(jié)果及修改代碼

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

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

????當我們輸入 hello 之后,發(fā)現(xiàn)客戶端沒有任何響應(yīng)——因為數(shù)據(jù)還在緩沖區(qū)內(nèi)

// 2. 把讀取的內(nèi)容構(gòu)造成請求, 發(fā)送給服務(wù)器.
//    注意, 這里的發(fā)送, 是帶有換行的!!
printWriter.println(request);

這里只是把數(shù)據(jù)寫入內(nèi)存的緩沖區(qū)中,等待緩沖區(qū)滿了,才會真正寫網(wǎng)卡

1??此時我們需要沖刷

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

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

?此時就可以響應(yīng)了;當前程序已經(jīng)跑起來了,已經(jīng)可以正常通信了

??但是還存在一個嚴重的 bug!!服務(wù)器需要同時能夠給多個客戶端提供服務(wù)的

2??在 idea 中啟動多個客戶端,需要配置,默認一個程序只能啟動一個

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

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

???此時就可以啟動多個程序

3??但是我們看到的是在第一個客戶端輸入 hello,運行是正常的;但是我們在第二個客戶端輸入 hello2的時候沒有任何反應(yīng)

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

?這就是當前服務(wù)器無法同時服務(wù)多個客戶端;為什么會造成這種原因呢?

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

?6??解決方法:希望同時能夠給客戶端1提供服務(wù),又能夠循環(huán)的調(diào)用 accept——多線程

?如果直接調(diào)用,該方法回影響這個循環(huán)的二次執(zhí)行,導(dǎo)致 accept 不及時了 ;這個時候就需要 創(chuàng)建新的線程,用新線程來調(diào)用 processConnection;每次來一個新的客戶端都搞一個新的線程即可!!!

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

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

?此時運行結(jié)果:

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

7??解決方案2:使用 線程池?修改上述代碼

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

? ?一個連接的所有請求處理完,這個程序不會銷毀,而且還到池子里,下次直接使用

?

?

?

?

?

到了這里,關(guān)于網(wǎng)絡(luò)編程【TCP流套接字編程】的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(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的編程流程:大致可以分為五個過程,分別是準備過程、連接建立過程、獲取新連接過程、消息收發(fā)過程和斷開過程。 1.準備過程:服務(wù)端和客戶端需要創(chuàng)建各自的套接字,除此之外服務(wù)端還需要綁定自己的地址信息和進行監(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)造盡量簡單一點,不要做一些“有風(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. 運行回顯服務(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ù)器封裝成一個類,當我們定義出一個服務(wù)器對象后需要馬上對服務(wù)器進行初始化,而初始化TCP服務(wù)器要做的第一件事就是創(chuàng)建套接字。 TCP服務(wù)器在調(diào)用socket函數(shù)創(chuàng)建套接字時,參數(shù)設(shè)置如下: 協(xié)議家族選擇 AF_INET ,因為我們要進行的是網(wǎng)絡(luò)通信。 創(chuàng)建套接字時

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

    網(wǎng)絡(luò)編程和套接字概要 網(wǎng)絡(luò)編程就是編寫程序使兩臺聯(lián)網(wǎng)的計算機相互交換數(shù)據(jù) 為了與遠程計算機進行數(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日
    瀏覽(858)
  • 【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地址 但是我們通常用點分十進制的字符串表示IP地址,以下函數(shù)可以在字符串表示和in_addr表示之間轉(zhuǎn)換 字符串轉(zhuǎn)in

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

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

    TCP依舊使用代碼來熟悉對應(yīng)的套接字,很多接口都是在udp中使用過的 所以就不會單獨把他們拿出來作為標題了,只會把第一次出現(xiàn)的接口作為標題 通過TCP的套接字 ,來把數(shù)據(jù)交付給對方的應(yīng)用層,完成雙方進程的通信 在 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套接字實現(xiàn)客戶端-服務(wù)端通信

    C++網(wǎng)絡(luò)編程 TCP套接字基礎(chǔ)知識,利用TCP套接字實現(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)紅包