程序猿成长之路之socket篇-socket通信原理简介

hello,各位小伙伴们大家好,上次以RSA加解密算法介绍作为密码学篇的结尾后,时光飞逝,转眼到了新一年的春季,这次将介绍一下socket通信和编程原理。

什么是socket(套接字)?

socket(套接字)是网络传输的一种工具,它是介于应用层与传输层之间,了解过七层OSI协议的同学应该知道,socket是基于TCP/IP协议进行网络传输的。socket分为server端和client端,它支持全双工式网络通信。

socket(套接字)有哪些用途?

说起socket的用途,大家可能首先会联想到聊天室,没错,这个就是socket的一类应用。由于全双工式的通信,socket可以支持双向的信息发送与接收。此外,socket还可以编写服务端向客户端主动发送消息。总之,有了socket,网络通信就变得容易了。

socket(套接字)其他知识

socket 生命周期在这里插入图片描述
在这里插入图片描述

什么是websocket?

WebSocket是一种在单个TCP连接上进行全双工通信的协议。它允许客户端和服务器之间进行简单而有效的双向数据传输。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。

WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。这个握手过程是通过HTTP/1.1协议的101状态码进行的。

websocket实现方式

websocket client端

const host = 'localhost'//设置自己的socket host
const port = 8888 	//设置自己的socket port
const ws =  new WebSocket(`ws://${host}:${port}/websocket/${username}`)
ws.onopen = () => {//创建完成websocketconsole.log('client opened')
}ws.onmessage = (msg) => {//接收到消息console.log(msg);
}ws.onerror = (err) => {//出错console.log(err);
}ws.onclose = () => {//websocket关闭时执行console.log("client closed")
}

websocket server端(node.js版)

onst ws = require('ws');const wss = new ws.Server({port:8888});wss.on('connection',function onConnection(ws) {ws.on('open',function onOpen(){console.log('connected!');ws.send("hello");});ws.on('message',function onMessage(msg){//批量群发wss.clients.forEach(function each(client) {//如果socket 为连接状态就发送消息if (client.readyState === ws.OPEN) {client.send(msg);}})})ws.on('close',function onOpen(){console.log('closed!');});
})

websocket server端(java版)
配置类:

/*** WebSocket配置类。开启WebSocket的支持*/
@Configuration
public class WebSocketConfig {/*** bean注册:会自动扫描带有@ServerEndpoint注解声明的Websocket Endpoint(端点),注册成为Websocket bean。* 要注意,如果项目使用外置的servlet容器,而不是直接使用springboot内置容器的话,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。*/@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}
}

websocket 消息 实体类

/*** 消息实体类* @author zygswo*/
@Data
@Accessors(chain = true)
@NoArgsConstructor
@ToString
public class Message implements Serializable {/*** 来源*/private String from;/*** 目标*/private String to;/*** 正文*/private String message;/*** 发送时间*/private String date;/*** 是否系统消息*/private boolean sysmsg;
}

websocket实现类:

package com.myhouse.common.utils.myWebsocket;import com.alibaba.fastjson.JSON;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;/*** ServerEndpoint注解表示开启websocket并且参数表示websocketserver 路径*/
@Component
@Slf4j
@Getter
@ServerEndpoint("/websocket/{username}")
public class MyWebSocket {/*** 在线人数*/private static AtomicInteger totalNb = new AtomicInteger(0);/*** websocket列表*/private static Map<String,MyWebSocket> socketMap = new ConcurrentHashMap<>();/*** 在线人数*/private Session session;/*** 用户名*/private String username;/*** 开启服务* @param username 用户名称* @param session session*/@OnOpenpublic void onOpen(@PathParam("username") String username, Session session) {this.username = username;this.session = session;     //保存当前会话addOnlineCount();           //在线数加1log.info("欢迎用户" + username +  " 加入聊天室!当前在线人数为: " + getOnlineCount());}/*** 获取到消息后* @param message 消息*/@OnMessagepublic void onMessage(String message) {Message msg = JSON.parseObject(message, Message.class);try {if (msg.getTo().equalsIgnoreCase("all")) {for (MyWebSocket socket : socketMap.values()) {socket.sendMessage(message);}} else {socketMap.get(msg.getTo()).sendMessage(message);}}catch (IOException e) {e.printStackTrace();}}/*** 发送消息* @param message 消息*/private void sendMessage(String message) throws IOException {this.session.getBasicRemote().sendText(message);}/*** 获取到消息后* @param session session* @param err 错误消息*/@OnErrorpublic void onError(Session session, Throwable err) {System.out.println("发生错误");try {session.close();} catch (IOException e) {e.printStackTrace();}log.error(err.getMessage());err.printStackTrace();}/*** socket连接关闭*/@OnClosepublic void onClose() {log.info(this.username + "退出聊天室!当前在线人数为" + getOnlineCount());socket.sendMessage(msg);socketMap.remove(this.username);}/*** 新增在线人数*/private static void addOnlineCount() {totalNb.incrementAndGet();}/*** 减少在线人数*/private static void substractOnlineCount() {totalNb.decrementAndGet();}/*** 获取在线人数* @return 在线人数*/public static int getOnlineCount() {return totalNb.get();}
}

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

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

相关文章

DataGrip 2023:让数据库开发变得更简单、更高效 mac/win

JetBrains DataGrip 2023是一款功能强大的数据库IDE&#xff0c;专为数据库开发和管理而设计。通过DataGrip&#xff0c;您可以连接到各种关系型数据库管理系统(RDBMS)&#xff0c;并使用其提供的一组工具来查询、管理、编辑和开发数据库。 DataGrip 2023软件获取 DataGrip 2…

【网络安全】手机不幸被远程监控,该如何破解,如何预防?

手机如果不幸被远程监控了&#xff0c;用三招就可以轻松破解&#xff0c;再用三招可以防范于未然。 三招可破解可解除手机被远程监控 1、恢复出厂设置 这一招是手机解决软件故障和系统故障的终极大招。只要点了恢复出厂设置&#xff0c;你手机里后装的各种APP全部将灰飞烟灭…

Leetcode 240. 搜索二维矩阵 II

题目描述&#xff1a; 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。 每列的元素从上到下升序排列。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6…

NAS网络存储的简单了解

一、概述 NAS网络存储&#xff0c;即网络附加存储&#xff08;Network Attached Storage&#xff09;&#xff0c;是一种具有很大存储容量的电脑外敷设备&#xff0c;它通过网络直接连接到交换机上。NAS的主要功能是为网络区域存储&#xff08;或磁盘&#xff09;的用户提供数据…

设计模式 -- 2:策略模式

目录 总结部分&#xff1a;策略模式的优点部分代码部分 总结部分&#xff1a; 策略模式和简单工厂模式很像 区别在于 简单工厂模式 需求的是由工程创造的类 去给客户直接答案 而策略模式在于 我有主体 一个主体 根据策略的不同来进行不同的计算 我的主体就负责收钱 然后调度相…

让若依生成的service、mapper继承mybatisPlus的基类

前言&#xff1a;若依继承mybatisPlus后&#xff0c;生成代码都要手动去service、serviceImpl、mapper文件去继承mybatisplus的基类&#xff0c;繁琐死了。这里通过修改若依生成模版从而达到生成文件后直接使用mybatisPlus的方法。 一、首先找到若依生成模版文件位置&#xff…

《安富莱嵌入式周报》第334期:开源SEM扫描电子显微镜,自制编辑器并搭建嵌入式环境,免费产品设计审查服务,实用电子技术入门,USB资料汇总,UDS统一诊断

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版&#xff1a; https://www.bilibili.com/video/BV1om411Z714/ 《安富莱嵌入式周报》第334期&#xff1a;开源SEM…

xcode15,个推推送SDK闪退问题处理办法

个推iOS推送SDK最新版本 优化了xcode15部分场景下崩溃问题&#xff0c;以及回执上传问题&#xff0c;近期您的应用有发版计划&#xff0c;建议更新SDK&#xff1a; 1&#xff09;GTSDK更新到3.0.5.0以及以上版本&#xff1b; 2&#xff09;GTCommonSDK更新到3.1.0.0及以上版本…

深入理解Python中的面向对象编程(OOP)【第129篇—Scikit-learn的入门】

深入理解Python中的面向对象编程&#xff08;OOP&#xff09; 在Python编程领域中&#xff0c;面向对象编程&#xff08;Object-Oriented Programming&#xff0c;简称OOP&#xff09;是一种强大而灵活的编程范式&#xff0c;它允许开发者以对象为中心组织代码&#xff0c;使得…

snowny-小诺框架-标签tabs消失不见

可能是由于&#xff0c;在配置菜单时&#xff0c;排序数字过小造成的&#xff0c;将排序数字改成大于0的数字就好使了。

安装VMWare

下载VMware软件&#xff08;已提供给大家&#xff09; 2&#xff0e;解压压缩文件 3.解压后文件夹中的内容 4.双击.exe进行VMware安装出现的第一个界面 5.点击下一步&#xff0c;出现以下界面 6.勾选我接受复选框&#xff0c;然后点击“下一步”。 7.后面几步都是点击“下一步”…

数码管的静态显示(二)

1.原理 要按照上图的顺序传递位选和段选的数据。 因为q0是最高位&#xff0c;共阳极数码管结构是dp....a&#xff0c;所以应该先传入低位a&#xff0c;而a在上图中的8段2进制编码中是seg[7]&#xff0c;所以段选信号的顺序是seg[0],...seg[7]。 因为输出信号是两个时钟&#x…

Spring boot 集成netty实现websocket通信

一、netty介绍 Netty 是一个基于NIO的客户、服务器端的编程框架&#xff0c;使用Netty 可以确保你快速和简单的开发出一个网络应用&#xff0c;例如实现了某种协议的客户、服务端应用。Netty相当于简化和流线化了网络应用的编程开发过程&#xff0c;例如&#xff1a;基于TCP和U…

如何从 Mac 电脑外部硬盘恢复删除的数据文件

本文向您介绍一些恢复 Mac 外置硬盘数据的快速简便的方法。 Mac 的内部存储空间通常不足以存储所有数据。因此&#xff0c;许多用户通过外部驱动器扩展存储或创建数据备份。然而&#xff0c;与几乎所有其他设备一样&#xff0c;从外部硬盘驱动器丢失有价值的数据并不罕见。由于…

STM32第七节:GPIO输入——按键检测(包含带参宏)

目录 前言 STM32第七节&#xff1a;GPIO输入——按键检测&#xff08;包含带参宏&#xff09; 带参宏 代码替换展示 定义带参宏 GPIO输入——按键检测 硬件部分 端口输入数据寄存器&#xff08;GPIOx_IDR&#xff09; 编写程序 配置以及编写bsp_key文件 main函数编程…

一文扫荡,12个可视化图表js库,收藏备用。

一、什么是可视化图表 可视化图表是通过图形化的方式将数据可视化展示出来的一种方式。它能够将复杂的数据以直观、易懂的形式呈现给用户&#xff0c;帮助用户更好地理解和分析数据。 可视化图表可以包括各种类型的图表&#xff0c;如线形图、柱状图、饼图、散点图、雷达图等。…

如何使用vue定义组件之——父组件调用子组件数据

首先&#xff0c;准备父子容器&#xff1a; <div class"container"><my-father></my-father><my-father></my-father><my-father></my-father><!-- 此处无法调用子组件&#xff0c;子组件必须依赖于父组件进行展示 --&…

【数据结构】双向链表及LRU缓存的实现

目录 前言 1. 在原有的自定义链表类 Linked 的基础上&#xff0c;添加新的 “节点添加”方法 addNode(Node node) 测试用例 测试结果 2. 在自定义链表类的基础上&#xff0c;使用双重循环“强力” 判断两个节点是否发生相交 测试用例 测试结果 3. 在自定义链表类的基础上…

Github 2024-03-14 Go开源项目日报 Top10

根据Github Trendings的统计,今日(2024-03-14统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Go项目9非开发语言项目1TypeScript项目1Ollama: 本地大型语言模型设置与运行 创建周期:248 天开发语言:Go协议类型:MIT LicenseStar数量:42…

【JVM】什么是运行时数据区?

什么是运行时数据区&#xff1f; 运行时数据区指的是JVM所管理的内存区域&#xff0c;其中分成两大类&#xff1a; 线程共享 – 方法区、堆 方法区&#xff1a;存放每一个加载的类的元信息、运行时常量池、字符串常量池。 堆&#xff1a;存放创建出来的对象。 线程不共享 – …