服务器端源码:

76号协议增加了加密字段

sec-websocket-key1

sec-websocket-key2

以及最后8个字节

服务器必须在握手信息之后发送回解密信息才能握手成功。

解密方式

key1 是 sec-websocket-key1 后面所有字节

key2 是 sec-websocket-key2 后面所有字节

part1 为 key1内除去所有的非数字字符后得到的数字 long型 / key1内空字符长度 int型

part2 为 key2内除去所有的非数字字符后得到的数字 long型 / key1内空字符长度 int型

part1 转换为byte[] byte1 (例:byte1 = {1,2,3,4})

part2 转换为byte[] byte2

byte1、byte2内值倒转(例:byte1 = {4,3,2,1})

byte3 是 客户端发送过来的最后8个字节

byte1、byte2、byte3 拼装为16个字节 byteKey[16]

byteKey[] 进行 MD5 加密 得 byteMD5[]

byteMD5[] 放置在握手协议最后端发送回去

C#  cs:

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Web.Security;
using System.IO;
namespace Room
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("服务器启动中...");
            IPEndPoint ipe = new IPEndPoint(IPAddress.Parse("192.168.1.80"), 2000);
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.Bind(ipe);
            socket.Listen(60);
            Console.WriteLine("服务器启动完毕...");
            bool isfirst = true;
            bool run = true;
            try
            {
                Socket a = socket.Accept();
                while (run)
                {
                    byte[] bytes = new byte[1024];
                    int bytelength = a.Receive(bytes);
                    Console.WriteLine("接收完毕。");
                    #region websocket握手
                    if (isfirst)
                    {
                        string recStr = Encoding.UTF8.GetString(bytes, 0, bytelength);
                        string[] ss = recStr.Split(Environment.NewLine.ToCharArray());
                        string k1 = ss[10].Substring(20);
                        string k2 = ss[12].Substring(20);
                        byte[] last = new byte[8];
                        for (int i = 0; i < 8; i++)
                        {
                            last[i] = bytes[bytelength - 8 + i];
                        }
                        uint key1 = (uint)(long.Parse(FilterNonNumber(k1)) / FilterNonEmpty(k1).Length);
                        uint key2 = (uint)(long.Parse(FilterNonNumber(k2)) / FilterNonEmpty(k2).Length);
                        byte[] byteTemp1 = BitConverter.GetBytes(key1);
                        byte[] byteKey1 = new byte[4];
                        byte[] byteTemp2 = BitConverter.GetBytes(key2);
                        byte[] byteKey2 = new byte[4];
                        for (int i = 0; i < 4; i++)
                        {
                            byteKey1[i] = byteTemp1[3 - i];
                            byteKey2[i] = byteTemp2[3 - i];
                        }
                        MemoryStream ms = new MemoryStream();
                        ms.Write(byteKey1, 0, 4);
                        ms.Write(byteKey2, 0, 4);
                        ms.Write(last, 0, 8);
                        ms.Flush();
                        byte[] byteMs = ms.ToArray();
                        ms.Dispose();
                        MD5 md5 = MD5.Create();
                        byte[] md = md5.ComputeHash(byteMs);
                        MemoryStream ms1 = new MemoryStream();
                        string sendStr = "HTTP/1.1 101 WebSocket Protocol Handshake/r/nUpgrade: WebSocket/r/nConnection: Upgrade/r/nSec-WebSocket-Origin: null/r/nSec-WebSocket-Location: ws://192.168.1.80:2000//r/n/r/n";
                        byte[] temp = Encoding.UTF8.GetBytes(sendStr);
                        ms1.Write(temp, 0, temp.Length);
                        ms1.Write(md, 0, md.Length);
                        ms1.Flush();
                        byte[] byteSend = ms1.ToArray();
                        ms1.Dispose();
                        a.Send(byteSend, byteSend.Length, 0);
                        Console.WriteLine("发送完毕。");
                        isfirst = false;
                    }
                    #endregion
                    else
                    {
                        if (bytelength > 2)
                        {
                            string recStr = Encoding.UTF8.GetString(bytes, 1, bytelength - 2);
                            MemoryStream ms2 = new MemoryStream();
                            string strSend = "发送回去的是中文。";
                            byte[] byteSend = Encoding.UTF8.GetBytes(strSend);
                            ms2.WriteByte(0);
                            ms2.Write(byteSend, 0, byteSend.Length);
                            ms2.WriteByte(255);
                            ms2.Flush();
                            a.Send(ms2.ToArray());
                            ms2.Dispose();
                            if (recStr.Equals("exit"))
                            {
                                run = false;
                                Console.WriteLine("用户已退出。");
                            }
                            else
                            {
                                Console.WriteLine("接收到:" + recStr);
                            }
                        }
                        else
                        {
                            run = false;
                            Console.WriteLine("用户已退出。");
                        }
                    }
                }
                Console.ReadLine();
                a.Close();
                socket.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                socket.Close();
            }
        }
        public static string FilterNonNumber(string str)
        {
            if (str == null)
            {
                return "";
            }
            char[] c = str.ToCharArray();
            StringBuilder sb = new StringBuilder();
            for (int i = 0, len = c.Length; i < len; i++)
            {
                if (char.IsNumber(c[i]))
                {
                    sb.Append(c[i]);
                }
            }
            return sb.ToString();
        }
        public static string FilterNonEmpty(string str)
        {
            if (str == null)
            {
                return " ";
            }
            char[] c = str.ToCharArray();
            StringBuilder sb = new StringBuilder();
            for (int i = 0, len = c.Length; i < len; i++)
            {
                if (c[i] == ' ')
                {
                    sb.Append(c[i]);
                }
            }
            if (sb.ToString().Length == 0)
            {
                return " ";
            }
            else
            {
                return sb.ToString();
            }
        }
    }
}

C# websocket Server 加密 76号协议的更多相关文章

  1. Microsoft SQL Server 数据库 错误号大全

    panchzh :Microsoft SQL Server 数据库 错误号大全0 操作成功完成. 1 功能错误. 2 系统找不到指定的文件. 3 系统找不到指定的路径. 4 系统无法打开文件. 5 拒 ...

  2. GIN+GORILLA=A GOLANG WEBSOCKET SERVER

    鉴于聊天已然成为大部分app的基础功能,而大部分app用户基数有没有辣么大,常用的聊天server架构如xmpp或者消息队列实现之类的用起来还挺麻烦的,有比较难跟网页端做交互,加之H5标准落地,所以w ...

  3. swoole之建立 websocket server

    一.代码部分 <?php /** * 为什么用WebSocket? * HTTP的通信只能由客户端发起 * * WebSocket 协议是基于TCP的一种新的网络协议.实现了浏览器与服务器全双工 ...

  4. 查看SQL SERVER 加密存储过程,函数,触发器,视图

    原文:查看SQL SERVER 加密存储过程,函数,触发器,视图 create  PROCEDURE sp_decrypt(@objectname varchar(50))ASbeginset noc ...

  5. 使用Jetty搭建Java Websocket Server,实现图像传输

    https://my.oschina.net/yushulx/blog/298140 How to Implement a Java WebSocket Server for Image Transm ...

  6. SQL Server 加密案例解析

    一.概述 加密是一种安全措施,有时候甚至是法律要求.作为攻破Windows系统的最后一道防线,通过加密可以保证在没有密钥的情况下获取备份或者物理介质变得毫无意义. 二.概念 加密层次结构 加密层次结构 ...

  7. SpringBoot报错:Failed to load ApplicationContext(javax.websocket.server.ServerContainer not available)

    引起条件: WebSocket+单元测试,单元测试报错! 解决方法: SpringBootTest增加webEnvironment参数. https://docs.spring.io/spring-b ...

  8. io.undertow.websockets.jsr.ServerWebSocketContainer cannot be cast to org.apache.tomcat.websocket.server.WsServerContainer

    Caused by: java.lang.ClassCastException: io.undertow.websockets.jsr.ServerWebSocketContainer cannot ...

  9. SQL SERVER孤立帐号的处理

    Step1:查询 Use KSHR_F23 Go exec sp_change_users_login @Action='Report' Go Step2:处理 Use KSHR_F23 Go exe ...

随机推荐

  1. (spring-第6回【IoC基础篇】)BeanDefinition——实例化Bean之前的第一大利器。

    上节讲了Bean实例化的内部机制,这里再复述一遍: ResourceLoader从系统中加载XML配置信息,并由Resource来表示. BeanDefinitionReader从Resource中读 ...

  2. 学习php前需要了解的知识

    1.静态网站与动态网站 A)静态网站: 不支持数据交互的网站(后缀:   .html  .htm) B)动态网站: 支持数据交互的网站,动态网站可以放静态网页的 i.实现动态网站的技术 1.Asp   ...

  3. 初始React Native

    1.何是React Native: React-Native是:Facebook 在2015年初React.js技术研讨大会上公布的一个开源项目.支持用开源的JavaScript库React.js来开 ...

  4. Sheet can not be presented because the view is not in a window的解决办法,和window的简单使用

    Sheet can not be presented because the view is not in a window,顺便在stackoverflow上找了答案,希望能给大家带来帮助,在此感谢 ...

  5. Windows 2008 R2防火墙,允许被ping

    netsh firewall set icmpsetting 8 1.         准备 1)         原因 出于安全因素考虑,在Windows 2008 R2上是不允许从外部对其Ping ...

  6. 学习笔记:iPhone终极指南、手机端、浏览器各种规范

    手机图解参考:http://www.paintcodeapp.com/news/iphone-6-screens-demystified 手机图标尺寸参考:https://developer.appl ...

  7. Java 集合深入理解(10):Deque 双端队列

    点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 什么是 Deque Deque 是 Double ended queue (双端队列) 的缩写,读音和 deck 一样,蛋 ...

  8. Unity3D ShaderLab 基础的高光实现

    Unity3D ShaderLab 基础的高光实现 关于高光: 在一个物体表面的高光属性就是为了描述它是如何表现光泽.这种类型的效果在着色器的世界中通常称为视点相关效果. 之所以这样说,是因为为了实现 ...

  9. C#里partial关键字的作用(转摘)

    C#里partial关键字的作用(转摘) 1. 什么是局部类型? C# 2.0 引入了局部类型的概念.局部类型允许我们将一个类.结构或接口分成几个部分,分别实现在几个不同的.cs文件中. 局部类型适用 ...

  10. Word embedding blog

    http://colah.github.io/posts/2014-07-NLP-RNNs-Representations/ https://www.quora.com/What-is-the-def ...