服务器端源码:

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. poj2955 区间dp

    //Accepted 200 KB 63 ms //区间dp //dp[i][j] 从i位到j位能得到的最大匹配数 //dp[i][j]=max(dp[i+1][j-1] (s[i-1]==s[j-1 ...

  2. Android Studio开发环境变量配置

    1,Android Studio官网可以下载 可以选择下载带有SDK版本 2,如果没有配置SDK,AVD虚拟机是没法使用的,真机调试也用不了. 有时会提醒adb is not connected. 和 ...

  3. unity3d角色控制器01

    参考出处貌似是雨松大神.如有侵权,立即删除. 需要导入包 ①将FirstPerson Controller拖拽入Hierarchy(层次视图)中.由于角色控制器是具有一定物理引擎的,所以一定要将它放在 ...

  4. GSM Sniffing入门之硬件篇

    3个月前,听朋友介绍得知OsmocomBB项目.此前一直以为GSM Sniffing需要价格昂贵的专用设备,但osmocomBB的上手成本:一个25元左右的手机,外加一根USB转TTL的串口线,着实让 ...

  5. 数组Mex

    题目描述 请设计一个高效算法,查找数组中未出现的最小正整数. 给定一个整数数组A和数组的大小n,请返回数组中未出现的最小正整数.保证数组大小小于等于500. 测试样例: [-1,2,3,4],4 返回 ...

  6. 利用NTP搭建自己的ntp服务

    利用NTP搭建自己的ntp服务 发表于 2013 年 9 月 22 日 作者 admin 对于校园网/企业用户,如果您网内所有计算机都通过互联网同步时间,在速度和精度上都有一定的折扣,并且对互联网出口 ...

  7. esayui-datagrid的使用

    第一步:在页面上引入easyui的jQuery链接 <script src="../../Scripts/easyUI/jquery-1.7.2.min.js" type=& ...

  8. iOS-appDelegate 生命周期

    - (void)applicationWillResignActive:(UIApplication *)application 说明:当应用程序将要入非活动状态执行,在此期间,应用程序不接收消息或事 ...

  9. 第二个sprint第六天

    讨论地点:qq 讨论成员:邵家文.李新.朱浩龙.陈俊金 今天完成:统计功能前期工作已经完成,暂时对它进行搁置.        开发感悟:今天回了乡下吃了一顿饭,发现还是乡下环境好,比较适合在那种环境下 ...

  10. linux服务器并发与tcmalloc

    前一天使用pmap查看服务器中自己开发的游戏服务的内存使用情况,发现其中数据存储服务的内存占用率非常高,截图如下. 从截图中可以看出来,分配了大量的64MB左右的内存空间,因为对自己的服务比较了解,知 ...