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

Socket编程、协议理解

Socket编程、协议理解

  • 简单说明
  • Socket编程
    • Socket 常用接口
    • Socket服务端业务编码
      • 代码说明
        • 文件服务(fileServe)
        • 消息服务(msgServe)
        • 消息写会(writeResponse)
      • 注意事项
    • Socket客户端业务编码
      • 代码说明
  • 总结

RYP协议:基于TCP/IP协议之上的自定义协议Rocky Protocol。
协议用途:学习并理解顶层协议基础中的基础原理和理论说明。

    // 协议 RYP// 协议规定:第一个字节为类型判断,1为文件流 其他为文字流。// 除第一字节后的body体即为传输内容。

简单说明

为了更好的学习Socket,实现Socket的过程中,更好的理解什么是应用层协议,也为了进一步理解协议的概念。
目的:学习Socket编程,了解协议的概念。
语言:Java

协议: 经商讨、协商而制定的多方公共认可的、遵守的约定。

举例:我们中国人讲的话被称作中文,这个就是世界共同认可的,达成共识的。
若你自己创建了一个语言发音,但是只是自己知道不成体系,这不被他人认可的就不能称作有协议的概念。

Socket编程

所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议栈进行交互的接口。 1

Socket编程,通常是一对套接字之间的通信交互。在下面的实例中,体现出来的双端分别为:服务端、客户端。

服务端:提供接入服务,并提供特有的服务和业务处理,服务端负责消息的接收,业务的处理和结果回写。作为服务端不可自主选择客户端,只能等待客户端的接入来完成服务,类似一个特定功能的应用程序,只为客户端提供特有的服务。

客户端:接入服务端,获取服务端提供的特定功能的服务。客户端可以指定服务端,客户端与客户端之间无法通信。

Socket 常用接口

方法名称入参说明
getInputStreamvoid获取读流
getOutputStreamvoid获取写流
shutdownInputvoid说明当前读流已完成,不会在进行读流操作了。is流也会失效。
shutdownOutputvoid说明当前写流已完成,不会进行写流操作了。os流也会失效。
closevoid关闭当前连接

Socket服务端业务编码

    // 协议 RYP// 协议规定:第一个字节为类型判断,1为文件流 其他为文字流。// 除第一字节后的body体即为传输内容public static final String FILE_RES = "服务端回复::文件接收成功 (~v~)";public static final String MSG_RES = "服务端回复::消息已成功接收!";public static void main(String[] args) {try {ServerSocket serverSocket = new ServerSocket(55555);while (true) {System.out.println("服务端接收准备完成...");Socket client = serverSocket.accept();InputStream is = client.getInputStream();byte type = getType(is);if (type == TypeEnums.FILE_TYPE) {fileServe(is);} else {msgServe(is);}client.shutdownInput();writeResponse(client, type);client.close();}} catch (IOException e) {e.printStackTrace();}}/*** 文件服务** @param inputStream* @throws IOException*/private static void fileServe(InputStream inputStream) throws IOException {System.out.println("当前是文件类型!");String filePath = "C:\\log.txt";FileOutputStream fos = new FileOutputStream(filePath);OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");char[] buff = new char[1024];BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));while (br.read(buff) != -1) {String str = new String(buff);osw.write(str);}osw.close();System.out.println("客户端发送文件已接收完成!");}/*** 消息服务** @param is* @throws IOException*/private static void msgServe(InputStream is) throws IOException {InputStreamReader isr = new InputStreamReader(is);BufferedReader br = new BufferedReader(isr);String temp = null;StringBuilder sb = new StringBuilder();while (null != (temp = br.readLine())) {sb.append(temp);}System.out.println("客户端请求:" + sb.toString());}/*** 消息写回** @param client* @param type   业务类型 1 文件 其他:消息* @throws IOException*/private static void writeResponse(Socket client, byte type) throws IOException {OutputStream outputStream = client.getOutputStream();PrintWriter writer = new PrintWriter(outputStream);writer.println(type == 1 ? FILE_RES : MSG_RES);writer.flush();writer.close();}/*** 获取业务类型** @param is* @return* @throws IOException*/private static byte getType(InputStream is) throws IOException {byte[] buf = new byte[1];is.read(buf);return buf[0];}

代码说明

ServerSocket serverSocket = new ServerSocket(55555)
用于定义服务端Socket,需定义一个端口,用于客户端的接入。
accept执行后,动服务端即会进入阻塞状态,当存在客户端接入是就会分配一个连接去响应客户端的请求服务。

在代码用例中可以看到,我们首先通过getType方法读流,当前协议的约定是第一个字节作为判断依据,“1:文件服务类型,其他:消息服务类型”。
在识别类型后作具体的业务判断是文件服务还是消息服务。

文件服务(fileServe)

文件服务实现的特定业务为文件存储,客户端将自己想要存储的文件写到流中,服务端读取到文件后,将文件转储到当前服务器中,类似于文件服务器的服务。(没有写读文件,大致理解就可,有兴趣的可以使用Socket编程写一个简易文件服务)

消息服务(msgServe)

消息服务实现的特定业务较为简单,接收客户端发送的信息,展示处理。

消息写会(writeResponse)

获取os流,回写需要返回给客户端的信息。

注意事项

  1. 文件使用字符流转储,也可使用字节流,但字节流对于存在中文的情况下,byte[]数组上限的情况下会存在乱码的情况且数据量大的情况下性能极低。
  2. 文件服务目前只适合传输txt类型的文件,若其他文件可以扩展业务类型使用字节流进行转储。

Socket客户端业务编码

public static final byte FILE_TYPE = 1;public static final byte MSG_TYPE = 2;public static void main(String[] args) {try {long sl = System.currentTimeMillis();Socket socket = new Socket("127.0.0.1", 55235);act(socket, FILE_TYPE);long se = System.currentTimeMillis();System.out.println("总花费时间:" + (se - sl) + "ms");socket.close();} catch (IOException e) {e.printStackTrace();}}/*** 执行器** @param socket* @param type* @throws IOException*/private static void act(Socket socket, byte type) throws IOException {if (type == FILE_TYPE) {transferFile(socket);} else {transferMsg(socket);}}/*** 文件传输** @param socket 套接字* @throws IOException*/public static void transferFile(Socket socket) throws IOException {System.out.println("客户端准备传输文件...");String filePath = "C:\\Users\\rock\\Desktop\\test.txt";OutputStream outputStream = socket.getOutputStream();outputStream.write(FILE_TYPE);outputStream.write(fileConvertToByteArray(new File(filePath)));socket.shutdownOutput();response(socket.getInputStream());}/*** 消息传输** @param socket 套接字*/public static void transferMsg(Socket socket) throws IOException {System.out.println("客户端准备传输消息...");String msg = "This is test msg";OutputStream outputStream = socket.getOutputStream();outputStream.write(MSG_TYPE);outputStream.write(msg.getBytes());socket.shutdownOutput();response(socket.getInputStream());}/*** 封装回复信息通知** @param inputStream 读流* @throws IOException*/public static void response(InputStream inputStream) throws IOException {InputStreamReader isr = new InputStreamReader(inputStream);BufferedReader br = new BufferedReader(isr);String temp = null;StringBuilder sb = new StringBuilder();while (null != (temp = br.readLine())) {sb.append(temp);}System.out.println(sb.toString());}/*** 文件转byte流** @param file 文件信息* @return*/private static byte[] fileConvertToByteArray(File file) {byte[] data = null;try {FileInputStream fis = new FileInputStream(file);ByteArrayOutputStream baos = new ByteArrayOutputStream();int len;byte[] buffer = new byte[1024];while ((len = fis.read(buffer)) != -1) {baos.write(buffer, 0, len);}data = baos.toByteArray();fis.close();baos.close();} catch (Exception e) {e.printStackTrace();}return data;}

代码说明

Socket socket = new Socket(“127.0.0.1”, 55555);
客户端创建连接时,需要指定服务端的IP和端口,这也是套接字的组成。
使用os流将需要的信息写入到流中,传入服务端。(根据协议的约定组装流数据)
无论是文件还是字符串都将转为字节流进行传输。
客户端的处理比服务端来讲,过程简单,也容易理解。
因为客户端是使用功能的一方,只需要传入约定的数据,获得对应的服务即可。

总结

至此,我们就简单的实现了Socket编程,以及完成了一个基于TCP/IP协议实现了另一套协议的约定的内容。之后再次进行应用协议的学习可能有更好的理论基础,因底层原理基本类似,只是顶层设计更为复杂,约定内容更为精细,职能更为清晰。

希望各位对Socket和协议有一个更加清晰的认知


  1. 王雷,TCP/IP网络编程基础教程,北京理工大学出版社,2017.02,第4页 ↩︎

相关文章:

Socket编程、协议理解

Socket编程、协议理解简单说明Socket编程Socket 常用接口Socket服务端业务编码代码说明文件服务(fileServe)消息服务(msgServe)消息写会(writeResponse)注意事项Socket客户端业务编码代码说明总结RYP协议:基于TCP/IP协议之上的自定义协议Rocky Protocol。 协议用途&…...

Idea集成码云

1:Idea集成码云1.1:IDEA安装码云插件【第一步】Idea 默认不带码云插件, 我们第一步要安装 Gitee 插件。如图所示, 在 Idea 插件商店搜索 Gitee,然后点击右侧的 Install 按钮。安装成功后,重启 Idea。Idea 重…...

并发编程学习篇ReentrantLock设计思想剖析

一、AQS原理剖析 什么是AQS java.util.concurrent包中的大多数同步器实现都是围绕着共同的基础行为,比如 等待队列、条件队列、独占获取、共享获取等而这些行为的抽象就是基于AbstractQueuedSynchronizer(简称AQS)实现的,AQS是一…...

区分效度全流程分析

基本说明 区分效度(又称判别效度、区别效度),其实质也是一种结构效度。区分效度强调本不应该在同一因子的测量项,确实不在同一因子下面。比如说,测量项A和 B分别测量两个属性,应该分属于因子A和因子B中&…...

【华为OD机试模拟题】用 C++ 实现 - 找数字(2023.Q1)

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…...

从0开始写Vue项目-Vue实现用户数据批量上传和数据导出

从0开始写Vue项目-环境和项目搭建_慕言要努力的博客-CSDN博客从0开始写Vue项目-Vue2集成Element-ui和后台主体框架搭建_慕言要努力的博客-CSDN博客从0开始写Vue项目-Vue页面主体布局和登录、注册页面_慕言要努力的博客-CSDN博客从0开始写Vue项目-SpringBoot整合Mybatis-plus实现…...

企业容器云管理平台选型指南

作者简介 涂家英,SUSE 资深架构师,专注 Cloud-Native 相关产品和解决方案设计,在企业级云原生平台建设领域拥有丰富的经验。 数字时代下的容器云管理平台 数字时代,市场竞争加剧,业务需求日新月异,敏态 IT…...

OpenGL超级宝典学习笔记:着色器存储区块、原子内存操作、内存屏障

前言 本篇在讲什么 本篇为蓝宝书学习笔记 着色器存储区块 原子内存操作 内存屏障 本篇适合什么 适合初学Open的小白 本篇需要什么 对C语法有简单认知 对OpenGL有简单认知 最好是有OpenGL超级宝典蓝宝书 依赖Visual Studio编辑器 本篇的特色 具有全流程的图文教学 重…...

SpringMVC框架知识详解(入门版)

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...

25-动画和过渡

动画和过渡 一、动画 使用css动画样式&#xff0c;配合vue实现动画效果。 编写模板 <template><div><button click"isShow !isShow">显示/隐藏</button><h1 v-show"isShow">你好啊</h1></div> </templa…...

Linux 操作系统原理 — 虚拟内存管理

目录 文章目录 目录虚拟内存技术页式内存管理技术x86_32 CPU 虚拟内存虚拟地址格式与内核页表虚拟内存空间Kernel SpaceUser Spacex86_64 CPU 虚拟内存虚拟地址格式与内核页表(四级页表)虚拟内存空间TLB 缓冲(快表)进程页表虚拟内存技术 虚拟内存技术是操作系统实现的一种…...

保持超低温环境新方法:功耗降至十分之一!

&#xff08;图片来源&#xff1a;网络&#xff09;量子比特是量子计算机的主要构建部分&#xff0c;然而热量会导致量子比特容易出错&#xff0c;因此量子系统通常保存在超低温稀释制冷机内&#xff0c;可以将温度保持在绝对零度&#xff08;−273.15℃&#xff09;以上。但是…...

论文投稿指南——中文核心期刊推荐(音乐)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…...

es-10搜索推荐suggest

搜索推荐&#xff1a;Suggest 概述 搜索一般都会要求具有“搜索推荐”或者叫“搜索补全”的功能&#xff0c;即在用户输入搜索的过程中&#xff0c;进行自动补全或者纠错。以此来提高搜索文档的匹配精准度&#xff0c;进而提升用户的搜索体验&#xff0c;这就是Suggest。 四…...

VMware ESXi 7.0 Update 3k - 领先的裸机 Hypervisor (sysin Custom Image)

VMware ESXi 7.0 Update 3k - 领先的裸机 Hypervisor (sysin Custom Image) VMware ESXi 7.0 Update 3k Standard & All Custom Image for ESXi 7.0 U3k Install CD 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-esxi-7-u3/&#xff0c;查看最新版。原创作品…...

JVM整体分析篇

这里写目录标题JVM的组成部分1.类装载子系统1.1一个类加载到JVM的过程1.2类加载机制1.3为什么设计双亲委派机制1.4怎么打破双亲委派机制2.运行时数据区2.1线程私有及共享2.2JVM内存区结构2.3JVM参数设置经验3.Java对象的生命周期3.1.对象的创建3.2.对象大小的计算&#xff08;6…...

【Python入门第十七天】Python While 循环

Python 循环 Python 有两个原始的循环命令&#xff1a; while 循环for 循环 while 循环 如果使用 while 循环&#xff0c;只要条件为真&#xff0c;我们就可以执行一组语句。 实例 只要 i 小于 7&#xff0c;打印 i&#xff1a; i 1 while i < 7:print(i)i 1运行实…...

怎样激发读者好奇心?短视频营销之场景化

目录 激发读者好奇心&#xff1f;四个小技巧帮你搞定 1.省略法 2.欲言又止法: 3.问句法:就是用疑问的形式引起别人的好奇。 4.反差法 选择合适的主题。 利用场景化效果 使用滤镜。 如何提高用户的留存率。 1、设置一个有趣的话题。 2、用好道具。 3、多用竖屏。 什…...

【LeetCode】剑指 Offer 14- II. 剪绳子 II p96 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/jian-sheng-zi-ii-lcof/ 1. 题目介绍&#xff08;14- II. 剪绳子 II&#xff09; 给你一根长度为 n 的绳子&#xff0c;请把绳子剪成整数长度的 m 段&#xff08;m、n都是整数&#xff0c;n>1并且m>1&#xff09;&…...

【红黑树】红黑树插入操作相关的细节和疑难拆解分析

本文就红黑树的插入操作进行细致到每一个小步骤的解析。1&#xff0c;成员变量本红黑树使用了三叉链结构&#xff0c;使用的时候尤其要记得处理指向父亲的指针。为何在节点的构造函数中&#xff0c;默认节点的颜色为红色&#xff1f;因为考虑到红黑树的性质&#xff08;对于每个…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

ZYNQ学习记录FPGA(一)ZYNQ简介

一、知识准备 1.一些术语,缩写和概念&#xff1a; 1&#xff09;ZYNQ全称&#xff1a;ZYNQ7000 All Pgrammable SoC 2&#xff09;SoC:system on chips(片上系统)&#xff0c;对比集成电路的SoB&#xff08;system on board&#xff09; 3&#xff09;ARM&#xff1a;处理器…...