WebSocket协议、与HTTP对比

news2024/11/14 19:46:31

WebSocket

也可前往本人的个人网站进行阅读

WebSocket 和 HTTP

WebSocket和HTTP协议一样,都是基于TCP协议实现的应用层协议。

HTTP协议通常是单边通信,主要用于传输静态文档、请求-响应通信,适用于Web浏览器加载网页、API调用等。然而WebSocket则是会主动给你发消息,实现实时双向通信,我们经常玩的游戏、使用的聊天软件什么采用的都是这个协议。

这里进行详细比较

共同点:

  1. 基于TCP: WebSocket和HTTP都是基于TCP协议的应用层协议,用于在客户端和服务器之间进行通信。
  2. 使用URI(统一资源标识符): 两者都使用统一资源标识符(URI)来标识资源或服务的位置。
  3. 都是面向应用层的协议: WebSocket和HTTP都属于应用层协议,用于在不同设备或应用程序之间进行通信。

不同点:

  1. 连接性和通信方式:
    • HTTP: 是一种无状态的请求-响应协议。每个HTTP请求都是独立的,服务器在每个请求之后会断开连接,需要在每次请求时重新建立连接。
    • WebSocket: 提供了全双工通信,允许客户端和服务器之间建立持久的连接,可以实现双向实时通信,而不需要为每个消息建立新的连接。
  2. 数据帧格式:
    • HTTP: 通常使用明文文本或基于二进制的数据传输,但每个请求和响应都具有特定的结构。
    • WebSocket: 使用帧(frame)的形式传输数据,可以是文本帧或二进制帧。
  3. 协议头和握手:
    • HTTP: 通过请求头和响应头来传递元数据信息,如请求方法、状态码等。
    • WebSocket: 在建立连接时,使用HTTP进行初始握手,然后切换到WebSocket协议。握手时使用特定的HTTP头部,如Upgrade和Connection。
  4. 目的和应用场景:
    • HTTP: 主要用于传输静态文档、请求-响应通信,适用于Web浏览器加载网页、API调用等。
    • WebSocket: 适用于需要实时、双向通信的应用场景,如实时聊天、在线游戏、股票市场数据更新等。

总的来说,WebSocket和HTTP都是网络通信中的重要协议,但它们在连接性、通信方式和应用场景等方面存在明显的区别。WebSocket更适合实时、双向通信,而HTTP主要用于请求-响应式的通信。

解析

接下来对此协议进行详细讲解,先看图:

https://asdxz.oss-cn-beijing.aliyuncs.com/pic/20240115181050.png

首先客户端(client)发送连接请求,通过HTTP发送到服务端,但是请求头会进行一定改变,比如:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

这其中包含了一些特殊的头部,比如 UpgradeConnection

服务器接收到这个请求后,如果支持WebSocket,就会回复一个HTTP 101状态码(切换协议)以及一些额外的头部,表示同意建立WebSocket连接

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

此过程则称为握手,服务端和客户端握手建立连接之后,连接将一直保持,直到其中一方终止

过程中的数据传输:客户端和服务器可以在连接上自由地发送文本或二进制数据帧。这些数据帧包含消息内容以及一些控制信息,如数据帧的类型和长度等

关闭连接:关闭连接时,终止方会发送一个特殊的关闭帧。

例子

以下是一个golang的例子

package main

import (
	"log"
	"net/http"
	"github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

func handleConnections(w http.ResponseWriter, r *http.Request) {
	// 将HTTP连接升级为WebSocket连接
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Fatal(err)
		return
	}
	defer conn.Close()

	for {
		// 读取客户端发送的消息
		messageType, p, err := conn.ReadMessage()
		if err != nil {
			log.Println(err)
			return
		}

		// 将接收到的消息原样发送回客户端
		if err := conn.WriteMessage(messageType, p); err != nil {
			log.Println(err)
			return
		}
	}
}

func main() {
	http.HandleFunc("/ws", handleConnections)
	log.Println("WebSocket server is running on :8080")
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		log.Fatal("Error starting server: ", err)
	}
}

客户端

package main

import (
	"fmt"
	"log"
	"github.com/gorilla/websocket"
)

func main() {
	// 连接WebSocket服务器
	conn, _, err := websocket.DefaultDialer.Dial("ws://localhost:8080/ws", nil)
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()

	// 向服务器发送消息
	message := []byte("Hello, WebSocket!")
	err = conn.WriteMessage(websocket.TextMessage, message)
	if err != nil {
		log.Fatal(err)
	}

	// 从服务器接收消息
	_, receivedMessage, err := conn.ReadMessage()
	if err != nil {
		log.Fatal(err)
	}

	// 打印接收到的消息
	fmt.Println("Received message from server:", string(receivedMessage))
}

最后效果:

https://asdxz.oss-cn-beijing.aliyuncs.com/pic/20240115224711.png

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

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

相关文章

C++类与对象【运算符重载】

🌈个人主页:godspeed_lucip 🔥 系列专栏:C从基础到进阶 🎄1 运算符重载🌽1.1 加号运算符重载🌽1.2 左移运算符重载🌽1.3 递增运算符重载🌽1.4 赋值运算符重载&#x1f33…

『MySQL快速上手』-⑩-索引特性

文章目录 1.索引的作用2.索引的理解建立测试表插入多条记录查看结果 2.1 MySQL与磁盘交互的基本单位2.1 为何IO交互要是 Page2.3 理解单个Page2.4 理解多个Page2.5 页目录2.6 单页情况2.7 多页情况2.8 B vs B2.9 聚簇索引 vs 非聚簇索引非聚簇索引聚簇索引 3.索引操作3.1 创建主…

C#操作pdf之使用itext实现01-生成一个简单的table

创建.net 8控制台项目 安装itext <PackageReference Include"itext" Version"8.0.2" /><PackageReference Include"itext.bouncy-castle-adapter" Version"8.0.2" /><PackageReference Include"itext.bouncy-cast…

操作系统实验报告

目录 目录 实验一 一、实验结果 实验二 使用信号量实现进程互斥与同步 一、实验结果 1. 使用信号量实现有限缓冲区的生产者和消费者问题 2. 使用信号量实现读进程具有优先权的读者和写者问题 实验三 死锁和预防 一、实验要求 二、实验内容 三、实验结果 实验四 内…

list上

文章目录 初步了解list面试题&#xff1a;为什么会有list&#xff1f;vector的缺点&#xff1a;vector、list优点 list结构迭代器的分类list的简单运用insert、erase、迭代器失效&#xff08;和vector的区别&#xff09;erase class和structlist的迭代器为什么这个迭代器的构造…

go 语言(九)----struct

定义一个结构体 type Book struct {title stringauth string }结构体使用 package mainimport "fmt"//定义一个结构体 type Book struct {title stringauth string }func main() {var book1 Bookbook1.title "Golang"book1.auth "zhang3"fmt…

PSoc62™开发板之i2c通信

实验目的 使用模拟i2c接口读取温湿度气压模块BME280数据 实验准备 PSoc62™开发板温湿度气压模块BME280公母头杜邦线 板载资源 本次实验是通过模拟i2c时序的方式来进行通信&#xff0c;理论上可以有非常多的方式配置i2c引脚&#xff0c;不像硬件i2c那样芯片出厂引脚已经固…

Apache Doris (六十七): DataX DorisWriter - (1) - 源码编译及集成

🏡 个人主页:IT贫道-CSDN博客 🚩 私聊博主:私聊博主加WX好友,获取更多资料哦~ 🔔 博主个人B栈地址:豹哥教你学编程的个人空间-豹哥教你学编程个人主页-哔哩哔哩视频 目录

GetShell的姿势

0x00 什么是WebShell 渗透测试工作的一个阶段性目标就是获取目标服务器的操作控制权限&#xff0c;于是WebShell便应运而生。Webshell中的WEB就是web服务&#xff0c;shell就是管理攻击者与操作系统之间的交互。Webshell被称为攻击者通过Web服务器端口对Web服务器有一定的操作权…

怎么移除WordPress后台工具栏的查看站点子菜单?如何改为一级菜单?

默认情况下&#xff0c;我们在WordPress后台想要访问前端网站&#xff0c;需要将鼠标移动到左上角的站点名称&#xff0c;然后点击下拉菜单中的“查看站点”才行&#xff0c;而且还不是新窗口打开。那么有没有办法将这个“查看站点”子菜单变成一级菜单并显示在顶部管理工具栏中…

数据分析-Pandas如何整合多张数据表

数据分析-Pandas如何整合多张数据表 数据表&#xff0c;时间序列数据在数据分析建模中很常见&#xff0c;例如天气预报&#xff0c;空气状态监测&#xff0c;股票交易等金融场景。数据分析过程中重新调整&#xff0c;重塑数据表是很重要的技巧&#xff0c;此处选择Titanic数据…

Qt拖拽组件与键盘事件

1.相关说明 1.设置widget或view的拖拽和放置模式函数setDragDropMode参数说明&#xff0c;NoDragDrop(无拖拽和放置)、DragOnly(只允许拖拽)、DropOnly(只允许放置)、DragDrop(允许拖拽和放置)、InternalMove(只移动不复制) 2.设置widget或view的放置动作函数setDefaultDropAct…

小周带你读论文-2之“草履虫都能看懂的Transformer老活儿新整“Attention is all you need(2)

书接前文&#xff1a;小周带你读论文-2之"草履虫都能看懂的Transformer老活儿新整"Attention is all you need(1) (qq.com) 上文书说到为什么我们要用casual-decoder架构&#xff0c;把Transformer的左边给省略了&#xff0c;于是得到下图这样的架构 上图是GPT-1的模…

leetcode2312卖木头块

其实不难&#xff0c;主要是你得一眼看出来这个问题缩小规模然后就可以用DP来做了 using ll long long; class Solution { public:long long sellingWood(int m, int n, vector<vector<int>>& prices) {ll f[m10][n10];ll p[m10][n10];memset(p,0,sizeof p)…

AI时代—ChatGPT-4.5的正确打开方式

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言4.5key价格泄漏ChatGPT4.0使用地址ChatGPT正确打开方式最新功能语音助手存档…

数据结构——Java实现栈和队列

一、栈 Stack 1.特点 &#xff08;1&#xff09;栈是一种线性数据结构 &#xff08;2&#xff09;规定只能从栈顶添加元素&#xff0c;从栈顶取出元素 &#xff08;3&#xff09;是一种先进后出的数据结构&#xff08;Last First Out&#xff09;LIFO 2.具体实现 Java中可…

win系统环境搭建(十二)——Windows系统下使用docker安装redis

windows环境搭建专栏&#x1f517;点击跳转 win系统环境搭建&#xff08;十二&#xff09;——Windows系统下使用docker安装redis 文章目录 win系统环境搭建&#xff08;十二&#xff09;——Windows系统下使用docker安装redis1.创建文件夹2.docker-compose.yaml配置文件3.red…

《WebKit 技术内幕》之四(1): 资源加载和网络栈

第四章 资源加载和网络栈 使用网络栈来下载网页和网页资源是渲染引擎工作的第一步 1.WebKit 资源加载机制 1.1 资源 网页本身就是一种资源、网页还需要依赖很多其他的资源(图片、视频) &#xff08;1&#xff09;HTML 支持的资源主要包括以下几种类型&#xff1a; HTML 页…

【动态规划】【C++算法】741摘樱桃

作者推荐 【动态规划】【数学】【C算法】18赛车 涉及知识点 动态规划 LeetCode741 摘樱桃 给你一个 n x n 的网格 grid &#xff0c;代表一块樱桃地&#xff0c;每个格子由以下三种数字的一种来表示&#xff1a; 0 表示这个格子是空的&#xff0c;所以你可以穿过它。 1 表…

Golang 搭建 WebSocket 应用(六) - 监控

我在上一篇文章中&#xff0c;提到了目前的认证方式存在一些问题&#xff0c;需要替换为一种更简单的认证方式。 但是最后发现&#xff0c;认证这个实在是没有办法简单化&#xff0c;认证本身又是另外一个不小的话题了&#xff0c;因此关于这一点先留个坑。 本文先讨论一下另外…