WebSockect Server and Client html .net5 sample project

 


//****- websockect server 

// csc wsserver.cs

// wsserver.exe


using System;

using System.Net;

using System.Net.Sockets;

using System.Text;

using System.Text.RegularExpressions;


class Server

{

    public static void Main()

    {

        string ip = "127.0.0.1";

        int port = 65;

        var server = new TcpListener(IPAddress.Parse(ip), port);


        server.Start();

        Console.WriteLine("Server has started on {0}:{1}, Waiting for a connection...", ip, port);


        TcpClient client = server.AcceptTcpClient();

        Console.WriteLine("A client connected.");


        NetworkStream stream = client.GetStream();


        

        while (true)

        {

            while (!stream.DataAvailable) ;

            while (client.Available < 3) ; 


            byte[] bytes = new byte[client.Available];

            stream.Read(bytes, 0, client.Available);

            string s = Encoding.UTF8.GetString(bytes);


            if (Regex.IsMatch(s, "^GET", RegexOptions.IgnoreCase))

            {

                Console.WriteLine("=====Handshaking from client=====\n{0}", s);


                // 1. Obtain the value of the "Sec-WebSocket-Key" request header without any leading or trailing whitespace

                // 2. Concatenate it with "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" (a special GUID specified by RFC 6455)

                // 3. Compute SHA-1 and Base64 hash of the new value

                // 4. Write the hash back as the value of "Sec-WebSocket-Accept" response header in an HTTP response

                string swk = Regex.Match(s, "Sec-WebSocket-Key: (.*)").Groups[1].Value.Trim();

                string swka = swk + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

                byte[] swkaSha1 = System.Security.Cryptography.SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(swka));

                string swkaSha1Base64 = Convert.ToBase64String(swkaSha1);


                // HTTP/1.1 defines the sequence CR LF as the end-of-line marker

                byte[] response = Encoding.UTF8.GetBytes(

                    "HTTP/1.1 101 Switching Protocols\r\n" +

                    "Connection: Upgrade\r\n" +

                    "Upgrade: websocket\r\n" +

                    "Sec-WebSocket-Accept: " + swkaSha1Base64 + "\r\n\r\n");


                stream.Write(response, 0, response.Length);

            }

            else

            {

                bool fin = (bytes[0] & 0b10000000) != 0,

                    mask = (bytes[1] & 0b10000000) != 0; // must be true, "All messages from the client to the server have this bit set"


                int opcode = bytes[0] & 0b00001111, // expecting 1 - text message

                    msglen = bytes[1] - 128, // & 0111 1111

                    offset = 2;


                if (msglen == 126)

                {

                    // was ToUInt16(bytes, offset) but the result is incorrect

                    msglen = BitConverter.ToUInt16(new byte[] { bytes[3], bytes[2] }, 0);

                    offset = 4;

                }

                else if (msglen == 127)

                {

                    Console.WriteLine("TODO: msglen == 127, needs qword to store msglen");

                    

                }


                if (msglen == 0)

                    Console.WriteLine("msglen == 0");

                else if (mask)

                {

                    byte[] decoded = new byte[msglen];

                    byte[] masks = new byte[4] { bytes[offset], bytes[offset + 1], bytes[offset + 2], bytes[offset + 3] };

                    offset += 4;


                    for (int i = 0; i < msglen; ++i)

                        decoded[i] = (byte)(bytes[offset + i] ^ masks[i % 4]);


                    string text = Encoding.UTF8.GetString(decoded);

                    Console.WriteLine("{0}", text);

                }

                else

                    Console.WriteLine("mask bit not set");


                Console.WriteLine();

            }

        }

    }


  


}


//***************************** client.html

<!doctype html>

<style>

    textarea { vertical-align: bottom; }

    #output { overflow: auto; }

    #output > p { overflow-wrap: break-word; }

    #output span { color: blue; }

    #output span.error { color: red; }

</style>

<h2>WebSocket Test</h2>

<textarea cols=60 rows=6></textarea>

<button>send</button>

<div id=output></div>

<script>

    // http://www.websocket.org/echo.html


    var button = document.querySelector("button"),

        output = document.querySelector("#output"),

        textarea = document.querySelector("textarea"),

        // wsUri = "ws://echo.websocket.org/",

        wsUri = "ws://127.0.0.1:65/",

        websocket = new WebSocket(wsUri);


    button.addEventListener("click", onClickButton);


    websocket.onopen = function (e) {

        writeToScreen("CONNECTED");

        doSend("WebSocket rocks");

    };


    websocket.onclose = function (e) {

        writeToScreen("DISCONNECTED");

    };


    websocket.onmessage = function (e) {

        writeToScreen("<span>RESPONSE: " + e.data + "</span>");

    };


    websocket.onerror = function (e) {

        writeToScreen("<span class=error>ERROR:</span> " + e.data);

    };


    function doSend(message) {

        writeToScreen("SENT: " + message);

        websocket.send(message);

    }


    function writeToScreen(message) {

        output.insertAdjacentHTML("afterbegin", "<p>" + message + "</p>");

    }


    function onClickButton() {

        var text = textarea.value;


        text && doSend(text);

        textarea.value = "";

        textarea.focus();

    }

</script>

 //*********** Github project

https://github.com/doktoralban/WebSocketServerClient

Yorumlar