C# Websocket连接实现wss协议
作者:无熵~ 发布时间:2022-09-02 08:20:41
一、什么是Websocket?
1.WebSocket是HTML5下一种新的协议(websocket协议本质上是一个基于tcp的协议)
2.它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯的目的
3.Websocket是一个持久化的协议
二、Websocket、Socket、Http、Mqtt之间的区别?
Socket:
Socket是对tcp/ip协议族的封装的接口,Socket连接可以指定不同的传输层协议,即TCP或UDP,由于它是基于tcp/ip的,所以一般用在局域网内通信。
WebSocket:
WebSocket协议是基于TCP的一种新的网络协议,和http协议一样属于应用层协议,是一种让客户端和服务器之间能进行双向实时通信(全双工)的技术,且支持长连接,可以进行互联网间通信。引入ws和wss分别代表明文和密文的websocket协议,且默认端口使用80或443,几乎与http一致,WebSocket也要有一个握手过程,然后才能正式收发数据,由于数据包头部协议较小,不同于http每次请求需要携带完整的头部,所以网络开销比较少,长连接也让延迟明显更少(不需要重复新建连接)。
MQTT:
MQTT协议是为大量计算能力有限,且工作在低带宽、不可靠的网络的远程传感器和控制设备通讯而设计的协议,它具有以下主要的几项特性:
1.使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合;
2.对负载内容屏蔽的消息传输;
3.使用 TCP/IP 提供网络连接;
HTTP:
HTTP是一个属于应用层的,基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。
通信方式:
1.浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送请求。Web服务器根据接收到的请求后,向客户端发送响应信息。
2.HTTP之请求消息Request:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成。
3.HTTP之响应消息Response:HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。
若connection 模式为close,则服务器会主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求;
三、WS和WSS协议
WS协议和WSS协议两个均是WebSocket协议的SCHEM,两者一个是非安全的,一个是安全的。也是统一的资源标志符。就好比HTTP协议和HTTPS协议的差别。非安全的没有证书,安全的需要SSL证书。(SSL是Netscape所研发,用来保障网络中数据传输的安全性,主要是运用数据加密的技术,能够避免数据在传输过程被不被窃取或者监听。)其中WSS表示在TLS之上的WebSocket。WS一般默认是80端口,而WSS默认是443端口,大多数网站用的就是80和433端口。(在高防防护过程中,80和433端口的网站是需要备案才可以接入国内的。)当然网站也会有别的端口,这种如果做高防是方案是可以用海外高防的。WS和WSS的体现形式分别是TCP+WS AS WS ,TCP+TLS+WS AS WS。服务器网址就是 URL。最后墨者安全再说下WebSocket协议的特点:建立在 TCP 协议之上,服务端实现容易;与 HTTP 协议有良好的兼容性,握手时不容易被屏蔽,可以通过各种 HTTP 代理服务器;数据轻量,实时通讯;可以发送文本和二进制数据。不限制同源,客户端可以与任意服务器端进行通讯。因此WebSocket协议的出现,为很多人解决了关于扩展以及兼容性协议的烦恼问题。
WSS连接:由于wss是基于SSL,所以需要进行双向验证,客户端连接服务端时,我需要添加证书(服务端不验证可以不添加),服务端进行验证。注意:客户也需要对服务端进行验证,所以需要添加服务端证书回调,进行验证,这是很多人忽视,所以出现无法连接远程服务器,TLS/SSL验证失败的提示。
public MainWindow()
{
InitializeComponent();
RemoteCertificateValidationCallback remote = ValidateServerCertificate;
ServicePointManager.ServerCertificateValidationCallback = remote;
}
/// <summary>
/// 服务端验证
/// </summary>
/// <param name="sender"></param>
/// <param name="certificate"></param>
/// <param name="chain"></param>
/// <param name="sslPolicyErrors"></param>
/// <returns></returns>
public bool ValidateServerCertificate( object sender,X509Certificate certificate,X509Chain chain,SslPolicyErrors sslPolicyErrors)
{
return true ;
}
/// <summary>
/// WebSocket客户端连接
/// </summary>
/// <param name="param"></param>
/// <returns></returns>
public async Task Connect()
{
CancellationTokenSource t = new CancellationTokenSource();
try
{
client.Options.SetRequestHeader("key", "value");
X509Certificate2 cert = new X509Certificate2("xxx.cert");
client.Options.ClientCertificates.Add(cert);
Uri uri = new Uri("wss://xxxxxx");
//var config=new ServerConfig
await client.ConnectAsync(uri, t.Token);
Thread.Sleep(300);
Console.WriteLine($"链接websocket:[{uri}] 完成");
Task s1 = new Task(Receive, t, t.Token, TaskCreationOptions.LongRunning);
s1.Start();
token = t;
Console.WriteLine("Send Hello");
}
catch (Exception ex)
{
Console.WriteLine($"链接websocket:[{uri}] 失败", ex.Message);
}
}
/// <summary>
/// Websocket接收
/// </summary>
/// <param name="obj"></param>
private void Receive(object obj)
{
CancellationTokenSource ts = obj as CancellationTokenSource;
byte[] bs = new byte[1024];
while (!ts.Token.IsCancellationRequested)
{
try
{
ArraySegment<byte> buff = new ArraySegment<byte>(bs, 0, bs.Length);
Task<WebSocketReceiveResult> res = client.ReceiveAsync(buff, ts.Token);
res.Wait();
if (ts.Token.IsCancellationRequested)
{
return;
}
if (WebSocketCloseStatus.NormalClosure == res.Result.CloseStatus)
{
Console.WriteLine($"websocket:与服务器断开链接:{res.Result.CloseStatus} --> Desc :{res.Result.CloseStatusDescription}");
ts.Cancel();
return;
}
string strData = encod.GetString(bs, 0, res.Result.Count);
Console.WriteLine(strData);
WsMsg msg = WsMsg.Deserialize(strData);
}
catch (Exception ex)
{
Console.WriteLine("解析或执行 websocket:命令失败", ex);
}
}
}
Websocket客户端与服务端通信代码参考文章:
WebSocket协议:5分钟从入门到精通 - 程序猿小卡 https://www.cnblogs.com/chyingp/p/websocket-deep-in.html
C# WebSocket_熊思雨的博客 https://blog.csdn.net/qq_38693757/article/details/114933642
C# WebSocket - 南国叶子 https://www.cnblogs.com/nanguoyezi/p/9351555.html
来源:https://blog.csdn.net/lvxingzhe3/article/details/124904887
猜你喜欢
- 1. 新建TestServlet类package com.yanek.test;import java.io.IOException;imp
- 前言记得几年前有一次栈长去面试,问到了这么一个问题:Java中的对象都是在堆中分配吗?说明为什么!当时我被问得一脸蒙逼,瞬间被秒杀得体无完肤
- 本文以一个C#的SQL数据库字串操作函数为例,说明如何实现对SQL字符串过滤、检测SQL是否有危险字符、修正sql语句中的转义字符,确保SQ
- 本文实例为大家分享了java通过PDF模板填写PDF表单的具体代码,包括图片,供大家参考,具体内容如下需要用到的java包: it
- Spring概述Spring就是为解决企业应用开发的复杂性而创建的,做为开源中间件,它使用基本的JavaBean来完成以前只可能有EJB(J
- MyBatis 是一款常用的持久层框架,使得程序能够以调用方法的方式执行某个指定的SQL,将执行SQL的底层逻辑进行封装。多数与Spring
- 1、自定义实现该类package com.linmain.dict.handle;import org.apache.ibatis.sess
- 前言我们在很多博客中都有发现,Seata AT模式里面的全局锁其实是行锁,这也是Seata AT模式和XA模式在锁粒度上的最大区别。我们可以
- 本文实例讲述了C#写入对象或集合类型数据到xml文件的方法。分享给大家供大家参考。具体实现方法如下:public static string
- final,static,this,super 关键字总结正文开始@Assassin1. final 关键字:final 关键字,意思是最终
- 前言惰性计算(尽可能延迟表达式求值)是许多函数式编程语言的特性。惰性集合在需要时提供其元素,无需预先计算它们,这带来了一些好处。首先,您可以
- 一:日志:1、配置日志级别日志记录器(Logger)的行为是分等级的。如下表所示:分为:OFF、FATAL、ERROR、WARN、INFO、
- 本文实例讲述了Java设计模式之 * 模式。分享给大家供大家参考,具体如下: * 模式有三个要素——事件源、事件对象、 * 。事件源:顾名思
- JDK * :利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。CGlib * :利用AS
- 骑缝章是用于往来业务合同,以确保合同真实、有效的印章加盖方法,是一种防范风险的重要方式。在Java程序中,可以通过使用工具来辅助加盖这种骑缝
- 简介Spring Security,这是一种基于 Spring AOP 和 Servlet 过滤器的安全框架。它提供全面的安全性解决方案,同
- 文件上传下载前台:1. 提交方式:post2. 表单中有文件上传的表单项: <input type=”file” />3. 指定
- 循环例子:while循环和do…while循环whlie(条件语句) {循环体}//先进行条件语句的判断,再进行循环体do {循环体}whl
- 标题index界面加载问题刚开始学习springBoot记录一下遇到的小问题1.index.html加载不出来的问题我习惯性的将index.
- 一、错误处理原理分析使用SpringBoot创建的web项目中,当我们请求的页面不存在(http状态码为404),或者器发生异常(http状