【JavaEE】网络编程——TCP

在这里插入图片描述
🤡🤡🤡个人主页🤡🤡🤡
🤡🤡🤡JavaEE专栏🤡🤡🤡

文章目录

  • 前言
  • 1.网络编程套接字
    • 1.1流式套接字(TCP)
      • 1.1.1特点
      • 1.1.2编码
        • 1.1.2.1ServerSocket
        • 1.1.2.2Socket
        • 1.1.2.3实现一个TCP(7*24)回显服务器
        • 1.1.2.4实现一个TCP的客户端
        • 1.1.2.5实现一个TCP字典翻译服务器

前言

网络编程的目的是为了跨主机通信,socket==》操作系统提供的网络编程的API就称为"socket"API

1.网络编程套接字

TCP和UDP都是传输层协议,都是给应用层提供服务的,由于这两个协议特点差异非常打,因此我们就需要两套API来分别表示。

1.1流式套接字(TCP)

1.1.1特点

  1. 有连接:在数据传输开始前,需要通信双方建立一个专用的通道,数据传输完成后再关闭连接,好比打电话,需要双方都接通才可以对话
  2. 可靠传输:在传输数据的时候,尽可能的将数据传输到达对方,并不是100%
  3. 面向字节流:面向对象是字节,在读写的操作会非常灵活。
  4. 全双工:一条链路中,能够进行双向通信。

1.1.2编码

TCP中的socket API重点是两个类:ServerSocket和Socket。

1.1.2.1ServerSocket

ServerSocket这个类主要是用于TCP的服务器的,里面有一个非常重要的方法accept,这个方法主要是让服务器与客户端建立连接的方法,没有建立连接是无法让服务器与客户端双方互相通信。

1.1.2.2Socket

Socket这个类是既可以用于服务器中也可以用于客户端中,这个类主要是以字节的形式将数据存储和传输的,所以这个类中提供的两种方法可以类比文件操作中的方法,这个类提供getInputStream()和getOutputStream()
前者是相当于文件操作中的读操作,后者类比于写操作,只是这里的操作对象换成了服务器与客户端了。

1.1.2.3实现一个TCP(7*24)回显服务器

在这里由于getInputStream()数据都是以字节的形式存在和传输的,但在处理响应的时候会转化为字符串的形式,为了不这么麻烦的去转化,我们就用Scanner来作为读操作,将getInputStream实现的对象放入Scanner构造方法中,让Scanner内部将字节数据转化为字符串的形式,这样就避免了之后程序中许多转化。

public class tcpEchoServer {private ServerSocket serverSocket = null;public tcpEchoServer(int port) throws IOException {serverSocket = new ServerSocket(port);}public void start() throws IOException {System.out.println("服务器启动!!!");//将服务器与客户端进行连接,连接成功返回一个Socket对象,后续服务器对客户端的操作都基于这个对象while(true) {Socket clientSocket = serverSocket.accept();//创建一个方法来操作每一个客户端与服务器的联系processConnection(clientSocket);}}public void processConnection(Socket clienSocket) throws IOException {//打印一个客户端上线的日志System.out.printf("[%s:%d]客户端上线!\n",clienSocket.getInetAddress(),clienSocket.getPort());//1.接收客户端发送过来的信息和并解析try(InputStream inputStream = clienSocket.getInputStream();OutputStream outputStream = clienSocket.getOutputStream()) {//接收客户端发送过来的请求并解析(相当于从客户端读到服务器),用到Scanner的原因是由于InputStream读取的数据是字节的形式,//后续处理数据的时候还是要将数据从字节形式转化为字符串,而Scanner内部可以帮我们直接转化。Scanner scanner = new Scanner(inputStream);//由于需要处理客户端不断发送过来的请求,我们就需要一个while循环while(true) {//处理客户端那边不发送请求的情况if(!scanner.hasNext()) {System.out.printf("[%s:%d]客户端下线!\n",clienSocket.getInetAddress(),clienSocket.getPort());break;}//将从客户端接收过来的数据赋值到request中,为之后处理数据做铺垫//这里的scanner.next()需要读到空白符才会停止,所以为了区分每一份的应用层的数据报,所以我们可以在客户端手动添加空白符,//来控制每一份的应用层数据报String request = scanner.next();//2.计算响应,由于这是一个回显服务器,所以我们呢不需要对响应做处理,请求什么就返回什么响应String response = process(request);//3.将计算好的响应传回客户端(相当与将数据写回客户端)outputStream.write(response.getBytes(),0,response.getBytes().length);//4.打印服务器日志System.out.printf("[%s:%d]res = %s,resp = %s\n",clienSocket.getInetAddress(),clienSocket.getPort(),request,response);}} catch (IOException e) {throw new RuntimeException(e);}finally {clienSocket.close();}}private String process(String request) {return request + "\n";}public static void main(String[] args) throws IOException {tcpEchoServer server = new tcpEchoServer(9999);server.start();}
}

在这里插入图片描述
程序走到这里有两种情况:

  1. 服务器与客户端双方之间的连接还在,但是客户端并没有发送请求,则会在此处进行阻塞,直到客户端发送请求过来,才会解除阻塞
  2. 服务器与客户端双方之间的连接已经断开了,那么直接就执行了if中的语句
    关于if中的scanner怎么判断连接存在还是不存在的情况,scanner是无法判断的,scnner只有阻塞作用,判断连接是否存在是scoket来判断的。
1.1.2.4实现一个TCP的客户端
public class tcpEchoClient {public Socket socket = null;public tcpEchoClient(String serverIp,int serverProt) throws IOException {socket = new Socket(serverIp,serverProt);}public void start() throws IOException {//打印日志System.out.println("客户端启动!");//1.从控制台读取Scanner scanner = new Scanner(System.in);try (InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream()){Scanner scannerNetwork = new Scanner(inputStream);while(true) {System.out.println("请输入你的请求:");String request = scanner.next();//与服务器规定的规则相对应request += "\n";//2.发送请求到服务器(写入服务器中)outputStream.write(request.getBytes());//3.接收从服务器发送过来的响应(从服务器将响应读入客户端)if(!scannerNetwork.hasNext()) {break;}String response = scannerNetwork.next();//4.将回应打印到控制台System.out.println(response);}}}public static void main(String[] args) throws IOException {tcpEchoClient client = new tcpEchoClient("127.0.0.1",9999);client.start();}
}

上述的服务器还是存在一些问题的,比如:无法处理多个客户端同时来访问服务器,解决这个问题可以使用多线程让一个主线程来创建多个服务器与客户端连接的对象,然后再用其他线程来给客户端提供服务。

public class tcpEchoServer {private ServerSocket serverSocket = null;public tcpEchoServer(int port) throws IOException {serverSocket = new ServerSocket(port);}public void start() throws IOException {System.out.println("服务器启动!!!");ExecutorService pool = Executors.newCachedThreadPool();//将服务器与客户端进行连接,连接成功返回一个Socket对象,后续服务器对客户端的操作都基于这个对象while(true) {Socket clientSocket = serverSocket.accept();pool.submit(new Runnable() {@Overridepublic void run() {try {processConnection(clientSocket);} catch (IOException e) {throw new RuntimeException(e);}}});}}public void processConnection(Socket clienSocket) throws IOException {//打印一个客户端上线的日志System.out.printf("[%s:%d]客户端上线!\n",clienSocket.getInetAddress(),clienSocket.getPort());//1.接收客户端发送过来的信息和并解析try(InputStream inputStream = clienSocket.getInputStream();OutputStream outputStream = clienSocket.getOutputStream()) {//接收客户端发送过来的请求并解析(相当于从客户端读到服务器),用到Scanner的原因是由于InputStream读取的数据是字节的形式,//后续处理数据的时候还是要将数据从字节形式转化为字符串,而Scanner内部可以帮我们直接转化。Scanner scanner = new Scanner(inputStream);//由于需要处理客户端不断发送过来的请求,我们就需要一个while循环while(true) {//处理客户端那边不发送请求的情况if(!scanner.hasNext()) {System.out.printf("[%s:%d]客户端下线!\n",clienSocket.getInetAddress(),clienSocket.getPort());break;}//将从客户端接收过来的数据赋值到request中,为之后处理数据做铺垫//这里的scanner.next()需要读到空白符才会停止,所以为了区分每一份的应用层的数据报,所以我们可以在客户端手动添加空白符,//来控制每一份的应用层数据报String request = scanner.next();//2.计算响应,由于这是一个回显服务器,所以我们呢不需要对响应做处理,请求什么就返回什么响应String response = process(request);//3.将计算好的响应传回客户端(相当与将数据写回客户端)outputStream.write(response.getBytes(),0,response.getBytes().length);//4.打印服务器日志System.out.printf("[%s:%d]res = %s,resp = %s\n",clienSocket.getInetAddress(),clienSocket.getPort(),request,response);}} catch (IOException e) {throw new RuntimeException(e);}finally {clienSocket.close();}}private String process(String request) {return request + "\n";}public static void main(String[] args) throws IOException {tcpEchoServer server = new tcpEchoServer(9999);server.start();}
}
1.1.2.5实现一个TCP字典翻译服务器
public class tcpDictServer extends tcpEchoServer{HashMap<String,String> map = null;public tcpDictServer(int port) throws IOException {super(port);map = new HashMap<>();map.put("server","服务\n");map.put("client","客户端\n");map.put("cat","🐱\n");map.put("dog","🐕\n");map.put("pig","🐖\n");}@Overridepublic String process(String request) {return map.getOrDefault(request,"该词汇没有查询到");}public static void main(String[] args) throws IOException {tcpDictServer tcpDictServer = new tcpDictServer(9999);tcpDictServer.start();}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信小游戏 彩色试管 倒水游戏 逻辑 (二)

最近开始研究微信小游戏&#xff0c;有兴趣的 可以关注一下 公众号&#xff0c; 记录一些心路历程和源代码。 定义一个 Water class 1. **定义接口和枚举**&#xff1a; - WaterInfo 接口定义了水的颜色、高度等信息。 - PourAction 枚举定义了水的倒动状态&#xff0c;…

【Nuxt3】vue3+tailwindcss+vuetify引入自定义字体样式

一、目的 在项目中引入自定义的字体样式&#xff08;全局页面都可使用&#xff09; 二、步骤 1、下载好字体 字体的后缀可以是ttf、otf、woff、eot或者svg&#xff08;推荐前三种&#xff09; 以抖音字体为例下载好放在静态文件夹&#xff08;font&#xff09;下 案例字…

数学建模入门

目录 文章目录 前言 一、数学建模是什么&#xff1f; 1、官方概念&#xff1a; 2、具体过程 3、适合哪一类人参加&#xff1f; 4、需要有哪些学科基础呢&#xff1f; 二、怎样准备数学建模&#xff08;必备‘硬件’&#xff09; 1.组队 2.资料搜索 3.常用算法总结 4.论文撰写的…

【密码学】数字签名

一、数字签名的基本概念 数字签名是一种用于验证电子文档完整性和身份认证的密码学技术。它通过使用公钥加密体系中的私钥对文档的一部分&#xff08;通常是文档的摘要&#xff09;进行加密&#xff0c;从而创建一个“签名”。这个签名可以附在文档上&#xff0c;或作为一个单独…

【数据结构】--- 堆的应用

​ 个人主页&#xff1a;星纭-CSDN博客 系列文章专栏 :数据结构 踏上取经路&#xff0c;比抵达灵山更重要&#xff01;一起努力一起进步&#xff01; 一.堆排序 在前一个文章的学习中&#xff0c;我们使用数组的物理结构构造出了逻辑结构上的堆。那么堆到底有什么用呢&…

【Linux】01.Linux 的常见指令

1. ls 指令 语法&#xff1a;ls [选项] [目录名或文件名] 功能&#xff1a;对于目录&#xff0c;该命令列出该目录下的所有子目录与文件。对于文件&#xff0c;将列出文件名以及其他信息 常用选项&#xff1a; -a&#xff1a;列出当前目录下的所有文件&#xff0c;包含隐藏文件…

Spring webflux基础核心技术

一、 用操作符转换响应式流 1 、 映射响应式流元素 转换序列的最自然方式是将每个元素映射到一个新值。 Flux 和 Mono 给出了 map 操作符&#xff0c;具有 map(Function<T&#xff0c;R>) 签名的方法可用于逐个处理元素。 当操作符将元素的类型从 T 转变为 R 时&#xf…

「豆包Marscode体验官」我用豆包Marscode画数据大屏

认识豆包Marscode 豆包 MarsCode IDE 是一个 AI 原生的云端集成开发环境&#xff08;IDE&#xff09;。内置的 AI 编程助手和开箱即用的开发环境让我们可以更加专注于各种项目的开发。豆包 MarsCode 编程助手&#xff0c;具备以智能代码补全为代表的 AI 功能。支持了多种编程语…

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(十二)-无人机群在物流中的应用

引言 本文是3GPP TR 22.829 V17.1.0技术报告&#xff0c;专注于无人机&#xff08;UAV&#xff09;在3GPP系统中的增强支持。文章提出了多个无人机应用场景&#xff0c;分析了相应的能力要求&#xff0c;并建议了新的服务级别要求和关键性能指标&#xff08;KPIs&#xff09;。…

解读网传《深圳IT圈⭕新解读八小时工作制》

网传深圳IT圈的新解读八小时工作制 工作时间安排&#xff1a; 10:00-12:0014:00-18:0019:00-21:00 初看&#xff1a;有惊喜 上午开始时间晚&#xff1a;相对于传统的9点开始&#xff0c;这种安排允许员工有更多的早晨时间&#xff0c;可以用来休息或处理个人事务。下午和晚上分…

Amazon EC2 部署Ollama + webUI

最近和同事闲聊&#xff0c;我们能不能内网自己部署一个LLM&#xff0c;于是便有了Ollama webUI的尝试 对于Linux&#xff0c;使用一行命令即可 curl -fsSL https://ollama.com/install.sh | shollama --help Large language model runnerUsage:ollam…

架构设计-NX的二次开发API架构设计介绍

1.与整体的关系 2.API设计目标 能够允许用户访问NX的所有UI工具组件&#xff0c;二次开发用户能够编写外观和运行行为类似NX的应用程序。能够允许用户直接访问NX数据模型即使底层数据结构和功能实现发生很大变化&#xff0c;API接口保持稳定&#xff0c;不会影响上层用户。 3…

智能家居开发新进展:乐鑫 ESP-ZeroCode 与亚马逊 ACK for Matter 实现集成

日前&#xff0c;乐鑫 ESP-ZeroCode 与亚马逊 Alexa Connect Kit (ACK) for Matter 实现了集成。这对智能家居设备制造商来说是一项重大进展。开发人员无需编写固件或开发移动应用程序&#xff0c;即可轻松设计符合 Matter 标准的产品。不仅如此&#xff0c;开发者还可以在短短…

网络协议 — Keepalived 高可用方案

目录 文章目录 目录Keepalived 是实现了 VRRP 协议的软件Keepalived 的软件架构VRRP StackCheckersKeepalived 的配置Global configurationvrrp_scriptVRRP Configurationvrrp synchroization groupvrrp instancevirtual ip addressesvirtual routesLVS Configurationvirtual_s…

知识图谱与LLMs:实时图分析(通过其关系的上下文理解数据点)

大型语言模型 (LLM) 极大地改变了普通人获取数据的方式。不到一年前&#xff0c;访问公司数据需要具备技术技能&#xff0c;包括熟练掌握各种仪表板工具&#xff0c;甚至深入研究数据库查询语言的复杂性。然而&#xff0c;随着 ChatGPT 等 LLM 的兴起&#xff0c;随着所谓的检索…

不常用的第三方服务集成

1.ldap 1.1.ldap服务搭建 docker方式搭建:包含了ldap服务和ldap admin图形化界面服务 参考ldap服务:http://127.0.0.1:81 用户名:CN=admin,DC=ldap,DC=com 密码:123456 docker-compose.yml文件内容如下 version: 3services:ldap:image: osixia/openldap:latestcontainer…

0基础学会在亚马逊云科技AWS上利用SageMaker、PEFT和LoRA高效微调AI大语言模型(含具体教程和代码)

项目简介&#xff1a; 小李哥今天将继续介绍亚马逊云科技AWS云计算平台上的前沿前沿AI技术解决方案&#xff0c;帮助大家快速了解国际上最热门的云计算平台亚马逊云科技AWS上的AI软甲开发最佳实践&#xff0c;并应用到自己的日常工作里。本次介绍的是如何在Amazon SageMaker上…

【qt】TCP客户端如何断开连接?

disconnectFromHost() 来关闭套接字,断开连接. 当我们关闭窗口时,也需要断开连接. 需要重写关闭事件 如果当前的套接字状态是连接上的,我们就可以来断开连接. 运行结果:

SSM框架学习笔记(仅供参考)

&#xff08;当前笔记简陋&#xff0c;仅供参考&#xff09; 第一节课&#xff1a; &#xff08;1&#xff09;讲述了Spring框架&#xff0c;常用jar包&#xff0c;以及框架中各个文件的作用 &#xff08;2&#xff09;演示了一个入门程序 &#xff08;3&#xff09;解释了…

前端项目本地的node_modules直接上传到服务器上无法直接使用(node-sasa模块报错)

跑 jekins任务的服务器不能连接外网下载依赖包&#xff0c;就将本地下载的 node_modules直接上传到服务器上&#xff0c;但是运行时node-sass模块报错了ERROR in Missing binding /root/component/node_modules/node-sass/vendor/linux-x64-48/binding.node >> 报错信息类…