当前位置: 首页 > 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越修越多,或者是问别…...

【JavaEE】-- HTTP

1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色&#xf…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

dify打造数据可视化图表

一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...