客戶端與服務端之間的通信連接

目錄

那什么是Socket?

什么是ServerSocket?

代碼展示:

代碼解析:

補充:

輸入流(InputStream):

輸出流(OutputStream):

`BufferedReader` 是如何提高讀取效率的?

`BufferedWritter` 是如何提高讀取效率的?


在Java中實現客戶端與服務器端之間的連接通常可以通過SocketServerSocket類來實現。

那什么是Socket?

  1. Socket(套接字)是在網絡編程中使用的一種抽象概念,用于建立不同計算機之間的通信連接。Socket允許不同計算機上的應用程序通過網絡進行數據交換。
  2. 在Java編程中,Socket類是對套接字的抽象表示,提供了用于網絡通信的接口。通過Socket類,可以實現客戶端和服務器之間的通信,包括數據的發送和接收。
  3. 在一個通信過程中,客戶端和服務器端各自創建一個Socket對象,并通過這個Socket對象來進行通信。客戶端通過Socket連接服務器端的地址和端口號,然后可以通過Socket對象發送數據到服務器端;服務器端接收到客戶端的請求后,也會創建一個新的Socket對象與客戶端建立連接,從而進行數據交換。
  4. Socket對象在使用完畢后需要進行關閉操作,以釋放資源和終止通信連接。在Java編程中,通常會在try-with-resources語句中使用Socket對象,以確保在通信結束時Socket對象能夠被正確關閉。
  5. 總的來說,Socket類在網絡編程中扮演著重要的角色,它提供了一種簡單而有效的方式來實現計算機之間的通信和數據交換。
    ?

什么是ServerSocket?

  1. ServerSocket是Java編程語言中的一個類,用于在服務器端創建一個服務器套接字,監聽客戶端的連接請求。通過ServerSocket,服務器端可以接收來自客戶端的連接,并與客戶端建立通信連接。
  2. ServerSocket類提供了創建服務器套接字、監聽端口、接受客戶端連接請求等功能。通過ServerSocket的accept()方法,服務器端可以等待客戶端的連接請求,并一旦有客戶端請求連接,accept()方法將返回一個Socket對象,服務器端可以通過這個Socket對象與客戶端進行通信。
  3. 在一個典型的網絡應用程序中,服務器端通常會使用ServerSocket來初始化并監聽一個特定的端口,等待客戶端連接,然后處理客戶端請求并進行相應的回復。ServerSocket類被廣泛應用于Java網絡編程中,用于實現服務器端的監聽與響應。
  4. 需要注意的是,ServerSocket通常用在服務器端,用于監聽客戶端連接請求;而連接到服務器的客戶端將會使用普通的Socket對象進行通信。通過ServerSocket和Socket相互配合,可以實現服務器端與多個客戶端之間的連接通信。
  5. 總的來說,ServerSocket是Java中用于創建服務器套接字、接收客戶端連接請求的重要類,是實現基于TCP協議的服務器端網絡通信的關鍵組件。

代碼展示:


import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
//【服務端】
public class AIzzServer {public static HashMap<String,String> map=new HashMap<>();static {map.put("你好", "你好呀,孫子");map.put("hi", "hello,孫子");map.put("hello", "hi,孫子");map.put("吃了嗎", "沒呢,孫子");map.put("很高興認識你", "我也是哦");}public static void main(String[] args) {try(ServerSocket serverSocket=new ServerSocket(8848)){while(true) {Socket clientSocket=serverSocket.accept();String clientIp=clientSocket.getInetAddress().getHostAddress();//輸入流:讀取客戶端發送的”問題“//輸出流:發送問題的答案給客戶端try(BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()))){//讀取來自客戶端的”問題“String question=reader.readLine();if(question==null||question.length()==0){continue;}System.out.printf("來自客戶端[%s]的問題:%s\n",clientIp,question);String answer=map.get(question);answer=answer==null?"對不起,我不知道你在說什么!":answer;//將問題的答案輸出至”客戶端“writer.write(answer);}}} catch (IOException e) {throw new RuntimeException(e);}}
}


import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;//【客戶端】
public class AIzzClient {public static void main(String[] args) {try(Scanner input=new Scanner(System.in)){//讀取控制臺輸入的問題String question=input.nextLine();//創建Socket,輸出流,輸入流try(Socket clientSocket=new Socket(InetAddress.getLocalHost(),8848);BufferedReader reader=new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));){//向服務端發送”問題“(輸出至服務端)writer.write(question);writer.flush();//暫時關閉輸出流clientSocket.shutdownOutput();//接收服務端返回的“答案”String ans=reader.readLine();System.out.println("來自服務端的回答:"+ans);} catch (UnknownHostException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);}}}
}

代碼解析:

????????上述代碼展示了一個基于 TCP 協議的簡單人工對打程序,包括服務端 `AIzzServer` 和客戶端 `AIzzClient` 兩個部分。

服務端 `AIzzServer` 主要負責:

  • 1. 創建一個監聽端口為 `8848` 的 `ServerSocket` ,等待客戶端連接。
  • 2. 當有客戶端連接成功時,獲取客戶端的 IP 地址。
  • 3. 通過輸入流讀取客戶端發送的問題,并在預先定義的 `HashMap` 中查找對應的答案。如果問題不存在于 `HashMap` 中,則返回默認的回答“對不起,我不知道你在說什么!”。
  • 4. 將找到的答案通過輸出流發送回客戶端。

客戶端 `AIzzClient` 主要負責:

  • 1. 從控制臺讀取用戶輸入的問題。
  • 2. 創建與本地主機 `8848` 端口的連接。
  • 3. 通過輸出流向服務端發送問題。
  • 4. 發送完成后關閉輸出流。? ?

????????通過輸入流接收服務端返回的答案,并打印輸出。 兩者通過 TCP 協議進行通信,客戶端發送問題,服務端接收并處理后返回答案,形成了一個簡單的交互流程。例如,當用戶在客戶端輸入“你好”,客戶端將這個問題發送給服務端,服務端從 `HashMap` 中找到對應的“你好呀,孫子”并返回給客戶端,客戶端接收并顯示出來。

補充:

輸入流(InputStream)

????????輸入流用于從數據源讀取數據到程序中。數據源可以是文件、網絡連接、內存緩沖區等。

它提供了一系列方法,允許程序按順序讀取數據的一部分或全部。常見的輸入流操作包括讀取一個字節、讀取一組字節、讀取一個字符、讀取一行文本等。

????????例如,FileInputStream?可以從文件中讀取字節數據,BufferedReader?可以更高效地從字符輸入流中讀取文本行。

輸出流(OutputStream)

????????輸出流則用于將程序中的數據寫入到數據目的地。目的地同樣可以是文件、網絡連接、內存緩沖區等。

輸出流提供了方法來將數據按順序寫入,例如寫入一個字節、寫入一組字節、寫入一個字符等。

????????比如,FileOutputStream?用于向文件中寫入字節數據,PrintWriter?常用于向輸出流中寫入格式化的文本。

總的來說,輸入流和輸出流是 Java 中用于實現數據在程序與外部數據源或目的地之間傳輸的重要機制。通過合理使用不同類型的輸入流和輸出流,可以方便地處理各種數據的讀取和寫入操作。

`BufferedReader` 是如何提高讀取效率的?

????????`BufferedReader` 通過內部的緩沖區來提高讀取效率。 當使用普通的輸入流(如 `FileReader` )讀取數據時,每次讀取操作可能都會導致與底層數據源(例如文件)的直接交互,這可能會帶來較高的系統開銷,特別是在頻繁讀取小量數據的情況下。

????????而 `BufferedReader` 在其內部維護了一個緩沖區(通常是一個字節數組)。當調用讀取方法時,它首先嘗試從緩沖區中獲取數據。如果緩沖區中有足夠的數據,就直接返回,避免了頻繁地與底層數據源進行交互。 當緩沖區中的數據不足時,`BufferedReader` 會一次性從底層輸入流中讀取較大塊的數據填充緩沖區,而不是每次只讀取一個字節或幾個字節。

???????? 例如,如果緩沖區大小設置為 8192 字節,那么 `BufferedReader` 可能會一次性從底層輸入流讀取 8192 字節的數據放入緩沖區,后續的讀取操作只要從緩沖區獲取即可,大大減少了與底層輸入流交互的次數,從而顯著提高了讀取效率。 這種緩沖機制特別適用于按行讀取文本文件的情況,因為按行讀取時,可能需要多次讀取少量的數據,`BufferedReader` 的緩沖作用能有效地優化這種操作。

`BufferedWritter` 是如何提高讀取效率的?

????????`BufferedWriter` 主要通過內部的緩沖區來提高寫入效率。 當使用普通的字符輸出流(如 `FileWriter`)進行寫入操作時,每次寫入一個字符或一小段數據,都可能會引發與底層輸出目的地(例如文件)的實際交互,這會帶來較多的系統開銷。

????????而 `BufferedWriter` 在其內部維護了一個緩沖區(通常是一個字符數組)。當調用寫入方法(如 `write`)時,數據并不是直接寫入到目的地,而是先被存儲到緩沖區中。 緩沖區有一定的大小,當緩沖區被填滿或者手動調用 `flush` 方法時,`BufferedWriter` 會一次性地將緩沖區中的數據寫入到底層輸出流中。這樣就減少了與底層輸出目的地交互的次數,從而顯著提高了寫入效率。

????????例如,在向文件寫入大量數據時,如果不使用 `BufferedWriter`,可能需要頻繁地進行磁盤 I/O 操作,而使用 `BufferedWriter` 后,只需在緩沖區滿或主動刷新時才進行實際的磁盤寫入,大大降低了磁盤 I/O 的次數。 一般情況下,使用默認大小的緩沖區即可滿足大多數需求。但如果明確知道寫入數據的特征,也可以在創建 `BufferedWriter` 對象時指定緩沖區的大小,

? ??

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/45583.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/45583.shtml
英文地址,請注明出處:http://en.pswp.cn/web/45583.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

K8s集群初始化遇到的問題

kubectl describe pod coredns-545d6fc579-s9g5s -n kube-system 找到原因1&#xff1a;CoreDNS Pod 處于 Pending 狀態的原因是集群中的節點都帶有 node.kubernetes.io/not-ready 污點 journalctl -u kubelet -f 14:57:59.178592 3553 remote_image.go:114] "PullIma…

《簡歷寶典》12 - 簡歷中“項目經歷”,內功學習 - 下篇

這一小節呢&#xff0c;我們繼續說簡歷中 “項目經歷” 的一些內功心法。因為項目經歷比較核心&#xff0c;所以說完了&#xff0c;內功呢&#xff0c;我們會著重說一下 實戰部分。 目錄 1 所用技術的考慮 2 自我成長的突出 3 綜合使用STAR法則 4 小節 1 所用技術的考慮 …

如何評估AI模型:評估指標的分類、方法及案例解析

如何評估AI模型&#xff1a;評估指標的分類、方法及案例解析 引言第一部分&#xff1a;評估指標的分類第二部分&#xff1a;評估指標的數學基礎第三部分&#xff1a;評估指標的選擇與應用第四部分&#xff1a;評估指標的局限性第五部分&#xff1a;案例研究第六部分&#xff1a…

pear-admin-fast項目修改為集成PostgreSQL啟動

全局搜索代碼中的sysdate()&#xff0c;修改為now() 【前者是mysql特有的&#xff0c;后者是postgre特有的】修改application-dev.yml中的數據庫url使用DBeaver把mysql中的數據庫表導出csv&#xff0c;再從postgre中導入csv腳本轉換后出現了bpchar(xx)類型&#xff0c;那么一定…

用友U8存貨分類按層級取數SQL語句

SELECT cInvCCode 分類編碼, cInvCName 分類名稱, iInvCGrade 分類層級, ss.bInvCEnd 是否是末級, aa.* FROM InventoryClass ss LEFT JOIN ( SELECT * FROM ( SELECT cInvCCode AS 一級分類編碼, …

python數據可視化(6)——繪制散點圖

課程學習來源&#xff1a;b站up&#xff1a;【螞蟻學python】 【課程鏈接&#xff1a;【【數據可視化】Python數據圖表可視化入門到實戰】】 【課程資料鏈接&#xff1a;【鏈接】】 Python繪制散點圖查看BMI與保險費的關系 散點圖: 用兩組數據構成多個坐標點&#xff0c;考察…

如何降低老年人患帕金森病的風險?

降低老年人患帕金森病風險的方法 避免接觸有害物質&#xff1a;長期接觸某些化學物質、農藥或其他有害物質可能會增加患帕金森病的風險。應減少這些物質的暴露&#xff0c;例如在工作或生活中采取防護措施。 健康飲食&#xff1a;均衡飲食&#xff0c;多吃富含抗氧化劑的食物&a…

做了一個萬能搜索框

最近給網頁做了一個搜索框&#xff0c;現在搜索比以前更加方便了&#xff0c;下面簡單介紹一下如何使用 我們進入網頁版&#xff08;app.zyjj.cc&#xff09;點擊右上角的搜索就可以看到這個新版的搜索框了 目前支持中文、拼音、首字母等多種搜索方式&#xff0c;大家可以隨意…

【Python】Python-docx使用實例 科技檔案封面批量生成

使用背景 根據excel表中的信息&#xff0c;按照word模板格式&#xff0c;每條信息生成一個對應的模板及文件名。 我這里的情況是將科技檔案的封面格式按照案卷表的明細批量生成。 &#xff08;單位的檔案軟件太雞肋了&#xff0c;沒有這個功能&#xff09; 代碼整篇 工程檔…

【Linux】常見指令(下)

【Linux】常見指令&#xff08;下&#xff09; 通配符 *man指令cp指令echo指令cat指令&#xff08;簡單介紹&#xff09;cp指令 mv指令alias指令which ctrl ccat指令linux下一切皆文件 more指令less指令head指令tail指令管道 通配符 ‘*’ 通配符’ *‘&#xff0c;是可以匹配…

4 C 語言控制流與循環結構的深入解讀

目錄 1 復雜表達式的計算過程 2 if-else語句 2.1 基本結構及示例 2.2 if-else if 多分支 2.3 嵌套 if-else 2.4 懸空的 else 2.5 注意事項 2.5.1 if 后面不要加分號 2.5.2 省略 else 2.5.3 省略 {} 2.5.4 注意點 3 while 循環 3.1 一般形式 3.2 流程特點 3.3 注…

Dynamic多數據源

有時候我們在項目中&#xff0c;可能會遇到需要同時使用多個數據庫連接的情況&#xff0c;這個時候可以使用MyBatis-Plus的dynamic多數據源的配置。但其實MyBatis-Plus官方還提供了mybatis-mate組件&#xff0c;但是他是付費的企業組件。 官方文檔&#xff1a; 多數據源支持 …

識別視頻中的人數并統計出來

目的: 使用Python和pysimpleguil以及opencv寫一個統計人流量的軟件。要求:1 加載選定的視頻 2 通過形態學特征識別人,3統計人數并且在界面上顯示出來,4 保存識別出人數的信息。 步驟 1: 安裝必要的庫 首先,確保你已經安裝了Python。然后,安裝PySimpleGUI和OpenCV。你可…

數電基礎 - 可編程邏輯器件

目錄 ?編輯 一. 簡介 二. 現場可編程邏輯陣列 三. 可編程陣列邏輯 四. 通用陣列邏輯 五. 可擦除的可編程邏輯器件 六. 復雜的可編程邏輯器件 七. 現場可編程門陣列 一. 簡介 可編程邏輯器件&#xff08;Programmable Logic Device&#xff0c;PLD&#xff09;是一種用…

Gmsh用戶界面

主要指出幾何、網格、求解三個模塊. 幾何模塊分為基本實體和物理組兩個部分&#xff0c;主要對幾何體進行操作&#xff0c;并設置物理屬性 網格模塊主要定義了對網格的操作和對應的算法 求解主要指出了網格求解方法 所有的界面操作都是基于這三個方法的

半導體仿真文件傳輸面臨時間和經濟成本挑戰,一招就能解決

對于芯片設計企業來說&#xff0c;其面臨的最大考驗就是芯片設計質量和時間成本控制之間的矛盾&#xff0c;具體表現在芯片的設計、仿真驗證過程存在著較大的挑戰&#xff1a; 芯片設計過程包括了仿真驗證這一重要的一環&#xff0c;但芯片設計企業在仿真驗證這一環卻面臨著較…

數據結構--二叉樹遍歷

目錄 1.介紹 &#xff08;1&#xff09;前序遍歷 &#xff08;2&#xff09;定義結構體 &#xff08;3&#xff09;前序遍歷實現 &#xff08;4&#xff09;中序遍歷實現 &#xff08;5&#xff09;二叉樹的節點個數 &#xff08;6&#xff09;二叉樹樹葉節點個數 &…

數倉工具—Hive語法之宏(Macro)

Hive中的宏 許多關系型數據庫,如Teradata,支持宏(Macro)函數。在關系數據庫管理系統(RDBMS)中,宏存儲在數據字典中。用戶可以共享宏,并根據需要執行它們。Hive宏與關系型數據庫中的宏略有不同。在本文中,我們將檢查什么是宏,它的語法,如何使用它們,以及一些宏的示…

java 字段 大于4000拆分

java 字段 大于4000拆分 public List<String> splitJsonIfNecessary(String jsonStr) {List<String> result new ArrayList<>();while (jsonStr.length() > Constant.MAX_LENGTH) {// 直接按字符數截取&#xff0c;不考慮JSON結構String part jsonStr.s…

東軟醫療 踩在中國醫療科技躍遷的風口上

恐怕沒有哪一家本土醫療裝備企業能像東軟醫療一樣&#xff0c;每一段成長的升維都發生在中國醫療科技躍遷史最重要的節點上。 在工業制造領域&#xff0c;醫療裝備產業由于涉及數十個學科領域&#xff0c;其技術復合程度毫不遜于今天公眾所熟知的EUV光刻機&#xff0c;是一門技…