websocket协议简介
概念介绍
- 单工通信:数据传输只允许在一个方向上传输,只能一方发送数据,另一方接收数据并发送。
- 半双工:数据传输允许两个方向上的传输,但在同一时间内,只可以有一方发送或接收数据。
- 全双工:同时可进行双向数据传输。
websocket介绍
- WebSocket协议在2008年诞生,2011年成为国际标准。
- WebSocket是一种在单个TCP连接上进行全双工通信的协议,位于 OSI 模型的应用层。
- WebSocket的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息。
出现背景
- HTTP 协议是一种无状态的、无连接的、单向的应用层协议。它采用了请求/响应模型。通信请求只能由客户端发起,服务端对请求做出应答处理。
- 这种通信模型有一个弊端:HTTP 协议无法实现服务器主动向客户端发起消息。很多网站为了实现推送技术,所用的技术都是轮询。即在特定得时间间隔,由浏览器对服务器发出http请求。
websocket与HTTP比较
http不同版本简介
相同点
- 都是一样基于TCP的,都是可靠性传输协议。
- 都是应用层协议。
不同点
- websocket 是持久连接,http 是短连接;
- websocket 的协议是以 ws/wss 开头,http 对应的是 http/https;
- websocket 是有状态的,http 是无状态的;
- websocket 连接之后服务器和客户端可以双向发送数据,http 只能是客户端发起一次请求之后,服务器才能返回数据;
- websocket 连接建立之后,不需要再发送request请求,数据直接从TCP通道传输。
联系
- WebSocket在建立握手时,数据是通过HTTP传输的。
websocket握手过程
- 1、浏览器、服务器建立TCP连接,三次握手。这是通信的基础,传输控制层,若失败后续都不执行。
- 2、TCP连接成功后,浏览器通过HTTP协议向服务器传送WebSocket支持的版本号等信息。(开始前的HTTP握手)
- 3、服务器收到客户端的握手请求后,同样采用HTTP协议回馈数据。
- 4、当收到了连接成功的消息后,通过TCP通道进行传输通信。
HTTP协议头
http协议头详解
请求
- Accept: text/html,application/xhtml+xml,application/xml
- Accept-Encoding: gzip, deflate, br
- Accept-Language: zh-CN,zh;q=0.9
- Connection: keep-alive
- Host: www.baidu.com
- User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36
响应
- Connection: keep-alive
- Content-Encoding: gzip
- Content-Type: text/html;charset=utf-8
- Date: Sat, 16 Apr 2022 10:43:46 GMT
- Server: BWS/1.1
websocket协议头
请求
- *Accept-Encoding: gzip, deflate
- *Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
- Connection: Upgrade
- Host: 192.168.1.2:8080
- Sec-WebSocket-Key: 821VqJT7EjnceB8m7mbwWA==
- Sec-WebSocket-Version: 13
- Upgrade: websocket
- User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.75 Safari/537.36 Edg/100.0.1185.39
响应
- Connection: Upgrade
- Date: Sat, 16 Apr 2022 10:49:05 GMT
- Sec-WebSocket-Accept: paFykwJusIMnfpohWxA5HVpjD1Q=
- Server: Server
- Upgrade: websocket
websocket头详解
- 请求头详解
- Upgrade: 向服务器指定协议类型,告诉web服务器当前使用的是websocket协议
- Sec-WebSocket-Key:是一个 Base64 encode 的值,这个是浏览器随机生成的
- Sec-WebSocket-Version:websocket协议版本
- 响应头详解(web服务返回状态码101表示协议切换成功)
- Sec-WebSocket-Accept: 是经过服务器确认,并且加密过后的 Sec-WebSocket-Key。用来证明客户端和服务器之间能进行通信了。
代码展示
服务端
服务端程序是通过QT实现
- websocketservice.h
#ifndef WEBSOCKETSERVER_H
#define WEBSOCKETSERVER_H#include <QWidget>
#include <QWebSocketServer>
#include <QWebSocket>
#include <QHostInfo>
#include <QNetworkInterface>namespace Ui {
class WebSocketServer;
}class WebSocketServer : public QWidget
{Q_OBJECTpublic:explicit WebSocketServer(QWidget *parent = 0);~WebSocketServer();private slots:void on_pushButton_startListen_clicked();void onNewConnection();void onTextMessageReceived(QString msg);void onDisconnected();void on_pushButton_send_clicked();private:Ui::WebSocketServer *ui;QWebSocketServer *server;QWebSocket *socket;QList<QWebSocket*> clientList;QString mAddr;int mPort;
};#endif // WEBSOCKETSERVER_H
- websocketservice.cpp
#include "websocketserver.h"
#include "ui_websocketserver.h"WebSocketServer::WebSocketServer(QWidget *parent) :QWidget(parent),ui(new Ui::WebSocketServer)
{ui->setupUi(this);ui->pushButton_send->setEnabled(false);//获取本机IP和端口QString hostName = QHostInfo::localHostName(); //获取主机名QHostInfo hostInfo = QHostInfo::fromName(hostName); //获取主机信息QList<QHostAddress> addList = hostInfo.addresses(); //获取IP地址列表QString localIP;if(!addList.isEmpty()){for(int i = 0; i < addList.count();i++){QHostAddress aHost = addList.at(i);if(QAbstractSocket::IPv4Protocol == aHost.protocol()){localIP = aHost.toString();break;}}}ui->lineEdit_url->setText(localIP);ui->lineEdit_port->setText("8080");//构造:QWebSocketServer(const QString& serverName,QWebSocketServer::SslMode secureMode,QObject *parent=nullptr)//使用给定的serverName构造一个新的QWebSocketServer。//该服务器名称将在HTTP握手阶段被用来识别服务器。它可以为空,此时不会将服务器名称发送给客户端。//SslMode指示服务器是通过wss(SecureMode)还是ws(NonSecureMode)运行//QWebSocketServer::SecureMode服务器以安全模式运行(通过wss)//QWebSocketServer::NonSecureMode服务器以非安全模式运行(通过ws)server=new QWebSocketServer("Server",QWebSocketServer::NonSecureMode,this);//有新的连接connect(server,&QWebSocketServer::newConnection,this,&WebSocketServer::onNewConnection);
}WebSocketServer::~WebSocketServer()
{delete ui;
}void WebSocketServer::on_pushButton_startListen_clicked()
{QHostAddress address = QHostAddress(ui->lineEdit_url->text());if(server->listen(address, ui->lineEdit_port->text().toInt())){ui->pushButton_startListen->setEnabled(false);ui->pushButton_startListen->setText("disListen");}
}void WebSocketServer::onNewConnection()
{socket=server->nextPendingConnection();mAddr = socket->peerAddress().toString();mPort = socket->peerPort();ui->plainTextEdit_clientStatus->appendPlainText("[" + mAddr + ":" + QString::number(mPort) + "]" + " connected...");ui->pushButton_send->setEnabled(true);connect(socket,&QWebSocket::textMessageReceived, this, &WebSocketServer::onTextMessageReceived);ui->plainTextEdit_sendMsg->clear();ui->plainTextEdit_sendMsg->appendPlainText("welcome to connect Server!");//断开连接时connect(socket,&QWebSocket::disconnected, this, &WebSocketServer::onDisconnected);
}void WebSocketServer::onTextMessageReceived(QString msg)
{ui->plainTextEdit_recvMsg->appendPlainText(msg);
}void WebSocketServer::onDisconnected()
{ui->plainTextEdit_clientStatus->appendPlainText("[" + mAddr + ":" + QString::number(mPort) + "]" + " disConnected!");
}void WebSocketServer::on_pushButton_send_clicked()
{socket->sendTextMessage(ui->plainTextEdit_sendMsg->toPlainText());
}
客户端
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Qt WebSocket Demo</title>
</head><body><input type="text" id="edit_url" value="ws://192.168.1.2:8080" /><input type="button" id="btn_open" value="open" onclick="doOpen()" /><br /><p>Recv:</p><br /><textarea id="edit_recv" cols="50" rows="10"></textarea><br /><p>Send:</p><br /><textarea id="edit_send" cols="50" rows="10">Hello, I am websocket Client!</textarea><br /><input type="button" value="Send" onclick="doSend()" /><script>var edit_url = document.getElementById("edit_url");var btn_open = document.getElementById("btn_open");var edit_recv = document.getElementById("edit_recv");var edit_send = document.getElementById("edit_send");var client = null;function doOpen() {console.log("open")if (!("WebSocket" in window)) {//不支持WebSocketconsole.log("no websocket")return;}if (client === null) {client = new WebSocket(edit_url.value);client.onopen = function () {btn_open.value = "Close";}//收到数据后追加到尾巴上client.onmessage = function (event) {edit_recv.value += String(event.data);}client.onclose = function () {client = null;btn_open.value = "Open";}} else {client.close();client = null;}}function doSend() {console.log("send")if (client === null)return;client.send(edit_send.value);}</script>
</body></html>
演示
- 可以看到只需发一次request请求,后续就不需要再发request请求,可以直接进行数据的传输,并且服务端也能主动发送消息给客户端
websocket协议简介相关推荐
- websocket协议以及在gin中的应用
目录 websocket协议简介 WebSocket 协议的来源 短轮询 本质 实现 应用场景 优缺点 长轮询 本质 实现 应用场景 优缺点 WebSocket协议 websocket定义及与HTPP ...
- 计算机网络整理:HTTP协议、HTTPS协议、Websocket协议
系列文章目录 UDP协议和TCP协议 文章目录 系列文章目录 一:http协议和https协议的区别 二:http协议 1.http的报文段 1)请求报文 1.请求方法 2.URL 3.协议版本 4. ...
- websocket ws 协议 简介
一.内容概览 WebSocket的出现,使得浏览器具备了实时双向通信的能力.本文由浅入深,介绍了WebSocket如何建立连接.交换数据的细节,以及数据帧的格式.此外,还简要介绍了针对WebSocke ...
- WebSocket API简介
WebSocket是html5新增加的一种通信协议,目前流行的浏览器都支持这个协议,例如Chrome,Safari,Firefox,Opera,IE等等,对该协议支持最早的应该是chrome,从chr ...
- 【 ➰斗艳争妍の网络协议姐妹花️➰】http协议 VS websocket协议
http协议 http简介 http http(hypertext transfer protocol),"超文本传输协议". 超文本 包含有超链接和各种多媒体元素标记的文本.常见 ...
- websocket的简介与应用
1.为什么使用websocket 前端和后端的交互模式最常见的就是前端发数据请求,从后端拿到数据后展示到页面中.如果前端不做操作,后端不能主动向前端推送数据,这恰恰就是http协议的缺陷.但在我们平常 ...
- 【协议】WebSocket协议总结
WebSocket协议总结 一.简介 二.单工.半双工.全双工的区别 三.请求格式 四.使用python实现简单的websocket客户端和服务端 一.简介 WebSocket是一种在单个TCP连接上 ...
- Spring Boot实战之基于WebSocket协议构建交互式Web应用
本文阅读时间大约8分钟. 1. WebSocket简介 WebSocekt协议诞生于2008年,在2011年成为国际标准,目前所有的浏览器都已经支持WebSocket协议了.WebSocket协议属于 ...
- WebSocket 协议
1.1 背景知识 由于历史原因,在创建一个具有双向通信机制的 web 应用程序时,需要利用到 HTTP 轮询的方式.围绕轮询产生了 "短轮询" 和 "长轮询". ...
最新文章
- 【Python 第8课】while
- 阿里面试: 说说强引用、软引用、弱引用、虚引用吧
- 32位so库兼容64位使用
- xshell连接服务器失败_xshell-ssh连接服务器被经常意外中断
- 列表推导式与生成表达式的区别
- 服务降级-降级的概念
- php mysql query 创建_借助PHP的mysql_query()函数来创建MySQL数据库的教程_MySQL
- 前端基础7:a标签常用方法和元素居中方式,响应式@media
- 江西师范大学2017年C语言考试,2018年江西师范大学程序设计(C语言)考研初试大纲...
- 中台之上(五):业务架构和中台的难点,都是需要反复锤炼出标准模型
- JS 父子(弹出)窗口操作总结
- 回头再说-006 时间音乐
- Sublime Text快捷键
- c语言+Easy X图形库实现飞机大战,源码加素材
- MULTISIM下载安装
- Nanopore sequencing and assembly of a human genome with ultra-long reads
- 不重启Windows使环境变量快速生效
- Linux 桌面图标分类
- springboot 长轮询实现
- 推荐 | CSP-JS信奥赛教材
热门文章
- 微信小程序最新获取头像昵称方式
- nodejs 游戏框架_NODEJS各种框架
- mac 4k分辨率 字太小 27寸 hidpi_电视机4a和4k的区别
- login with google
- @Transactional
- outlook阅读为html,Office 2010: outlook中设置邮件格式为HTML、RTF、纯文本
- 新年趣事之打牌【01背包】【输出方案】
- (三十五:2021.01.12)MICCAI 2019学习(一)《前列腺近距离放射治疗中粒子定位的深度回归模型》
- 用telnet命令发送邮件
- 蓝桥杯web:第九题【算法题】小兔子爬楼梯