WebSocket和Socket编程

news2025/3/12 23:35:17

面试一般会问

socket原理
socket为啥要有端口:确定一个链路的是一个四元组
Socket编程
socket通信
你做过socket编程吗,socket是怎么实现知道有连接过来的
说说WebSocket与socket的区别

先谈谈Websocket与Socket的区别

首先Socket == 不属于协议范畴 ,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用来实现进程在网络中的通信。
WebSocket是应用层协议,是一种
让客户端和服务器之间能进行双向实时通信==的技术。
WebSocket 更易用,而 Socket 更灵活。主机 A 的应用程序要能和主机 B 的应用程序通信,必须通过 Socket 建立连接,而建立 Socket 连接必须需要底层 TCP/IP 协议来建立 TCP 连接。建立 TCP 连接需要底层 IP 协议来寻址网络中的主机。网络层使用的 IP 协议可以帮助我们根据 IP 地址来找到目标主机,但是一台主机上可能运行着多个应用程序,如何才能与指定的应用程序通信就要通过 TCP 或 UDP 的地址也就是端口号来指定。这样就可以通过一个 Socket 实例唯一代表一个主机上的一个应用程序的通信链路了。而 WebSocket 则不同,它是一个完整的 应用层协议,包含一套标准的 API 。
Socket 是传输控制层的接口,用户可以通过 Socket 来操作底层 TCP/IP 协议族通信。Socket是对TCP/IP的封装,WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次 HTTP 握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

WebSocket是什么

同一时间里,双方都可以主动向对方发送数据。这就是所谓的全双工。而现在使用最广泛的HTTP/1.1,也是基于TCP协议的,同一时间里,客户端和服务器只能有一方主动发数据,这就是所谓的半双工。因为HTTP协议设计之初考虑的是看看网页文本的场景,能做到客户端发起请求再由服务器响应,未考虑网页游戏这种,客户端和服务器之间都要互相主动发大量数据的场景,为了更好支持这个场景我们需要另一个TCP的新协议,因此新的应用层协议被设计出来,虽然带有socket,但是与socket毫无关系。

怎么建立WebSocket连接

浏览器在TCP三次握手建立连接后,都统一使用HTTP协议先进行一次通信。

  • 如果是普通的HTTP请求,那后续双方还是老样子
  • 如果想建立WebSocket连接,就会在HTTP请求里带上特殊的Header投头:
Connection: Upgrade
Upgrade: WebSocket
Sec-WebSocket-Key: T2a6wZlAwhgQNqruZ2YUyg==\r\n

如果服务器正好支持升级成WebSocket协议就会走WebSocket握手流程,同时根据客户端生成的base64码,用某个公开算法变成另一段字符串,放在Sec-WebSocket-Accept里,同时带上101状态码(协议切换)发回给浏览器。

HTTP/1.1 101 Switching Protocols\r\n
Sec-WebSocket-Accept: iBJKv/ALIW2DobfoA4dmr3JHBCY=\r\n
Upgrade: WebSocket\r\n
Connection: Upgrade\r\n

在这里插入图片描述
WebSocket只有在建立连接(利用HTTP协议加上一些特殊的 header 头进行握手升级操作,升级成功后就跟 HTTP 没有任何关系了)时才用到了HTTP,升级完成之后就跟HTTP没有任何关系了。
在这里插入图片描述

WebSocket使用场景

WebSocket完美继承了 TCP 协议的全双工能力,并且还贴心的提供了解决粘包的方案。
它适用于需要服务器和客户端(浏览器)频繁交互的大部分场景,比如网页/小程序游戏,网页聊天室,以及一些类似飞书这样的网页协同办公软件。
在使用 WebSocket 协议的网页游戏里,怪物移动以及攻击玩家的行为是服务器逻辑产生的,对玩家产生的伤害等数据,都需要由服务器主动发送给客户端,客户端获得数据后展示对应的效果。

Socket

socket通常称为“套接字”,用于描述IP地址和端口,是一个通信链的句柄。应用程序通过套接字向网络发出请求或应答网络请求。服务器和客户端通过socket进行交互。服务器需要绑定在本机的某个端口号上客户端需要声明自己连接哪个地址的哪个端口,这样服务器和客户端就能连接了。
socket一般用于比较即时的通信和实时性较高的情况,比如推送,聊天,保持心跳长连接等,对比http一般用于实时性要求不那么高的情况,比如信息反馈,图片上传,获取新闻信息等。

监听的socket和真正用来传送数据的socket,属于两个socket,一个叫做监听socket,一个叫做已完成连接socket。
需要注意服务端调用accept时,连接成功了就会返回一个已完成连接的socket,后续用来传输数据。
成功连接建立之后,双方开始通过 read 和 write 函数来读写数据,就像往一个文件流里面写东西一样。
在这里插入图片描述
Linux内核维护两个队列:
半连接队列(SYN 队列):接收到一个 SYN 建立连接请求,处于 SYN_RCVD 状态;
全连接队列(Accpet 队列):已完成 TCP 三次握手过程,处于 ESTABLISHED 状态;
在这里插入图片描述

Socket通信原理简单阐述

(1)服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。
(2)客户端请求:是指由客户端的套接字提出连接请求要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
(3)连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求建立一个新的线程把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

accept发生在三次握手的哪一步

在这里插入图片描述
客户端协议栈向服务端发送了SYN包,告诉服务端当前发送序号client_isn,客户端进入SYN_SENT状态
服务端协议栈收到这个包之后,和客户端进行ACK应答,应答client_isn+1,表示对SYN包client_isn的确认,同时服务端也发送一个SYN包,告诉客户端当前我的发送序列号为server_isn,服务端进入 SYN_RCVD 状态;客户端协议栈收到ACK之后使得应用程序connect调用返回,表示客户端到服务端的单向连接建立成功,客户端状态为ESTABLISHED。同时客户端协议栈对服务端的SYN包进行应答,应答数据为server_isn+1;ACK应答包到达服务端,服务端TCP连接进入ESTABLISHED状态,同时服务端协议栈使得accept阻塞调用返回,这个时候服务端到客户端单向连接建立成功。至此,客户端和服务端两个方向的连接都建立成功。
客户端connect成功返回是在第二次握手,服务端accept成功返回是在第三次握手成功之后

客户端调用close了,连接是断开的流程是什么?

在这里插入图片描述
客户端调用 close,表明客户端没有数据需要发送了,则此时会向服务端发送 FIN 报文,进入 FIN_WAIT_1 状态;服务端接收到了 FIN 报文,TCP 协议栈会为 FIN 包插入一个文件结束符 EOF 到接收缓冲区中,应用程序可以通过 read 调用来感知这个 FIN 包。这个 EOF 会被放在已排队等候的其他已接收的数据之后,这就意味着服务端需要处理这种异常情况,因为 EOF 表示在该连接上再无额外数据到达。此时,服务端进入 CLOSE_WAIT 状态;接着,当处理完数据后,自然就会读到 EOF,于是也调用 close 关闭它的套接字,这会使得服务端发出一个 FIN 包,之后处于 LAST_ACK 状态;客户端接收到服务端的 FIN 包,并发送 ACK 确认包给服务端,此时客户端将进入 TIME_WAIT 状态;服务端收到 ACK 确认包后,就进入了最后的 CLOSE 状态;客户端经过 2MSL 时间之后,也进入 CLOSE 状态;

没有accept,能建立TCP连接吗?

可以,accept不参与TCP三次握手,它只是负责从TCP全连接队列中取出一个已经建立连接的socket,用户层通过accept系统调用拿到了已经建立连接的socket,就可以对该socket进行读写操作。
在这里插入图片描述

没有listen,能建立TCP连接吗?

客户端可以自己连自己,也可以两个客户端同时向对方发出请求建立连接,相同点在于没有服务端参与,也就没有listen,就能TCP建立连接。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

处理用户输入

shell脚本编程系列 传递参数 向shell脚本传递数据的最简单方法是使用命令行参数 比如 ./add 10 30读取参数 bash shell会将所有的命令行参数都指派给位置参数的特殊变量。其中$0对应脚本名、$1是第一个参数、$2是第二个参数,依次类推,直到$9 #!/bin/b…

Unity3D打包WebGL并使用MQTT(二):使用json

Unity3D打包WebGL并使用MQTT(二):使用json 1. 软件环境 Unity: 2021.3stomp.js 2.3.3: 下载地址:https://www.jsdelivr.com/package/npm/stompjs 2. 内容介绍 这篇博客的主要内容是记录将一个Unity项目打包成WebGL项目,并集成MQTT进行json数据传输的过程。 3. …

〖Python网络爬虫实战⑬〗- XPATH实战案例

订阅:新手可以订阅我的其他专栏。免费阶段订阅量1000python项目实战 Python编程基础教程系列(零基础小白搬砖逆袭) 说明:本专栏持续更新中,目前专栏免费订阅,在转为付费专栏前订阅本专栏的,可以免费订阅付费…

一篇文章理解堆栈溢出

一篇文章理解堆栈溢出引言栈溢出ret2text答案ret2shellcode答案ret2syscall答案栈迁移答案堆溢出 unlink - UAF堆结构小提示向前合并/向后合并堆溢出题答案引言 让新手快速理解堆栈溢出,尽可能写的简单一些。 栈溢出 代码执行到进入函数之前都会记录返回地址到SP…

wsl区分和切换,安装NVIDIA驱动+cuda+ffmpeg

wsl区分和切换,安装NVIDIA驱动cudaffmpeg 安装Nvidia驱动 打开terminal wsl --update进入wsl nvidia-smi网上找了一些博客,获取信息: window安装好驱动即可wsl有1和2 我的win10已经安装了驱动 wsl1和wsl怎么区分?切换 区分…

实时聊天提示的最佳做法

本文将教您更多关于有效的实时聊天功能对您的品牌的重要性,以及您可以使用的一些最佳实践来确保您的实时聊天功能尽可能好。实时聊天提示是为您的网站访问者显示的自动聊天消息。在SaleSmartly(ss客服)中,如您将聊天插件安装到您的…

Win10 安装 MongoDB 5.0.16

一、MongoDB 的官方:http://www.mongodb.com/ 下载:​ ​https://www.mongodb.com/download-center/community​ 二、下载msi文件,双击该文件进行安装。 (1)打开对话框 ,单击“Next” (2)请勾…

总结815

4月(复习完高数18讲内容,背诵21篇短文,熟词僻义300词基础词) 4.8 英语:早上继续背昨天没背完的第15篇文章单词,感觉效率极高,可能是昨晚睡眠质量特别好。下午抄写第16篇文章每日一句长难句看《…

Meetup 直播预告|助力企业数字化转型,8 大微服务容器开源实践亮点抢先看

随着数字化、智能化发展趋势不断加快,大中小型企业纷纷将企业“上云”提上日程,推动企业数字化转型。云时代下,企业需要新技术架构,使之更好地利用云计算优势,让业务更敏捷、成本更低、可伸缩性更强,云原生…

进程概念详解

目录 进程是什么? 描述进程:进程控制块-PCB task_struct task_struct 是什么? task_struct内容分类 组织进程 查看进程 fork创建子进程 进程状态 僵尸进程 孤儿进程 进程优先级 其他概念 进程是什么? 一般书上…

【微信小程序】父子组件之间传值

微信小程序父子组件之间传值有两种: 1.父组件向子组件传值 2.子组件向父组件传值 区别: 父向子传值使用的是属性绑定,子组件中的properties对象进行接收父组件传递过来的值。子向父传值使用的是自定义事件,父组件通过自定义事件…

VUE 学习笔记(一)开发环境搭建

1、Visual Studio Code安装及使用 下载地址官网:https://code.visualstudio.com/ 直接点击下载按钮即可,会根据系统自动下载合适的版本,无需自行选择。 2、VSCode 上安装:JavaScript Debugger 目前 Debugger for Chrome 已经处…

基于html+css的盒子内容旋转

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

【目标检测论文阅读笔记】Reducing Label Noise in Anchor-Free Object Detection

(Augmentation for small object detection) Abstract 当前的 anchor-free无锚目标检测器 将空间上落在真值框预定义中心区域内的所有特征标记为正。这种方法会在训练过程中产生 标签噪声,因为这些 正标记的特征中的一些 可能位于背景或遮挡…

2023最新8个电脑必装软件,新电脑装完好用又高效

新买的笔记本电脑到手了,需要安装什么软件?不会真的有人这样问吧,万一真的有人不知道需要安装什么软件呢?好吧,提醒一下各位,新电脑不要乱安装软件啊,不然电脑很容易中病毒的。根据我多次换电脑…

MyBatis配置文件 —— 相关标签详解

目录 一、Mybatis配置文件 — properties标签 二、Mybatis配置文件 — settings标签 三、Mybatis配置文件 — plugins标签 四、Mybatis配置文件 — typeAliases标签 五、Mybatis配置文件 — environments标签 六、Mybatis配置文件 — mappers标签 一、Mybatis配置文件 —…

burp抓包https链接不安全解决方法

在浏览器已经导入Burpsuite的证书之后,抓包,浏览器仍然显示抓取https包提示不是私密链接解决方法 适用于没有继续访问的按钮。 方法一: 浏览器输入 chrome://flags 搜索 Allow invalid certificates for resources loaded from localhost.翻译过来就是 允许从本地主机加载资…

2023 年十大目标检测模型!

2023 年十大目标检测模型! 使用深度学习革新对象检测的综合指南。 对象检测示例 “目标检测是计算机视觉中最令人兴奋和最具挑战性的问题之一,而深度学习已成为解决它的强大工具。” 对象检测是计算机视觉中的一项基本任务,涉及识别和定位…

SpringBoot与RabbitMQ 集成以及死信队列,TTL,延迟队列

简单示例 项目结构依赖配置生产者消费者 消息的可靠投递示例 confirmreturn 消费者确认机制消费端限流TTL 单条消息整个队列设置 TTL 死信队列 死信队列的实现步骤 延迟队列消息幂等设计 简单示例 项目结构 依赖 <dependencies><dependency><groupId>org.…

【Linux 裸机篇(一)】ARM Cortex-A 架构基础、汇编基础

目录一、ARM Cortex-A 架构基础1. Cortex-A 处理器运行模型2. Cortex-A 寄存器组2.1 通用寄存器2.1.1 未备份寄存器2.1.2 备份寄存器2.1.3 程序计数器 R152.2 程序状态寄存器二、ARM 汇编基础1. GNU 汇编语法1.1 语句1.2 段1.3 伪操作1.4 函数2. 常用汇编指令2.1 处理器内部数据…