当前位置: 首页 > news >正文

JavaEE|网络编程之套接字 TCP

文章目录

    • 一、ServerSocket API
      • 构造方法
      • 常用方法
    • 二、Socket API
      • 构造方法
      • 常用方法
      • 注意事项
    • 三、TCP中的长短连接
    • E1:一发一收(短连接)
    • E2:请求响应(短连接)
    • E3:多线程下的TCP回响服务器

说明:这部分说实话有点懵,理解上有点吃力,这里暂时先放到这,有新的认识再进行回来修改。

一、ServerSocket API

它是创建TCP服务端Socket的api

构造方法

方法签名说明
ServerSocket(int port)创建一个服务端流套接字Socket,并绑定到指定端口

给服务器绑定端口。

常用方法

方法签名说明
Socket accept()开始监听创建时绑定的端口,有客户端连接后,返回一个服务端Socket 对象,并基于该Socket建立与客户端的连接,否则阻塞等待
void close()关闭此套接字

二、Socket API

即会给客户端和服务器使用。

构造方法

方法签名说明
Socket(String host, int port)创建一个客户端流套接字Socket,并与对应IP的主机上,对应端口的 进程建立连接

常用方法

方法签名说明
InetAddress getInetAddress()返回套接字所连接的地址
InputStream getInputStream()返回此套接字的输入流
OutputStream getOutputStream()返回此套接字的输出流

TCP中,socket对象,对于服务器而言,是靠accpet返回的;对于客户端而言,是靠代码内部构造的。

注意事项

  • TCP 中的ClientSocket的socket对象需要释放,而前边Server对象和UDP的都没释放,为什么这里需要呢?原因有二

    1.这里的socket声明周期比较短,UDP里边的和TCP服务器里的是要跟随整个程序的。

    2.这里的socket对象可能比较多,可能会把文件描述符表占满。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ln3qbRpA-1676879262621)(F:\typora插图\image-20230220145615579.png)]

outputStream相当于一个文件描述符(一个socket文件),通过这个对象就可以往这个文件描述符中写数据。

OutStream自身方法不方便写字符串,把流进行转换一下,用一个PW对象来表示(对应的文件还是通过一个)。

不过使用PW(打印流)写,往一个地方写,只不过的写的更方便了。

println是写,往控制台上,往网卡上……

三、TCP中的长短连接

客户端socket对象构造,会触发tcp建立连接

短连接:每次接收到数据并返回响应后,都关闭连接,即是短连接。也就是说,短连接只能一次收发数据。

长连接:不关闭连接,一直保持连接状态,双方不停的收发数据,即是长连接。也就是说,长连接可以多次收发数据。

两者区别如下:
建立连接、关闭连接的耗时:短连接每次请求、响应都需要建立连接,关闭连接;而长连接只需要第一次建立连接,之后的请求、响应都可以直接传输。相对来说建立连接,关闭连接也是要耗时的,长连接效率更高。

主动发送请求不同:短连接一般是客户端主动向服务端发送请求;而长连接可以是客户端主动发送请求,也可以是服务端主动发。

两者的使用场景有不同:短连接适用于客户端请求频率不高的场景,如浏览网页等。长连接适用于客户端与服务端通信频繁的场景,如聊天室,实时游戏等。

E1:一发一收(短连接)

服务器端代码、客户端代码

public class Code04_TCPEchoServer {private ServerSocket serverSocket=null;//这种可以返回Socket类型的对象public Code04_TCPEchoServer(int port) throws IOException {serverSocket=new ServerSocket(port);}public void start() throws IOException {System.out.println("启动服务器成功!");while(true){Socket clientSocket=serverSocket.accept();//效果是接收连接//前提是客户端来建立连接:若有则连接,若无,则阻塞等待//建立连接processConnection(clientSocket);}}//使用这个方法来处理一个连接//这个连接对应到一个客户端,但是这里可能会设计到多次交互private void processConnection(Socket clientSocket) {System.out.printf("[%s:%d] 客户端上线!",clientSocket.getInetAddress().toString(),clientSocket.getPort());//基于上述socket进行通信try(InputStream inputStream=clientSocket.getInputStream();//由于要处理多个请求,所以也是使用循环来进行OutputStream outputStream=clientSocket.getOutputStream()){while(true){//1.读取请求Scanner scanner=new Scanner(inputStream);if(!scanner.hasNext()){
//                   System.out.println("当前连接已关闭!");System.out.printf("[%s:%d] 客户端下线!",clientSocket.getInetAddress().toString(),clientSocket.getPort());break;}System.out.println();String request=scanner.next();//next读到换行符/其他空白符结束,但是不包含//2.根据请求构造响应String response=process(request);//3.返回响应结果PrintWriter printWriter = new PrintWriter(outputStream);printWriter.println(response);// 此处加上 flush 保证数据确实发送出去了.printWriter.flush();//4.打印中间结果System.out.printf(response);}} catch (IOException e) {e.printStackTrace();}finally {try{clientSocket.close();} catch (IOException e) {e.printStackTrace();}}}public String process(String request) {return request;}public static void main(String[] args) throws IOException {Code04_TCPEchoServer tcpEchoServer=new Code04_TCPEchoServer(1200);tcpEchoServer.start();}
}
public class Code05_TCPEchoClient {private Socket socket = null;//这是用来接收服务器的socket对象public Code05_TCPEchoClient(String serverIp, int serverPort) throws IOException {// Socket 构造方法, 能够识别 点分十进制格式的 IP 地址. 比 DatagramPacket 更方便.// new 这个对象的同时, 就会进行 TCP 连接操作.socket = new Socket(serverIp, serverPort);}public void start() {System.out.println("客户端启动!");Scanner scanner = new Scanner(System.in);try (InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream()) {while (true) {// 1. 先从键盘上读取用户输入的内容System.out.print("> ");String request = scanner.next();if (request.equals("exit")) {System.out.println("bye");break;}// 2. 把读到的内容构造成请求, 发送给服务器.PrintWriter printWriter = new PrintWriter(outputStream);printWriter.println(request);// 此处加上 flush 保证数据确实发送出去了.printWriter.flush();// 3. 读取服务器的响应Scanner respScanner = new Scanner(inputStream);String response = respScanner.next();// 4. 把响应内容显示到界面上System.out.println(response);}} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) throws IOException {Code05_TCPEchoClient client = new Code05_TCPEchoClient("127.0.0.1", 1200);client.start();}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5BGi1OmX-1676879262623)(F:\typora插图\image-20230220151140134.png)]

这里不用println写是不行的,原因如下:

TCP协议是面向字节流的协议。接收方一次读多少个字节需要我们在数据传输中进行明确约定。

这里的next和println是相互制约的。next在等请求中的结束符。

enter是换行符,但是这里按下enter是把next里内容送上去,并没有把换行符读到。

E2:请求响应(短连接)

与UDP类似,这里是在服务器处,加上了相关的业务逻辑。

E3:多线程下的TCP回响服务器

public class Code04_TCPEchoServer {private ServerSocket serverSocket=null;//这种可以返回Socket类型的对象public Code04_TCPEchoServer(int port) throws IOException {serverSocket=new ServerSocket(port);}public void start() throws IOException {System.out.println("启动服务器成功!");ExecutorService threadPool= Executors.newCachedThreadPool();while(true){Socket clientSocket=serverSocket.accept();//效果是接收连接//前提是客户端来建立连接:若有则连接,若无,则阻塞等待//建立连接threadPool.submit(()->{processConnection(clientSocket);});}}//使用这个方法来处理一个连接//这个连接对应到一个客户端,但是这里可能会设计到多次交互private void processConnection(Socket clientSocket) {System.out.printf("[%s:%d] 客户端上线!",clientSocket.getInetAddress().toString(),clientSocket.getPort());//基于上述socket进行通信try(InputStream inputStream=clientSocket.getInputStream();//由于要处理多个请求,所以也是使用循环来进行OutputStream outputStream=clientSocket.getOutputStream()){while(true){//1.读取请求Scanner scanner=new Scanner(inputStream);if(!scanner.hasNext()){
//                   System.out.println("当前连接已关闭!");System.out.printf("[%s:%d] 客户端下线!",clientSocket.getInetAddress().toString(),clientSocket.getPort());break;}System.out.println();String request=scanner.next();//next读到换行符/其他空白符结束,但是不包含//2.根据请求构造响应String response=process(request);//3.返回响应结果PrintWriter printWriter = new PrintWriter(outputStream);printWriter.println(response);// 此处加上 flush 保证数据确实发送出去了.printWriter.flush();//4.打印中间结果System.out.printf(response);}} catch (IOException e) {e.printStackTrace();}finally {try{clientSocket.close();} catch (IOException e) {e.printStackTrace();}}}public String process(String request) {return request;}public static void main(String[] args) throws IOException {Code04_TCPEchoServer tcpEchoServer=new Code04_TCPEchoServer(1200);tcpEchoServer.start();}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YpC6p15H-1676879262624)(F:\typora插图\image-20230220154240639.png)]

1.修改允许多个客户端其中之后服务器只显示一个客户端上线

2.客户端1发送消息可以,客户端2发送消息没有响应【占线】

一旦客户端1一下线,客户端2立即上线。

为什么?这里需要我们结合服务器的启动代码分析

这里是多线程的问题。(其实还是有点不太懂,但具体是哪里说不上来)

当有客户端连上服务器后,代码就执行到了processConnection这个方法里的while循环,这时另一个客户端再次尝试发送请求,由于此时调到这里循环不结束,processConnection方法就结束不了,进一步也就无法再次accept了

解决办法:使用多线程。

主线程。专门负责accpet,每次收到一个连接,创建新线程,由这个新线程负责这个新的客户端

这里因为有可能频繁的申请释放线程,所以这里我们采用的是线程池。

一般的版本:

Thread t=new Thread(()->{processConnection(clientSocket);
});
t.start();

说明:虽然线程池的加入会一定程度上解决多个客户端的需要同时启动的效率问题。但是线程的创建与销毁始终还是比较耗时间的。一旦客户端的数量激增接近阈值,还是存在的问题的。
对此,操作系统提供了io多路复用的机制缓解。
【基于BIO(同步阻塞IO)的长连接会一直占用系统资源。对于并发要求很高的服务端系统来说,这样的消耗是不能承受的。

实际应用时,服务端一般是基于NIO(即同步非阻塞IO)来实现长连接,性能可以极大的提升。】

相关文章:

JavaEE|网络编程之套接字 TCP

文章目录一、ServerSocket API构造方法常用方法二、Socket API构造方法常用方法注意事项三、TCP中的长短连接E1:一发一收(短连接)E2:请求响应(短连接)E3:多线程下的TCP回响服务器说明:这部分说实话有点懵&a…...

Robot Framework自动化测试---元素定位

不要误认为Robot framework 只是个web UI测试工具,更正确的理解Robot framework是个测试框架,之所以可以拿来做web UI层的自动化是国为我们加入了selenium2的API。比如笔者所处工作中,更多的是拿Robot framework来做数据库的接口测试&#xf…...

ASP.NET Core中的路由

传统路由 app.MapControllerRoute( name: "default", pattern: "{controllerHome}/{actionIndex}/{id?}"); MapControllerRoute用于创建单个路由。 单个路由命名为 default 路由 。大多数具有控制器和视图的应用都使用类似 default 路由的路由模板。 之所…...

VBA提高篇_26 Textbox多行_ListBox_ComboBox

文章目录1. 文本框多行换行2. ListBox: 列表框2.1 列表框中添加条目的三种方法:3. ComboBox 组合框: 属性方法等同于以上ListBox1. 文本框多行换行 MultiLine: 控制文本框多行自动换行() Enterkeybehevior: True 代表允许在文本框中使用回车键换行 WordWrap: True 代表自动换…...

python环境配置

python环境配置一、ADB环境配置1、ADB下载路径:2、点击下载3、解压并放到本地磁盘4、配置ADB环境变量二、Python环境配置1、Python下载路径:2、点击下载(默认下载最新的)3、解压并放到本地磁盘4、配置Python环境变量5、配置pip环境变量三、Pycharm安装1、pycharm下载路径:2、点…...

集算器连接外部库

1. 配置jar包将以下jar包从报表的类路径(【安装根目录】\report\lib或【安装根目录】\report\web\webapps\demo\WEB-INF\lib)中拷贝到集算器目录(【安装根目录】\esProc\ extlib\mongoCli);润乾外部库核心jar为:scu-mo…...

力扣刷题|216.组合总和 III、17.电话号码的字母组合

文章目录LeetCode 216.组合总和题目链接🔗思路LeetCode 17.电话号码的字母组合题目链接🔗思路LeetCode 216.组合总和 题目链接🔗 LeetCode 216.组合总和 思路 本题就是在[1,2,3,4,5,6,7,8,9]这个集合中找到和为n的k个数的组合。 相对于7…...

机器学习笔记之谱聚类(一)k-Means聚类算法介绍

机器学习笔记之谱聚类——K-Means聚类算法介绍引言回顾:高斯混合模型聚类任务基本介绍距离计算k-Means\text{k-Means}k-Means算法介绍k-Means\text{k-Means}k-Means算法示例k-Means\text{k-Means}k-Means算法与高斯混合模型的关系k-Means\text{k-Means}k-Means算法的…...

云原生周刊 | 2023 年热门:云 IDE、Web Assembly 和 SBOM | 2023-02-20

在 CloudNative SecurityCon 上,云原生计算基金会的首席技术官 Chris Aniszczyk 在 The New Stack Makers 播客的这一集中强调了 2023 年正在形成几个趋势: 随着 GitHub 的 Codespaces 平台通过集成到 GitHub 服务中获得认可,云 IDE&#xf…...

python 打包EXE

注: 从个人博客园 移植而来 环境: Windows7 Python 2.7 参考: 使用pyinstaller打包python程序 Pyinstaller 打包发布经验总结 Using PyInstaller 简介 使用python引用第三方的各种模块编写一个工具后,如果想发给其他人&…...

CANopen概念总结、心得体会

NMT网络管理报文: NMT 主机和 NMT 从机之间通讯的报文就称为 NMT 网络管理报文。常见报文说明: 0101---------------网络报文发送Nmt_Start_Node,让电机进入OP模式(此时还不会发送同步信号) setState(d, Operational)------------------开启…...

【2】MYSQL数据的导入与导出

文章目录 MYSQL-库(相同库名称)的导入导出MYSQL-库(不同库名称)的导入导出MYSQL-表的导入导出MYSQL-表的指定查询记录导入导出前提: 客户端工具是:SQLyog MYSQL-库(相同库名称)的导入导出 1、选中指定库——右键,选择【将数据库复制到不同的主机/数据库】 2、选中指…...

Kaggle系列之CIFAR-10图像识别分类(残差网络模型ResNet-18)

CIFAR-10数据集在计算机视觉领域是一个很重要的数据集,很有必要去熟悉它,我们来到Kaggle站点,进入到比赛页面:https://www.kaggle.com/competitions/cifar-10CIFAR-10是8000万小图像数据集的一个子集,由60000张32x32彩…...

ESP-C3入门11. 创建最基本的HTTP请求

ESP-C3入门11. 创建最基本的HTTP请求一、menuconfig配置二、配置 CMakeLists1. 设置项目的额外组件目录2. 设置头文件搜索目录三、在 ESP32 上执行 HTTP 请求的基本步骤1. 创建 TCP 连接2. 设置 HTTP 请求3. 发送 HTTP 请求4. 接收 HTTP 响应5. 处理 HTTP 响应6. 关闭 TCP 连接…...

K8S+Jenkins+Harbor+Docker+gitlab集群部署

K8SJenkinsHarborDockergitlab服务器集群部署 目录K8SJenkinsHarborDockergitlab服务器集群部署1.准备以下服务器2.所有服务器统一处理执行2.1 关闭防火墙2.2 关闭selinux2.3 关闭swap(k8s禁止虚拟内存以提高性能)2.4 更新yum (看需要更新)2.5 时间同步2…...

看见统计——第四章 统计推断:频率学派

看见统计——第四章 统计推断:频率学派 接下来三节的主题是中心极限定理的应用。在不了解随机变量序列 {Xi}\{X_i\}{Xi​} 的潜在分布的情况下,对于大样本量,中心极限定理给出了关于样本均值的声明。例如,如果 YYY 是一个 N(0&am…...

2023年2月访问学者博士后热门国家出入境政策变化汇总

近期关于出国的咨询量日益增多,出入境政策也是其中之一。所以本期知识人网小编汇总了最新访问学者和博士后关注的热门国家及地区入境政策变化,提供给大家。目前各国入境政策大致分为三种:一、 无法入境的国家如:摩洛哥、朝鲜等。二…...

“离开浪浪山”是假象,80%年轻人下班后还在学习,真实是想先上个山。

最近,又有一个关于年轻人与职场的新词横空出世—— 浪浪山。 什么是浪浪山? 每个人心中都有一座浪浪山。 浪浪山,其实是人生的一种状态,步入社会时满腔热血,然而很快就被现实给修理了一顿;想要辞职不干出去…...

Kotlin 33. CompileSdkVersion 和 targetSdkVersion 有什么区别?

CompileSdkVersion 和 targetSdkVersion 有什么区别? 在 build.gradle (Module) 文件中,我们通常会看到 CompileSdkVersion 和 targetSdkVersion 的使用,比如下面是一个完整的 build.gradle (Module) 文件: plugins {id com.and…...

实用调试技巧——“C”

各位CSDN的uu们你们好呀,今天小雅兰的内容是实用调试技巧,其实小雅兰一开始,也不知道调试到底是什么,一遇到问题,首先就是观察程序,改改这里改改那里,最后导致bug越修越多,或者是问别…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...