C# HTML5 Websocket Server

后端 未结 4 473
醉话见心
醉话见心 2020-12-28 09:50

I\'m trying to create a C# Websocket server but I just don\'t seem to get it working. I now have a server that accepts the TCPClient, receives the HTTP request from the clie

4条回答
  •  长情又很酷
    2020-12-28 10:30

    Here's a sample server I wrote illustrating the handshake phase in accordance to the draft-ietf-hybi-thewebsocketprotocol-00:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using System.Net.Sockets;
    using System.Security.Cryptography;
    using System.Text;
    using System.Text.RegularExpressions;
    
    class Program
    {
        static void Main(string[] args)
        {
            var listener = new TcpListener(IPAddress.Loopback, 8080);
            listener.Start();
            while (true)
            {
                using (var client = listener.AcceptTcpClient())
                using (var stream = client.GetStream())
                {
                    var headers = new Dictionary();
                    string line = string.Empty;
                    while ((line = ReadLine(stream)) != string.Empty)
                    {
                        var tokens = line.Split(new char[] { ':' }, 2);
                        if (!string.IsNullOrWhiteSpace(line) && tokens.Length > 1)
                        {
                            headers[tokens[0]] = tokens[1].Trim();
                        }
                    }
    
                    var key = new byte[8];
                    stream.Read(key, 0, key.Length);
    
                    var key1 = headers["Sec-WebSocket-Key1"];
                    var key2 = headers["Sec-WebSocket-Key2"];
    
                    var numbersKey1 = Convert.ToInt64(string.Join(null, Regex.Split(key1, "[^\\d]")));
                    var numbersKey2 = Convert.ToInt64(string.Join(null, Regex.Split(key2, "[^\\d]")));
                    var numberSpaces1 = CountSpaces(key1);
                    var numberSpaces2 = CountSpaces(key2);
    
                    var part1 = (int)(numbersKey1 / numberSpaces1);
                    var part2 = (int)(numbersKey2 / numberSpaces2);
    
                    var result = new List();
                    result.AddRange(GetBigEndianBytes(part1));
                    result.AddRange(GetBigEndianBytes(part2));
                    result.AddRange(key);
    
                    var response =
                        "HTTP/1.1 101 WebSocket Protocol Handshake" + Environment.NewLine +
                        "Upgrade: WebSocket" + Environment.NewLine +
                        "Connection: Upgrade" + Environment.NewLine +
                        "Sec-WebSocket-Origin: " + headers["Origin"] + Environment.NewLine +
                        "Sec-WebSocket-Location: ws://localhost:8080/websession" + Environment.NewLine + 
                        Environment.NewLine;
    
                    var bufferedResponse = Encoding.UTF8.GetBytes(response);
                    stream.Write(bufferedResponse, 0, bufferedResponse.Length);
                    using (var md5 = MD5.Create())
                    {
                        var handshake = md5.ComputeHash(result.ToArray());
                        stream.Write(handshake, 0, handshake.Length);
                    }
                }
            }
        }
    
        static int CountSpaces(string key)
        {
            return key.Length - key.Replace(" ", string.Empty).Length;
        }
    
        static string ReadLine(Stream stream)
        {
            var sb = new StringBuilder();
            var buffer = new List();
            while (true)
            {
                buffer.Add((byte)stream.ReadByte());
                var line = Encoding.ASCII.GetString(buffer.ToArray());
                if (line.EndsWith(Environment.NewLine))
                {
                    return line.Substring(0, line.Length - 2);
                }
            }
        }
    
        static byte[] GetBigEndianBytes(int value)
        {
            var bytes = 4;
            var buffer = new byte[bytes];
            int num = bytes - 1;
            for (int i = 0; i < bytes; i++)
            {
                buffer[num - i] = (byte)(value & 0xffL);
                value = value >> 8;
            }
            return buffer;
        }
    }
    

    And a sample client:

    
    
    
        
    
    
    
    
    

提交回复
热议问题