C# WebSocket草稿76握手混淆

C# WebSocket草稿76握手混淆,c#,html,websocket,C#,Html,Websocket,我想我大概是这里第一百万个有问题的人了;我真的希望有人能帮我 无论如何;我有一台C#服务器,我正试图让它与WebSocket一起正常工作,不幸的是,我无法让这该死的东西建立连接!扯掉我的头发也没用 internal class Request { private delegate void _create_request(Request request); private Request(_create_request create_functi

我想我大概是这里第一百万个有问题的人了;我真的希望有人能帮我

无论如何;我有一台C#服务器,我正试图让它与WebSocket一起正常工作,不幸的是,我无法让这该死的东西建立连接!扯掉我的头发也没用

    internal class Request
    {
        private delegate void _create_request(Request request);

        private Request(_create_request create_function)
        {
            Headers = new Dictionary<string, string>();
            Headers["Upgrade"] = null;
            Headers["Connection"] = null;
            Headers["Host"] = null;
            Headers["Origin"] = null;
            Headers["Sec-WebSocket-Key1"] = null;
            Headers["Sec-WebSocket-Key2"] = null;
            Headers["Sec-WebSocket-Protocol"] = null;
            Success = false;
            Secure = false;
            Method = "GET";
            Code = new byte[8];

            create_function(this);
        }

        /// <summary>
        /// the code value is the last 8 bytes of the packet
        /// </summary>
        public byte[] Code { get; internal set; }

        /// <summary>
        /// the resource is the directory being associated with optional extension
        /// eg: ws://localhost:90/[resource]
        /// </summary>
        public string Resource { get; internal set; }

        /// <summary>
        /// the resource is the directory being associated with optional extensions
        /// </summary>
        public bool Success { get; internal set; }

        /// <summary>
        /// this value can either be "GET"
        /// </summary>
        public string Method { get; internal set; }

        /// <summary>
        /// is this connection using a wss:// or ws:// configuration
        /// </summary>
        public bool Secure { get; internal set; }

        /// <summary>
        /// these values contain information about our connection
        /// </summary>
        public Dictionary<string, string> Headers { get; internal set; }

        /// <summary>
        /// this value will give you the responce buffer to pass to the WebSocket server
        /// </summary>
        public byte[] Response
        {
            get
            {
                if (!Success)
                {
                    return null;
                }

                byte[] key_value1 = _get_key_value(Headers["Sec-WebSocket-Key1"]);
                byte[] key_value2 = _get_key_value(Headers["Sec-WebSocket-Key2"]);
                byte[] concatenatedKeys = new byte[16];

                Array.Copy(key_value1, 0, concatenatedKeys, 0, 4);
                Array.Copy(key_value2, 0, concatenatedKeys, 4, 4);
                Array.Copy(Code, 0, concatenatedKeys, 8, 8);

                // MD5 Hash
                System.Security.Cryptography.MD5 MD5Service = System.Security.Cryptography.MD5.Create();
                byte[] challenge_buffer = MD5Service.ComputeHash(concatenatedKeys);

                string response = "HTTP/1.1 101 WebSocket Protocol Handshake\r\n";
                response += "Upgrade: WebSocket\r\n";
                response += "Connection: Upgrade\r\n";
                response += "Sec-WebSocket-Origin: " + Headers["Origin"] + "\r\n";

                string location = ((Secure) ? "wss://" : "ws://") + Headers["Host"] + "/" + Resource;
                response += "Sec-WebSocket-Location: " + location + "\r\n";

                string protocol = Headers["Sec-WebSocket-Protocol"];
                if (Headers["Sec-WebSocket-Protocol"] == null)
                {
                    protocol = "*";
                }
                response += "Sec-WebSocket-Protocol: " + protocol.Trim(' ') + "\r\n";
                response += "\r\n";

                byte[] response_buffer = new byte[response.Length + 16];
                Array.Copy(Encoding.ASCII.GetBytes(response), 0, response_buffer, 0, response.Length);
                Array.Copy(challenge_buffer, 0, response_buffer, response.Length, 16);

                return response_buffer;
            }
        }

        internal byte[] _get_key_value(string key)
        {
            byte[] value = new byte[4];
            ulong r = 0;
            ulong s = 0;
            for (int i = 0; i < key.Length; ++i)
            {
                if (key[i] > '0' && key[i] < '9')
                {
                    r = r * 10 + key[i] - '0';
                }
                else if (key[i] == ' ')
                {
                    s++;
                }
            }
            value = BitConverter.GetBytes(r / s);
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(value);
            }
            return value;
        }

        /// <summary>
        /// this function will instantiate a new request object, from request data
        /// </summary>
        /// <param name="data">the request data</param>
        /// <returns></returns>
        internal static Request Instantiate(byte[] data)
        {
            string sdata = Encoding.ASCII.GetString(data);
            return new Request(delegate(Request request)
            {
                string _regex_descriptor = @"^([^ ]+)\s\/([^ ]+)\sHTTP/1.1";
                string _regex_header = @"\n([^:]+):\s([^\r\n]+)";

                string _regex_secure = "^ws([^:]+)?:\\/\\/";
                Match match_descriptor = Regex.Match(sdata, _regex_descriptor);
                MatchCollection match_headers = Regex.Matches(sdata, _regex_header);

                if (match_descriptor.Success)
                {
                    request.Method = match_descriptor.Groups[1].Value;
                    request.Resource = match_descriptor.Groups[2].Value;
                    //Console.WriteLine("Method = " + request.Method);
                    //Console.WriteLine("Resource = " + request.Resource);
                }
                else return;
                if (match_headers.Count > 0)
                {
                    foreach (Match match in match_headers)
                    {
                        if (match.Success)
                        {
                            if (match.Groups[1].Value == "Host")
                            {
                                Match match_secure = Regex.Match(match.Groups[2].Value, _regex_secure);
                                if (match_secure.Success)
                                {
                                    request.Secure = (match_secure.Groups[1].Value == "s");
                                }
                            }
                            request.Headers[match.Groups[1].Value] = match.Groups[2].Value;
                            //Console.WriteLine("Header[\"" + match.Groups[1].Value + "\"] = " + match.Groups[2].Value);
                        }
                    }
                }
                else return;

                Array.Copy(data, data.Length - 8, request.Code, 0, 8);

                request.Success = true;
            });
        }
    }
内部类请求
{
私人委托无效(创建)请求(请求);;
私有请求(创建请求创建函数)
{
Headers=新字典();
标题[“升级”]=null;
头文件[“连接”]=null;
标题[“主机”]=null;
标题[“源”]=null;
标题[“Sec-WebSocket-Key1”]=null;
标题[“Sec-WebSocket-Key2”]=null;
标头[“Sec WebSocket协议”]=null;
成功=错误;
安全=错误;
方法=“获取”;
代码=新字节[8];
创建_函数(此函数);
}
/// 
///代码值是数据包的最后8个字节
/// 
公共字节[]代码{get;内部集合;}
/// 
///资源是与可选扩展名关联的目录
///例如:ws://localhost:90/[resource]
/// 
公共字符串资源{get;内部集;}
/// 
///资源是与可选扩展关联的目录
/// 
公共布尔成功{get;内部集合;}
/// 
///此值可以是“GET”
/// 
公共字符串方法{get;internal set;}
/// 
///此连接是否使用wss://或ws://配置
/// 
公共布尔安全{get;内部集合;}
/// 
///这些值包含有关我们的连接的信息
/// 
公共字典头{get;internal set;}
/// 
///此值将为您提供要传递到WebSocket服务器的响应缓冲区
/// 
公共字节[]响应
{
得到
{
如果(!成功)
{
返回null;
}
字节[]键值1=_获取键值(标题[“Sec-WebSocket-Key1”);
字节[]键值2=_获取键值(标题[“Sec-WebSocket-Key2]”);
字节[]串联键=新字节[16];
复制(键值1,0,串联键值0,4);
复制(键值2,0,串联键值4,4);
复制(代码,0,串联键,8,8);
//MD5散列
System.Security.Cryptography.MD5 MD5Service=System.Security.Cryptography.MD5.Create();
byte[]challenge_buffer=MD5Service.ComputeHash(串联键);
string response=“HTTP/1.1 101 WebSocket协议握手\r\n”;
响应+=“升级:WebSocket\r\n”;
响应+=“连接:升级\r\n”;
响应+=“Sec WebSocket原点:”+头[“原点”]+“\r\n”;
字符串位置=((安全)?“wss:/”:“ws:/”)+头[“主机”]+“/”+资源;
响应+=“Sec WebSocket位置:”+Location+“\r\n”;
字符串协议=头[“Sec WebSocket协议”];
如果(标题[“Sec WebSocket协议”]==null)
{
协议=“*”;
}
响应+=“Sec WebSocket协议:”+协议修剪(“”)+“\r\n”;
响应+=“\r\n”;
byte[]response_buffer=新字节[response.Length+16];
Copy(Encoding.ASCII.GetBytes(response),0,response\u buffer,0,response.Length);
复制(质询缓冲区,0,响应缓冲区,响应长度,16);
返回响应缓冲区;
}
}
内部字节[]获取密钥值(字符串密钥)
{
字节[]值=新字节[4];
乌隆r=0;
乌隆s=0;
对于(int i=0;i0'和键[i]<9')
{
r=r*10+键[i]-“0”;
}
否则如果(键[i]='')
{
s++;
}
}
值=位转换器.GetBytes(r/s);
if(位转换器.IsLittleEndian)
{
数组。反向(值);
}
返回值;
}
/// 
///此函数将根据请求数据实例化一个新的请求对象
/// 
///请求数据
/// 
内部静态请求实例化(字节[]数据)
{
字符串sdata=Encoding.ASCII.GetString(数据);
返回新请求(委托(请求)
{
字符串正则表达式描述符=@“^([^]+)\s\/([^]+)\sHTTP/1.1”;
字符串_regex_header=@“\n([^:]+):\s([^\r\n]+)”;
字符串“\u regex\u secure=“^ws([^:::+)?:\/\/”;
Match\u descriptor=Regex.Match(sdata,\u Regex\u descriptor);
MatchCollection match_headers=Regex.Matches(sdata,_Regex_header);
if(匹配描述符成功)
{
request.Method=match_descriptor.Groups[1]。值;
request.Resource=match_descriptor.Groups[2]。值;
//Console.WriteLine(“Method=“+request.Method”);
//Console.WriteLine(“Resource=“+request.Resource”);
}
否则返回;
如果(匹配头数>0)
{
foreach(匹配头中的匹配)
{
如果(匹配成功)
{
if (key[i] >= '0' && key[i] <= '9')
value = BitConverter.GetBytes((int)(r / s));