zoukankan      html  css  js  c++  java
  • C# websocket Server 加密 76号协议

    服务器端源码:

    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();
                }
            }
        }
    }

  • 相关阅读:
    基础_String
    tomcat缓存
    jquery绑定事件
    Java面试之基础题---对象Object
    Java设计模式学习三-----工厂模式
    网络基础学习---各种概念
    Java设计模式学习二
    Hibernate框架的主键生成策略
    Hibernate的Session的get()和load()方法区别
    Hibernate 框架理解
  • 原文地址:https://www.cnblogs.com/kuangwu/p/3280647.html
Copyright © 2011-2022 走看看