网络编程——TCP通信练习

目录

一、多发多收

二、接收和反馈

三、上传文件

四、解决上传文件名重复问题

五、上传文件多线程版

六、上传文件线程池版

七、B/S(接收浏览器的消息并打印)


一、多发多收

客户端:多次发送数据

服务器:接收多次数据,并打印

public class Client {public static void main(String[] args) throws IOException {Socket socket = new Socket("127.0.0.1", 10010);Scanner scanner = new Scanner(System.in);OutputStream os = socket.getOutputStream();while (true) {System.out.println("请输入内容:");String str = scanner.nextLine();os.write(str.getBytes());if ("拜拜".equals(str)) {break;}}socket.close();}
}public class Server {public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(10010);Socket socket = serverSocket.accept();BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));int len;while ((len = br.read()) != -1) {System.out.print((char) len);}socket.close();serverSocket.close();}
}

运行结果:

二、接收和反馈

客户端:发送一条数据,接收服务端反馈的消息并打印

服务器:接收数据并打印,再给客户端反馈消息

public class Client {public static void main(String[] args) throws IOException {Socket socket = new Socket("127.0.0.1", 10010);// 写出数据OutputStream os = socket.getOutputStream();String str = "客户端发送消息:见到你很开心!";os.write(str.getBytes());// 写出结束标记socket.shutdownOutput();// 读取数据BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));int len = 0;while ((len = br.read()) != -1) {System.out.print((char) len);}// 释放资源socket.close();}
}public class Server {public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(10010);Socket socket = serverSocket.accept();// 读取数据// 细节:read方法会从连接通道中读取数据//       但是,需要有一个结束标记,此处的循环才会停止,//       否则,程序就会一直停在read方法这里,等待读取下面的数据BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));int len;while ((len = br.read()) != -1) {System.out.print((char) len);}// 写出数据OutputStream os = socket.getOutputStream();String str = "服务器发送消息:有多开心?";os.write(str.getBytes());// 释放资源socket.close();serverSocket.close();}
}

运行结果:

三、上传文件

客户端:将本地文件上传到服务器,接收服务器的反馈。

服务器:接收客户端上传的文件,上传完毕之后给出反馈。

使用FileInputStream读取本地文件,使用FileOutputStream保存本地文件

public class Client {public static void main(String[] args) throws IOException {// 1.创建Socket对象,并连接服务器Socket socket = new Socket("127.0.0.1", 10020);// 2.读取本地文件中的数据,并写到服务器中BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());BufferedInputStream bis = new BufferedInputStream(new FileInputStream("mysocketnet/clientdir/a.jpg"));int len;byte[] bytes = new byte[1024];while ((len = bis.read(bytes)) != -1) {bos.write(bytes, 0, len);}// 向服务器写出结束标记socket.shutdownOutput();// 3.接收服务器的回写数据BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));String str = br.readLine();System.out.println(str);// 4.释放资源socket.close();}
}public class Server {public static void main(String[] args) throws IOException {// 1.创建对象并绑定端口ServerSocket serverSocket = new ServerSocket(10020);// 2.等待客户端来连接Socket socket = serverSocket.accept();// 3.读取客户端发送的数据,并将数据存入指定路径中BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("mysocketnet/serverdir/a.jpg"));int len;byte[] bytes = new byte[1024];while ((len = bis.read(bytes)) != -1) {bos.write(bytes, 0, len);}// 4. 服务器向客户端回写数据BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));bw.write("服务器向客户端发送消息:文件已接收!");bw.newLine();bw.flush();// 5.释放资源socket.close();serverSocket.close();}
}

运行结果:

四、解决上传文件名重复问题

Client代码无需修改

public class Server {public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(10020);Socket socket = serverSocket.accept();BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());// 方式一:使用毫秒值拼接
//        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("mysocketnet\\serverdir" + File.separator + System.currentTimeMillis() + ".jpg"));// 方式二:使用UUID拼接String name = UUID.randomUUID().toString().replace("-", "");BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("mysocketnet\\serverdir" + File.separator + name + ".jpg"));int len;byte[] bytes = new byte[1024];while ((len = bis.read(bytes)) != -1) {bos.write(bytes, 0, len);}BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));bw.write("文件上传成功!");bw.newLine();bw.flush();socket.close();serverSocket.close();}
}

运行结果:

五、上传文件多线程版

让服务器不停止,能接收很多用户上传的图片,可以使用(循环+多线程)

Client代码无需修改 

public class MyRunnable implements Runnable {public Socket socket;public MyRunnable(Socket socket) {this.socket = socket;}@Overridepublic void run() {try {BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());String name = UUID.randomUUID().toString().replace("-", "");BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("mysocketnet\\serverdir" + File.separator + name + ".jpg"));int len;byte[] bytes = new byte[1024];while ((len = bis.read(bytes)) != -1) {bos.write(bytes, 0, len);}BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));bw.write("文件上传成功!");bw.newLine();bw.flush();} catch (IOException e) {throw new RuntimeException(e);} finally {if (socket != null) {try {socket.close();} catch (IOException e) {throw new RuntimeException(e);}}}}
}public class Server {public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(10020);while (true) {// 等待客户端来连接Socket socket = serverSocket.accept();// 一个用户对应服务端的一条线程new Thread(new MyRunnable(socket)).start();}}
}

先开启Server,每开启一次Client,就会创建一个线程,文件也会上传

运行结果:

六、上传文件线程池版

频繁创建线程并销毁非常浪费系统资源,所以需要用线程池优化。

只需要修改Server即可: 

public class Server {public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(10020);// 创建线程池对象ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(3, // 核心线程数量16, // 线程池总大小60, // 空闲时间TimeUnit.SECONDS, // 空闲时间(单位)new ArrayBlockingQueue<>(2), // 队列Executors.defaultThreadFactory(), // 线程工厂,让线程池如何创建线程对象new ThreadPoolExecutor.AbortPolicy() // 阻塞队列);while (true) {Socket socket = serverSocket.accept();
//            new Thread(new MyRunnable(socket)).start();poolExecutor.submit(new MyRunnable(socket));}}
}

运行结果:

七、B/S(接收浏览器的消息并打印)

客户端:不需要写

服务器:接收数据并打印

public class Server {public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(10010);Socket socket = serverSocket.accept();BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));int len;char[] chars = new char[1024];while ((len = br.read(chars)) != -1) {System.out.println(new String(chars, 0, len));br.readLine();}socket.close();serverSocket.close();}
}

浏览器输入:http://localhost:10010/

运行结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/10161.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Selenium自动化测试 —— 模拟鼠标键盘的操作事件

软件测试资料领取&#xff1a;[内部资源] 想拿年薪40W的软件测试人员&#xff0c;这份资料必须领取~ 软件测试面试刷题工具&#xff1a;软件测试面试刷题【800道面试题答案免费刷】 鼠标操作事件 在实际的web产品测试中&#xff0c;对于鼠标的操作&#xff0c;不单单只有clic…

线性回归模型

线性回归模型 代价函数 梯度下降 学习率 梯度下降的收敛与调优 梯度下降的收敛性依赖于以下因素&#xff1a; 学习率的选择&#xff1a;合适的学习率能够确保稳定收敛&#xff0c;过大或过小的学习率可能会导致收敛不稳定或效率低下。数据的特征&#xff1a;数据的规模和特征…

书生大模型基础岛第一关书生大模型全链路开源体系

本文档相当于是对书生*浦语的了解文档 官网&#xff1a; https://internlm.intern-ai.org.cn/ github: https://github.com/internLM/ 开源之路&#xff1a; 2023.7.6 InterLM-7B2023.9.20 InterLM-20B2024.1.17 InternLM22024.7.4 InternLM2.5 性能天梯&#xff1a; InternL…

01OpenGL基本学习

文章目录 第一节1、概念立即模式vs核心模式 2、问题 第二节1、三维坐标系![三维坐标系](https://i-blog.csdnimg.cn/direct/0703ba6b68914b08b1d14b936ccd862d.png)2、什么是模型&#xff1f;3、什么是颜色&#xff1f;4、材质 第三节渲染管线第四节GLAD配置流程1、为什么需要G…

测试-请求特定资源使用Postman工具(3)

目录 前言 实操 开发者工具 前言 介绍过&#xff0c;就不再介绍了&#xff0c;只需要知道它是一个网络请求的工具就行了 实操 开发者工具 这里我们还需要借助开发者工具来帮助我们进行资源的请求&#xff0c;这里用 百度一下 进行测试 如下是 百度一下 的首页 右键打开…

Foliate:沉浸式阅读!!!

项目简介 Foliate 是一款开源的电子书阅读器&#xff0c;专为现代操作系统设计&#xff0c;提供了优雅且实用的阅读体验。它支持多种电子书格式&#xff0c;包括 EPUB、Mobipocket、Kindle、FB2、CBZ 和 PDF&#xff0c;让用户能够以分页或滚动模式阅读。Foliate 允许用户自定义…

打包18款AI营销神器,批量运营项目收藏必备!

淘金的不如卖铲子的&#xff0c;AI工具的应用越来越普及&#xff0c;这也让很多原本淘金的人都来卖铲子。如果自己能有很好的铲子&#xff0c;自己也会淘金&#xff0c;就可以既能卖铲子赚钱&#xff0c;也能掏金赚钱。 还有两天就是双十一了&#xff0c;各种AI工具&#xff0…

【MyBatis源码】SQL 语句构建器AbstractSQL

文章目录 介绍org.apache.ibatis.jdbc.SQLSQL类使用示例SelectProvider搭配动态SQLAbstractSQL类源码分析 介绍 当我们需要使用Statement对象执行SQL时&#xff0c;SQL语句会嵌入Java代码中。SQL语句比较复杂时&#xff0c;我们可能会在代码中对SQL语句进行拼接&#xff0c;查…

Vue2进阶

1.el安装 官网地址 Element - The worlds most popular Vue UI frameworkElement&#xff0c;一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库https://element.eleme.cn/#/zh-CN 安装 npm install element-ui -S 引入组件&#xff08;在 main.js&#xf…

案例:三次锁定(下)

第二步: 在 Form1.cs 中完成以下代码 using Dome16_三次锁定.service; using Dome16_三次锁定.service.serviceimpl; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using Sys…

前端学习笔记—Vue3特性

一、 Vue3与Vite构建工具简介 image.png image.png image.png image.png Vite构建工具&#xff08;其他的打包工具有webpack&#xff0c;grunt&#xff0c;gulp&#xff09; image.png image.png 构建 二、创建Vue3项目 vite在TypeScript结合使用上&#xff0c;直接开箱即用&am…

iOS 去掉URL里面的百分号符号

遇到这个一段字符串 “publicId2030095197043302&publicBizTypeCONTENT_USER&chInfoch_life__chsub_Ndiscovery.featured&logoUrlhttps%3A%2F%2Fmdn.alipayobjects.com%2Fopen_content%2Fafts%2Fimg%2FA*_SUKQodfigcAAAAAAAAAAAAAfVx1AQ%2Foriginal&publicName…

node.js安装配置(Windows)

1、下载 CNPM Binaries Mirror 2、安装 3、验证 win R 进入cmd 4、配置环境变量 4.1、创建两个文件夹 4.2、安装目录进入cmd(配置全局属性) 配置两个命令&#xff1a; npm config set prefix "D:\liyunqing\nodejs\node_global"npm config set cache "D:\l…

jdbc中预防SQL攻击

目录 展示SQL攻击 举一个出现sql 攻击的例子 SQL攻击的原因 分析原因 阻止SQL攻击 PreparedStatement的含义 使用PreparedStatement的原因 步骤如下 注意 总结 展示SQL攻击 举一个出现sql 攻击的例子 假设我们在做登录业务时&#xff0c;思路是这样的&#xff1a; 首…

30.1 时序数据库TSDB的典型特点

本节重点介绍 : db-ranking网站对db进行排名时序数据特点时序数据库特点时序数据库遇到的挑战开源时间序列数据库 db-ranking 一个神奇的网站 https://db-engines.com/en/ranking 时序数据ranking https://db-engines.com/en/ranking/timeseriesdbms 排名方法 https://db-en…

14:00面试,14:06就出来了,问的问题过于变态了。。。

我从一家小公司转投到另一家公司&#xff0c;期待着新的工作环境和机会。然而&#xff0c;新公司的加班文化让我有些始料未及。虽然薪资相对较高&#xff0c;但长时间的工作和缺乏休息使我身心俱疲。 就在我逐渐适应这种高强度的工作节奏时&#xff0c;公司突然宣布了一则令人…

架构师之路-学渣到学霸历程-49

实现不同终端的跳转实验 今天分享一下&#xff1a; nginx的跳转&#xff1a;主要看你的访问是手机还是网页&#xff1b;于是就有这个跳转的功能&#xff1b; 1、基础的环境部署 安装好nginx&#xff08;这里最好的就是干净的环境&#xff09;创建两个server&#xff1b;用于…

RK3568笔记1:BootRom

BootRom是瑞芯微公司在生产的CPU时&#xff0c;存储在内部flash中的一段固件代码&#xff0c;用于初始化硬件和启动系统。 RK3568 处理器也具备 BootROM。这是存储在处理器内部的只读存储器 (ROM) 中的一段代码&#xff0c;通常是不可修改的&#xff0c;其主要功能是在设备加电…

DataWind将字符串数组拆出多行的方法

摘要&#xff1a; 可视化建模中先将字符串split为array再用explode(array)即可 可视化建模 进入“可视化建模”页面 1.1 新建任务 如果团队内没有可视化建模任务。请点击“新建任务”&#xff0c;输入名称并确定。 1.2 建立数据连接 在左边栏中选择“数据连接”&#xff0c…

2024年【电工(中级)】考试及电工(中级)考试报名

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 电工&#xff08;中级&#xff09;考试参考答案及电工&#xff08;中级&#xff09;考试试题解析是安全生产模拟考试一点通题库老师及电工&#xff08;中级&#xff09;操作证已考过的学员汇总&#xff0c;相对有效帮…