服务器端源码:

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. uart与usart

    字面意义:UART:universal asynchronous receiver and transmitter通用异步收发器:USART:universal synchronous asynchr ...

  2. Bayeux

    Bayeux是一种用来在客户端和服务器端传输低延迟的异步消息(主要通过http)的一种协议.它定义的消息通过命名通道进行路由并且能够进行交互传 送:server -> client, clien ...

  3. (转)js函数参数设置默认值

    原文:http://www.cnblogs.com/RightDear/archive/2013/06/26/3156652.html js函数参数设置默认值   php有个很方便的用法是在定义函数时 ...

  4. (spring-第15回【IoC基础篇】)容器事件

    五个人在报社订阅了报纸.报社一旦有了新报纸,就派员工分别送到这五个人手里.在这个例子中,“报纸”就是事件,“报社”就是广播器,五个订阅者就是监听器.广播器收到事件,把事件传给监听器,监听器对事件做一些 ...

  5. (spring-第13回【IoC基础篇】)PropertyEditor(属性编辑器)--实例化Bean的第五大利器

    上一篇讲到JavaBeans的属性编辑器,编写自己的属性编辑器,需要继承PropertyEditorSupport,编写自己的BeanInfo,需要继承SimpleBeanInfo,然后在BeanIn ...

  6. win7下环境搭建

    1.Python下载 https://www.python.org/downloads/windows/ 选择需要安装的版本,我偷懒装的可执行文件. 下载之后双击安装就OK啦,安装过程中有一项偷懒的选 ...

  7. C#泛型(二)

    <1>.泛型方法 以前文章说到用一个泛型类 SortHelper 来做一个冒泡排序的处理,下面回顾一下之前的代码: public class SortHelper<T> whe ...

  8. CoreData的使用入门到精通

    源码下载地址: http://download.csdn.net/download/huntaiji/6664567 一,创建项目文件--选择Empty Application  起名:CoreDat ...

  9. UITableView详解(1)

    一,UITableView控件使用必备,红色部分是易错点和难点 首先创建一个项目,要使用UITableView就需要实现协议<UITableViewDataSource>,数据源协议主要完 ...

  10. magento日常使用

    magento order number长度(修改)设置 2013年3月15日星期五 Asia/Shanghai上午10时22分02秒 1-进入要修改的该网站的数据库:2-找到表名:eav_entit ...