Day(22)--網絡編程習題

習題

以下是這些 TCP 通信練習題的 Java 代碼實現及解析:

TCP 通信練習 1 - 多發多收

客戶端(Client1.java)

java

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
?
public class Client1 {public static void main(String[] args) {try (Socket socket = new Socket("localhost", 8888)) {OutputStream os = socket.getOutputStream();String[] messages = {"Hello", "World", "Java"};for (String message : messages) {os.write(message.getBytes());os.flush();}} catch (IOException e) {e.printStackTrace();}}
}
服務器(Server1.java)

java

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
?
public class Server1 {public static void main(String[] args) {try (ServerSocket serverSocket = new ServerSocket(8888);Socket socket = serverSocket.accept();InputStream is = socket.getInputStream()) {byte[] buffer = new byte[1024];int len;while ((len = is.read(buffer)) != -1) {String message = new String(buffer, 0, len);System.out.println("收到客戶端消息: " + message);}} catch (IOException e) {e.printStackTrace();}}
}

解析

  • 客戶端:創建 Socket 連接到本地主機的 8888 端口,獲取輸出流,循環發送多個字符串消息。

  • 服務器:創建 ServerSocket 監聽 8888 端口,接受客戶端連接后獲取輸入流,通過循環讀取輸入流數據,直到沒有數據可讀,打印接收到的消息。

TCP 通信練習 2 - 接收和反饋

客戶端(Client2.java)

java

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
?
public class Client2 {public static void main(String[] args) {try (Socket socket = new Socket("localhost", 8888)) {OutputStream os = socket.getOutputStream();os.write("你好".getBytes());os.flush();
?InputStream is = socket.getInputStream();byte[] buffer = new byte[1024];int len = is.read(buffer);String feedback = new String(buffer, 0, len);System.out.println("收到服務器反饋: " + feedback);} catch (IOException e) {e.printStackTrace();}}
}
服務器(Server2.java)

java

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
?
public class Server2 {public static void main(String[] args) {try (ServerSocket serverSocket = new ServerSocket(8888);Socket socket = serverSocket.accept();InputStream is = socket.getInputStream();OutputStream os = socket.getOutputStream()) {byte[] buffer = new byte[1024];int len = is.read(buffer);String message = new String(buffer, 0, len);System.out.println("收到客戶端消息: " + message);
?os.write("已收到".getBytes());os.flush();} catch (IOException e) {e.printStackTrace();}}
}

解析

  • 客戶端:連接到服務器,發送一條消息后,等待接收服務器反饋并打印。

  • 服務器:接受客戶端連接,讀取客戶端發送的消息并打印,然后向客戶端發送反饋消息。

TCP 通信練習 3 - 上傳文件

客戶端(Client3.java)

java

import java.io.*;
import java.net.Socket;
?
public class Client3 {public static void main(String[] args) {try (Socket socket = new Socket("localhost", 8888);FileInputStream fis = new FileInputStream("test.txt");OutputStream os = socket.getOutputStream()) {byte[] buffer = new byte[1024];int len;while ((len = fis.read(buffer)) != -1) {os.write(buffer, 0, len);}socket.shutdownOutput();
?InputStream is = socket.getInputStream();byte[] feedbackBuffer = new byte[1024];int feedbackLen = is.read(feedbackBuffer);String feedback = new String(feedbackBuffer, 0, feedbackLen);System.out.println(feedback);} catch (IOException e) {e.printStackTrace();}}
}
服務器(Server3.java)

java

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
?
public class Server3 {public static void main(String[] args) {try (ServerSocket serverSocket = new ServerSocket(8888);Socket socket = serverSocket.accept();InputStream is = socket.getInputStream();FileOutputStream fos = new FileOutputStream("received.txt")) {byte[] buffer = new byte[1024];int len;while ((len = is.read(buffer)) != -1) {fos.write(buffer, 0, len);}OutputStream os = socket.getOutputStream();os.write("文件上傳成功".getBytes());os.flush();} catch (IOException e) {e.printStackTrace();}}
}

解析

  • 客戶端:連接服務器,讀取本地文件并通過 Socket 輸出流發送給服務器,發送完畢后關閉輸出流,然后接收服務器反饋。

  • 服務器:監聽端口接受連接,通過輸入流讀取客戶端發送的數據寫入新文件,文件接收完畢后向客戶端發送反饋。

TCP 通信練習 4 - 上傳文件(文件名重復問題)

解決方案思路

在服務器端接收文件時,檢查文件名是否已存在,如果存在可以在文件名后添加序號或時間戳等方式進行重命名。以下是簡單示例代碼在 Server3 基礎上修改:

java

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
?
public class Server4 {public static void main(String[] args) {try (ServerSocket serverSocket = new ServerSocket(8888);Socket socket = serverSocket.accept();InputStream is = socket.getInputStream()) {String fileName = "received.txt";File file = new File(fileName);int count = 1;while (file.exists()) {String filePrefix = fileName.substring(0, fileName.lastIndexOf('.'));String fileSuffix = fileName.substring(fileName.lastIndexOf('.'));fileName = filePrefix + "(" + count + ")" + fileSuffix;file = new File(fileName);count++;}try (FileOutputStream fos = new FileOutputStream(file)) {byte[] buffer = new byte[1024];int len;while ((len = is.read(buffer)) != -1) {fos.write(buffer, 0, len);}OutputStream os = socket.getOutputStream();os.write("文件上傳成功".getBytes());os.flush();}} catch (IOException e) {e.printStackTrace();}}
}

解析:在服務器接收文件前,先檢查文件名是否存在,若存在則通過添加序號的方式生成新文件名,再進行文件接收操作。

TCP 通信練習 5 - 上傳文件(多線程版)

服務器(Server5.java)

java

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
?
public class Server5 {public static void main(String[] args) {try (ServerSocket serverSocket = new ServerSocket(8888)) {while (true) {Socket socket = serverSocket.accept();new Thread(() -> {try (InputStream is = socket.getInputStream();FileOutputStream fos = new FileOutputStream("received_" + System.currentTimeMillis() + ".txt")) {byte[] buffer = new byte[1024];int len;while ((len = is.read(buffer)) != -1) {fos.write(buffer, 0, len);}System.out.println("文件接收成功");} catch (IOException e) {e.printStackTrace();}}).start();}} catch (IOException e) {e.printStackTrace();}}
}
客戶端(可復用 Client3.java)

解析:服務器通過無限循環接受客戶端連接,每接收到一個連接就創建一個新線程來處理文件接收,這樣可以同時處理多個客戶端的上傳請求。

TCP 通信練習 6 - 上傳文件(線程池優化)

服務器(Server6.java)

java

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
?
public class Server6 {private static final int THREAD_POOL_SIZE = 5;private static ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
?public static void main(String[] args) {try (ServerSocket serverSocket = new ServerSocket(8888)) {while (true) {Socket socket = serverSocket.accept();executorService.submit(() -> {try (InputStream is = socket.getInputStream();FileOutputStream fos = new FileOutputStream("received_" + System.currentTimeMillis() + ".txt")) {byte[] buffer = new byte[1024];int len;while ((len = is.read(buffer)) != -1) {fos.write(buffer, 0, len);}System.out.println("文件接收成功");} catch (IOException e) {e.printStackTrace();}});}} catch (IOException e) {e.printStackTrace();}}
}
客戶端(可復用 Client3.java)

解析:使用線程池(這里是固定大小線程池)來管理線程,避免頻繁創建和銷毀線程,提高系統資源利用率,當有客戶端連接時,將任務提交給線程池處理。

TCP 通信練習 7 - BS(接收瀏覽器的消息并打印)

服務器(Server7.java)

java

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
?
public class Server7 {public static void main(String[] args) {try (ServerSocket serverSocket = new ServerSocket(8080);Socket socket = serverSocket.accept();InputStream is = socket.getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(is))) {String line;while ((line = br.readLine()) != null) {System.out.println(line);if (line.isEmpty()) {break;}}} catch (IOException e) {e.printStackTrace();}}
}

解析:服務器監聽 8080 端口(常用 HTTP 端口),接受瀏覽器連接后,通過 BufferedReader 逐行讀取瀏覽器發送的 HTTP 請求消息并打印,當讀取到空行時(HTTP 請求頭結束標志)停止讀取。

TCP 通信練習 8 - 控制臺版的聊天室

客戶端(ChatClient.java)

java

import java.io.*;
import java.net.Socket;
import java.util.Scanner;
?
public class ChatClient {public static void main(String[] args) {try (Socket socket = new Socket("localhost", 8888);OutputStream os = socket.getOutputStream();PrintWriter pw = new PrintWriter(os, true);InputStream is = socket.getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(is));Scanner scanner = new Scanner(System.in)) {new Thread(() -> {try {String message;while ((message = br.readLine()) != null) {System.out.println(message);}} catch (IOException e) {e.printStackTrace();}}).start();
?String input;while ((input = scanner.nextLine()) != null) {pw.println(input);if ("exit".equals(input)) {break;}}} catch (IOException e) {e.printStackTrace();}}
}
服務器(ChatServer.java)

java

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
?
public class ChatServer {private static List<PrintWriter> writers = new ArrayList<>();
?public static void main(String[] args) {try (ServerSocket serverSocket = new ServerSocket(8888)) {while (true) {Socket socket = serverSocket.accept();new Thread(() -> {try (InputStream is = socket.getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(is));OutputStream os = socket.getOutputStream();PrintWriter pw = new PrintWriter(os, true)) {writers.add(pw);String message;while ((message = br.readLine()) != null) {for (PrintWriter writer : writers) {writer.println(message);}if ("exit".equals(message)) {writers.remove(pw);break;}}} catch (IOException e) {e.printStackTrace();}}).start();}} catch (IOException e) {e.printStackTrace();}}
}

解析

  • 客戶端:創建 Socket 連接服務器,啟動一個線程用于接收服務器轉發的消息并打印,通過 Scanner 讀取控制臺輸入,將輸入消息發送給服務器,輸入 “exit” 時退出。

  • 服務器:監聽端口接受客戶端連接,為每個連接創建新線程,將每個客戶端的輸出流(PrintWriter)保存到列表中,讀取客戶端發送的消息并轉發給所有客戶端,當客戶端發送 “exit” 時從列表中移除該客戶端的輸出流。

以上代碼基于 Java 語言實現,在實際運行時,需根據情況調整端口等配置,并且要注意異常處理等方面的優化。

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

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

相關文章

20、.NET SDK概述

.NET SDK&#xff08;Software Development Kit&#xff09; 是微軟提供的一套開發工具包&#xff0c;用于構建、運行和管理基于 .NET 平臺的應用程序。它包含了一組豐富的工具、庫和運行時環境&#xff0c;支持開發者在多種操作系統&#xff08;如 Windows、Linux 和 macOS&am…

DELL電腦開機進入自檢界面

疑難解答 - 如何解決開機直接進入BIOS畫面 添加鏈接描述 一、DELL電腦開機自檢提示please run setup program 未設置一天中的時間-請運行安裝程序(Time-of-day not set - please run SETUP program) 配置信息無效-請運行安裝程序(Invalid configuration information - ple…

2025 最新版 Node.js 下載安裝及環境配置詳細教程【保姆級】

2025 最新版 Node.js 下載安裝及環境配置詳細教程【保姆級】 一、下載安裝二、環境配置三、緩存配置、全局配置以及更換國內淘寶鏡像源 一、下載安裝 下載地址&#xff1a;Node.js 官方下載地址 雙擊安裝&#xff0c;點擊 Change 更改安裝位置。我只有一個C盤&#xff0c;這里…

2025年4月通信科技領域周報(4.07-4.13):6G技術加速落地 衛星通信網絡迎來組網高潮

2025年4月通信科技領域周報&#xff08;4.07-4.13&#xff09;&#xff1a;6G技術加速落地 衛星通信網絡迎來組網高潮 目錄 2025年4月通信科技領域周報&#xff08;4.07-4.13&#xff09;&#xff1a;6G技術加速落地 衛星通信網絡迎來組網高潮一、本周熱點回顧1. 華為發布全球首…

vxe-table 動態列篩選,以及篩選項動態變化的解決方案記錄

需求場景&#xff1a; table 的列是由接口動態返回的&#xff1b;列的篩選項就是數據的值&#xff0c;比如【姓名】這個字段總共有三個值&#xff0c;那么姓名這一列的篩選項就是這三個值本身&#xff1b;當有一列篩選后&#xff0c;其他列的篩選項也要動態變化。 vxe-table …

UE5游戲分辨率設置和窗口模式

第一種方法: 在項目配置Config文件夾下新建 DefaultGameUserSettings.ini 輸入代碼 [/Script/Engine.GameUserSettings] bUseVSyncFalse ResolutionSizeX1960 ResolutionSizeY1080 LastUserConfirmedResolutionSizeX800 LastUserConfirmedResolutionSizeY600 WindowPosX-1 …

鏈表知識回顧

類型&#xff1a;單鏈表&#xff0c;雙鏈表、循環鏈表 存儲&#xff1a;在內存中不是連續存儲 刪除操作&#xff1a;即讓c的指針指向e即可&#xff0c;無需釋放d&#xff0c;因為java中又內存回收機制 添加節點&#xff1a; 鏈表的構造函數 public class ListNode {// 結點…

詳解與FTP服務器相關操作

目錄 什么是FTP服務器 搭建FTP服務器相關 ?編輯 Unity中與FTP相關的類 上傳文件到FTP服務器 使用FTP服務器上傳文件的關鍵點 開始上傳 從FTP服務器下載文件到客戶端 使用FTP下載文件的關鍵點 開始下載 關于FTP服務器的其他操作 將文件的上傳&#xff0c;下載&…

Day92 | 靈神 | 二叉樹 路徑總和

Day92 | 靈神 | 二叉樹 路徑總和 112.路徑總和 112. 路徑總和 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 1.遞歸函數意義 如果在根節點為t的樹中可以找到長度為target的路徑就返回true&#xff0c;找不到就返回false 2.參數和返回值 bool tra(TreeNode …

探索鴻蒙應用開發:ArkTS應用執行入口揭秘

# 探索鴻蒙應用開發&#xff1a;ArkTS應用執行入口揭秘 在鴻蒙應用開發的領域中&#xff0c;ArkTS作為聲明式開發語言&#xff0c;為開發者們帶來了便捷與高效。對于剛接觸鴻蒙開發的小伙伴來說&#xff0c;搞清楚ArkTS應用程序的執行入口是邁向成功開發的關鍵一步。今天&…

【Web API系列】Web Shared Storage API之WorkletSharedStorage深度解析與實踐指南

前言 在現代Web開發領域&#xff0c;數據存儲與隱私保護的矛盾始終存在。傳統存儲方案如LocalStorage和Cookies面臨著日益嚴格的安全限制&#xff0c;而跨域數據共享的需求卻在持續增長。正是在這樣的背景下&#xff0c;Web Shared Storage API應運而生&#xff0c;其核心組件…

探索鴻蒙沉浸式:打造無界交互體驗

一、鴻蒙沉浸式簡介 在鴻蒙系統中&#xff0c;沉浸式是一種極具特色的設計理念&#xff0c;它致力于讓用戶在使用應用時能夠全身心投入到內容本身&#xff0c;而盡可能減少被系統界面元素的干擾。通常來說&#xff0c;就是將應用的內容區巧妙地延伸到狀態欄和導航欄所在的界面…

機器學習03——K近鄰

K近鄰算法學習筆記 一、算法簡介 K近鄰算法&#xff08;K - Nearest Neighbors&#xff0c;簡稱KNN&#xff09;是一種簡單而有效的分類和回歸算法。它的核心思想是“近朱者赤&#xff0c;近墨者黑”&#xff0c;即一個數據點的類別或值可以通過其周圍最近的K個鄰居來判斷。K…

序列化 反序列化實例

在Python中&#xff0c; pickle 模塊常用于實現對象的序列化和反序列化&#xff0c;以下是一個簡單的實例&#xff1a; import pickle # 定義一個類 class Person: def __init__(self, name, age): self.name name self.age age # 創建一個Person對象 person Person("…

代碼隨想錄算法訓練營第十九天

LeetCode題目: 77. 組合216. 組合總和 III17. 電話號碼的字母組合2537. 統計好子數組的數目(每日一題)516. 最長回文子序列1039. 多邊形三角剖分的最低得分543. 二叉樹的直徑124. 二叉樹中的最大路徑和2246. 相鄰字符不同的最長路徑 其他: 今日總結 往期打卡 77. 組合 跳轉: 7…

存算分離看場景

計算機行業是唯一一個比時裝行業概念更多的行業。概念頻出&#xff0c;最慢的話半年一定出一個&#xff0c;短的話半個月就能看到新的名詞和技術甚至是概念。 存算分離的概念 我第一次聽到存算分離時候還是從Hadoop上聽到的。然后就去問什么是存算分離。聽了講解以后&#xf…

MCP協議,.Net 使用示例

服務器端示例 基礎服務器 以下是一個基礎的 MCP 服務器示例&#xff0c;它使用標準輸入輸出&#xff08;stdio&#xff09;作為傳輸方式&#xff0c;并實現了一個簡單的回顯工具&#xff1a; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.H…

智能語音處理+1.5使用PocketSphinxshinx實現語音轉文本(100%教會)

歡迎來到智能語音處理系列的最后一篇文章&#xff0c;到這里,基本上語音處理是沒問題了. 第一篇:智能語音處理1.1下載需要的庫(100%實現)-CSDN博客 第二篇:智能語音識別1.2用SAPI實現文本轉語音(100%教會)-CSDN博客 第三篇:智能語音處理1.3用SpeechLib實現文本轉語音(100%教會)…

Kubernetes 節點摘除指南

目錄 一、安全摘除節點的標準流程 1. 確認節點名稱及狀態 2. 標記節點為不可調度 3. 排空&#xff08;Drain&#xff09;節點 4. 刪除節點 二、驗證節點是否成功摘除 1. 檢查節點列表 2. 檢查節點詳細信息 3. 驗證 Pod 狀態 三、徹底清理節點&#xff08;可選&#xf…

信息安全管理與評估2021年國賽正式卷答案截圖以及十套國賽卷

2021年全國職業院校技能大賽高職組 “信息安全管理與評估”賽項 任務書1 賽項時間 共計X小時。 賽項信息 賽項內容 競賽階段 任務階段 競賽任務 競賽時間 分值 第一階段 平臺搭建與安全設備配置防護 任務1 網絡平臺搭建 任務2 網絡安全設備配置與防護 第二…