Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7608023
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 31, 20262026-05-31T00:48:50+00:00 2026-05-31T00:48:50+00:00

I’ve been working on a hello-world sort of WebSocket app to see if I

  • 0

I’ve been working on a hello-world sort of WebSocket app to see if I can get it working in VS 2010. The client side code is very straight forward, and it works great in Safari because Safari still runs on the WebSocket 76 protocol.

Google Chrome on the other hand runs the newer Sec-WebSocket-Version code which is more complicated. I “borrowed” some code as a base from a code-plex project to get it working for the older 76 and 75 protocols: http://wsaspnet.codeplex.com/SourceControl/changeset/view/58121#1561340

I then proceeded to upgrade the code I found there until it could perform the new handshake (in the code below). The part I have finally hit a wall at and cannot seem to find any help on is communication to a Sec-WebSocket-Version 8+ socket. It used to be you could just append a 0x00 to the beginning, and a 0xFF to the end and tada! it worked! but now apparently there is more to be done to fix a security problem. I can tell that the socket is closing when I send a message by debugging the code, and I read in several places that chrome likes to close a socket when it receives a message it doesn’t understand.

So then I found this post: How can I send and receive WebSocket messages on the server side? where the guy had the same issue as me, but I can’t seem to translate the pseudo-code that his answerer posted into C#. Can anyone help me out?

The client code:

<div id="ComLog" style="height:600px;">


</div>
<input type="button" onclick="javascript:connectToServer();" value='connect' />

<script type="text/javascript">
    var sock;
    function connectToServer() {
        try {
            sock = new WebSocket("ws://localhost:8181/websock");
            //sock = new WebSocket("ws://192.168.0.100:8181/websock");

            //sock = new WebSocket("ws://websockets.org:8787");

            sock.onopen = sockOpen;
            sock.onerror = sockError;
            sock.onclose = sockClosed;
            sock.onmessage = sockMessage;
        } catch (e) {
            log("error:" + e);
        }
    }

    function sockOpen() {
        log("connected");
    }

    function sockError(error, p2) {
        log("socket error!");
    }

    function sockClosed() {
        log("socket closed");
    }

    function sockMessage(event) {
        log("<b>Server:</b> " + event.data);
    }

    function log(msg) {
        var txtLog = document.getElementById("ComLog");
        txtLog.innerHTML += msg + "</br>";
    }
</script>

The Server code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Web;
using System.Collections.Specialized;
using System.Text.RegularExpressions;
using System.Threading;
using System.Security.Cryptography;

namespace WebSocks
{
    public class WebSockServer
    {

        /// <summary>
        /// Port number to listen on
        /// </summary>
        private const int PortNumber = 8181;

        /// <summary>
        /// Socket which awaits connections
        /// </summary>
        private static Socket ListenerSocket;

        /// <summary>
        /// Thread in which we await for incomming connections.
        /// </summary>
        static System.Threading.Thread _serverThread;


        static WebSockServer() { }

        /// <summary>
        /// Starts thread with listening socket.
        /// </summary>
        public static void Start()
        {
            System.Threading.ThreadStart ts = new System.Threading.ThreadStart(Listen);
            _serverThread = new System.Threading.Thread(ts);
            _serverThread.Start();
        }

        /// <summary>
        /// Stops listening for connections.
        /// </summary>
        public static void End()
        {
            _serverThread.Abort();
            ListenerSocket.Dispose();
        }

        public static void Listen()
        {
            //Start listening
            ListenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            EndPoint ep = new IPEndPoint(IPAddress.Parse("0.0.0.0"), PortNumber);
            ListenerSocket.Bind(ep);
            ListenerSocket.Listen(5);

            while (true)
            {
                //New client
                using (Socket client = ListenerSocket.Accept())
                {
                    //Receiving clientHandshake
                    string clientHandshake = String.Empty;
                    byte[] buffer = null;
                    int readBytes = 0;
                    do
                    {
                        buffer = new byte[client.Available];
                        readBytes = client.Receive(buffer);
                        clientHandshake += Encoding.UTF8.GetString(buffer);
                    }
                    while (client.Available > 0);

                    //Last eight bytes are body of requets (we should include it in response)
                    byte[] secKey3 = buffer.Skip(readBytes - 8).Take(8).ToArray();

                    //Variables we can extract from clientHandshake
                    string clientOrigin = String.Empty;
                    string secKey1 = String.Empty;
                    string secKey2 = String.Empty;
                    string WebSocketVersion = String.Empty;
                    int WSV = 0;
                    string WebSocketKey = String.Empty;

                    //Extracting values from headers (key:value)
                    string[] clientHandshakeLines = Regex.Split(clientHandshake, Environment.NewLine);
                    foreach (string hline in clientHandshakeLines)
                    {
                        int valueStartIndex = hline.IndexOf(':') + 2;
                        if (valueStartIndex > 0)
                        {
                            if (hline.StartsWith("Origin"))
                            {
                                clientOrigin = hline.Substring(valueStartIndex, hline.Length - valueStartIndex);
                            }
                            else if (hline.StartsWith("Sec-WebSocket-Key2"))
                            {
                                secKey2 = hline.Substring(valueStartIndex, hline.Length - valueStartIndex);
                            }
                            else if (hline.StartsWith("Sec-WebSocket-Key1"))
                            {
                                secKey1 = hline.Substring(valueStartIndex, hline.Length - valueStartIndex);
                            }

                            if (hline.StartsWith("Sec-WebSocket-Version"))
                            {
                                WebSocketVersion = hline.Replace("Sec-WebSocket-Version: ", "");
                                WSV = Convert.ToInt32(WebSocketVersion);
                            }

                            if (hline.StartsWith("Sec-WebSocket-Key"))
                            {
                                WebSocketKey = hline.Replace("Sec-WebSocket-Key: ", "");
                            }
                        }
                    }




                    if (!String.IsNullOrEmpty(WebSocketVersion)) //WebSocketVersion 8 and up handshake check
                    {
                        //New WebSocketVersion number, included after Version 8
                        StringBuilder mResponse = new StringBuilder();
                        mResponse.AppendLine("HTTP/1.1 101 Switching Protocols");
                        mResponse.AppendLine("Upgrade: WebSocket");
                        mResponse.AppendLine("Connection: Upgrade");
                        mResponse.AppendLine(String.Format("Sec-WebSocket-Accept: {0}", ComputeWebSocketHandshakeSecurityHash09(WebSocketKey)) + Environment.NewLine);

                        byte[] HSText = Encoding.UTF8.GetBytes(mResponse.ToString());

                        client.Send(HSText, 0, HSText.Length, 0);
                    }
                    else
                    {
                        //This part is common for all websockets editions (v. 75 & v.76)
                        client.Send(Encoding.UTF8.GetBytes("HTTP/1.1 101 Web Socket Protocol Handshake" + Environment.NewLine));
                        client.Send(Encoding.UTF8.GetBytes("Upgrade: WebSocket" + Environment.NewLine));
                        client.Send(Encoding.UTF8.GetBytes("Connection: Upgrade" + Environment.NewLine));


                        if (String.IsNullOrEmpty(secKey1) && String.IsNullOrEmpty(secKey2))  //75 or less handshake check
                        {                 
                            client.Send(Encoding.UTF8.GetBytes(String.Format("WebSocket-Origin: {0}", clientOrigin) + Environment.NewLine));
                            client.Send(Encoding.UTF8.GetBytes("WebSocket-Location: ws://localhost:8181/websock" + Environment.NewLine));
                            client.Send(Encoding.UTF8.GetBytes(Environment.NewLine));
                        }
                        else //76 handshake check
                        {
                            //Keys present, this means 76 version is used. Writing Sec-* headers 
                            client.Send(Encoding.UTF8.GetBytes(String.Format("Sec-WebSocket-Origin: {0}", clientOrigin) + Environment.NewLine));
                            client.Send(Encoding.UTF8.GetBytes("Sec-WebSocket-Location: ws://localhost:8181/websock" + Environment.NewLine));
                            client.Send(Encoding.UTF8.GetBytes(Environment.NewLine));

                            //Calculating response body
                            byte[] secret = CalculateSecurityBody(secKey1, secKey2, secKey3);
                            client.Send(secret);
                        }
                    }

                    Thread.Sleep(1000);

                    SendMessage("This message will terminate in 5 seconds...", client, WSV);

                    Thread.Sleep(1000);

                    SendMessage("4", client, WSV);

                    Thread.Sleep(1000);

                    SendMessage("3", client, WSV);

                    Thread.Sleep(1000);

                    SendMessage("2", client, WSV);

                    Thread.Sleep(1000);

                    SendMessage("1", client, WSV);

                    Thread.Sleep(1000);

                }
            }
        }

        private static void SendMessage(string Msg, Socket client, int WebSockVersion)
        {
            if (WebSockVersion >= 8)
            {
                //This is the section that doesn't work
                client.Send(Encoding.UTF8.GetBytes(Msg));

            }
            else 
            {
                client.Send(new byte[] { 0x00 });
                client.Send(Encoding.UTF8.GetBytes(Msg));
                client.Send(new byte[] { 0xFF });
            }
        }


        public static byte[] CalculateSecurityBody(string secKey1, string secKey2, byte[] secKey3)
        {
            //Remove all symbols that are not numbers
            string k1 = Regex.Replace(secKey1, "[^0-9]", String.Empty);
            string k2 = Regex.Replace(secKey2, "[^0-9]", String.Empty);

            //Convert received string to 64 bit integer.
            Int64 intK1 = Int64.Parse(k1);
            Int64 intK2 = Int64.Parse(k2);

            //Dividing on number of spaces
            int k1Spaces = secKey1.Count(c => c == ' ');
            int k2Spaces = secKey2.Count(c => c == ' ');
            int k1FinalNum = (int)(intK1 / k1Spaces);
            int k2FinalNum = (int)(intK2 / k2Spaces);

            //Getting byte parts
            byte[] b1 = BitConverter.GetBytes(k1FinalNum).Reverse().ToArray();
            byte[] b2 = BitConverter.GetBytes(k2FinalNum).Reverse().ToArray();
            //byte[] b3 = Encoding.UTF8.GetBytes(secKey3);
            byte[] b3 = secKey3;

            //Concatenating everything into 1 byte array for hashing.
            List<byte> bChallenge = new List<byte>();
            bChallenge.AddRange(b1);
            bChallenge.AddRange(b2);
            bChallenge.AddRange(b3);

            //Hash and return
            byte[] hash = MD5.Create().ComputeHash(bChallenge.ToArray());
            return hash;
        }

        public static String ComputeWebSocketHandshakeSecurityHash09(String secWebSocketKey)         
        {             
            const String MagicKEY = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";             
            String secWebSocketAccept = String.Empty;              
            // 1. Combine the request Sec-WebSocket-Key with magic key.             
            String ret = secWebSocketKey + MagicKEY;              
            // 2. Compute the SHA1 hash             
            SHA1 sha = new SHA1CryptoServiceProvider();             
            byte[] sha1Hash = sha.ComputeHash(Encoding.UTF8.GetBytes(ret));              
            // 3. Base64 encode the hash             
            secWebSocketAccept = Convert.ToBase64String(sha1Hash);              
            return secWebSocketAccept;         
        } 
    }
}

The apparent untranslated “answer” to all my problems:

bytesFormatted[0] = 129

indexStartRawData = -1 // don't matter what value is here; it will be set now:

if bytesRaw.length <= 125
    bytesFormatted[1] = bytesRaw.length

    indexStartRawData = 2

else if bytesRaw.length >= 126 and bytesRaw.length <= 65535
    bytesFormatted[1] = 126
    bytesFormatted[2] = ( bytesRaw.length >> 8 ) AND 255
    bytesFormatted[3] = ( bytesRaw.length      ) AND 255

    indexStartRawData = 4

else
    bytesFormatted[1] = 127
    bytesFormatted[2] = ( bytesRaw.length >> 56 ) AND 255
    bytesFormatted[3] = ( bytesRaw.length >> 48 ) AND 255
    bytesFormatted[4] = ( bytesRaw.length >> 40 ) AND 255
    bytesFormatted[5] = ( bytesRaw.length >> 32 ) AND 255
    bytesFormatted[6] = ( bytesRaw.length >> 24 ) AND 255
    bytesFormatted[7] = ( bytesRaw.length >> 16 ) AND 255
    bytesFormatted[8] = ( bytesRaw.length >>  8 ) AND 255
    bytesFormatted[9] = ( bytesRaw.length       ) AND 255

    indexStartRawData = 10

// put raw data at the correct index
bytesFormatted.put(bytesRaw, indexStartRawData)


// now send bytesFormatted (e.g. write it to the socket stream)

~~~~~~~~~~~Edit~~~~~~~~~~~~

Current version of send function:

private static void SendMessage(string Msg, Socket client, int WebSockVersion)
        {
            if (WebSockVersion >= 8)
            {
                bool IsFinal = true;
                int OpCode = 1;
                int? Mask = null;
                int PayloadLength = Encoding.UTF8.GetBytes(Msg).Length;
                byte[] buffer = Encoding.UTF8.GetBytes(Msg);

                int offset = 0;
                buffer[offset++] = (byte)((IsFinal ? 128 : 0) | ((int)OpCode & 15));
                if (PayloadLength > ushort.MaxValue)
                { // write as a 64-bit length
                    buffer[offset++] = (byte)((Mask.HasValue ? 128 : 0) | 127);
                    buffer[offset++] = 0;
                    buffer[offset++] = 0;
                    buffer[offset++] = 0;
                    buffer[offset++] = 0;
                    buffer[offset++] = (byte)(PayloadLength >> 24);
                    buffer[offset++] = (byte)(PayloadLength >> 16);
                    buffer[offset++] = (byte)(PayloadLength >> 8);
                    buffer[offset++] = (byte)(PayloadLength);
                }
                else if (PayloadLength > 125)
                { // write as a 16-bit length
                    buffer[offset++] = (byte)((Mask.HasValue ? 128 : 0) | 126);
                    buffer[offset++] = (byte)(PayloadLength >> 8);
                    buffer[offset++] = (byte)(PayloadLength);
                }
                else
                { // write in the header
                    buffer[offset++] = (byte)((Mask.HasValue ? 128 : 0) | PayloadLength);
                }
                if (Mask.HasValue)
                {
                    int mask = Mask.Value;
                    buffer[offset++] = (byte)(mask >> 24);
                    buffer[offset++] = (byte)(mask >> 16);
                    buffer[offset++] = (byte)(mask >> 8);
                    buffer[offset++] = (byte)(mask);
                }
                //stream.Write(buffer, 0, offset);

                client.Send(buffer, 0, PayloadLength, SocketFlags.None);

            }
            else 
            {
                client.Send(new byte[] { 0x00 });
                client.Send(Encoding.UTF8.GetBytes(Msg));
                client.Send(new byte[] { 0xFF });
            }
        }
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-31T00:48:52+00:00Added an answer on May 31, 2026 at 12:48 am

    That looks about right to be honest; it is pretty similar to my working code (which only handles 32-bit lengths, hence the lack of >> 32 and above):

    int offset = 0;
    buffer[offset++] = (byte)((IsFinal ? 128 : 0) | ((int)OpCode & 15));
    if (PayloadLength > ushort.MaxValue)
    { // write as a 64-bit length
        buffer[offset++] = (byte)((Mask.HasValue ? 128 : 0) | 127);
        buffer[offset++] = 0;
        buffer[offset++] = 0;
        buffer[offset++] = 0;
        buffer[offset++] = 0;
        buffer[offset++] = (byte)(PayloadLength >> 24);
        buffer[offset++] = (byte)(PayloadLength >> 16);
        buffer[offset++] = (byte)(PayloadLength >> 8);
        buffer[offset++] = (byte)(PayloadLength);
    }
    else if (PayloadLength > 125)
    { // write as a 16-bit length
        buffer[offset++] = (byte)((Mask.HasValue ? 128 : 0) | 126);
        buffer[offset++] = (byte)(PayloadLength >> 8);
        buffer[offset++] = (byte)(PayloadLength);
    }
    else
    { // write in the header
        buffer[offset++] = (byte)((Mask.HasValue ? 128 : 0) | PayloadLength);
    }
    if (Mask.HasValue)
    {
        int mask = Mask.Value;
        buffer[offset++] = (byte)(mask >> 24);
        buffer[offset++] = (byte)(mask >> 16);
        buffer[offset++] = (byte)(mask >> 8);
        buffer[offset++] = (byte)(mask);
    }
    stream.Write(buffer, 0, offset);
    

    after that, it just writes the payload (if any). Since you are writing from the server to the client, you don’t actually need to worry about the outbound mask, so that would always be just 127. However, if you are accepting incoming messages, then you very much do need to worry about masks.

    Notes: .NET 4.5 on Windows 8 has WebSocket support built into HttpListener and ASP.NET; until then, another approach might be to look at SuperWebSocket.


    Re your edit: you have chomped your own data! Try instead:

    bool IsFinal = true;
    int OpCode = 1;
    int? Mask = null;
    byte[] payload = Encoding.UTF8.GetBytes(Msg);
    int PayloadLength = payload.Length;
    byte[] buffer = new byte[64]; // for working out the header
    
    int offset = 0;
    buffer[offset++] = (byte)((IsFinal ? 128 : 0) | ((int)OpCode & 15));
    if (PayloadLength > ushort.MaxValue)
    { // write as a 64-bit length
        buffer[offset++] = (byte)((Mask.HasValue ? 128 : 0) | 127);
        buffer[offset++] = 0;
        buffer[offset++] = 0;
        buffer[offset++] = 0;
        buffer[offset++] = 0;
        buffer[offset++] = (byte)(PayloadLength >> 24);
        buffer[offset++] = (byte)(PayloadLength >> 16);
        buffer[offset++] = (byte)(PayloadLength >> 8);
        buffer[offset++] = (byte)(PayloadLength);
    }
    else if (PayloadLength > 125)
    { // write as a 16-bit length
        buffer[offset++] = (byte)((Mask.HasValue ? 128 : 0) | 126);
        buffer[offset++] = (byte)(PayloadLength >> 8);
        buffer[offset++] = (byte)(PayloadLength);
    }
    else
    { // write in the header
        buffer[offset++] = (byte)((Mask.HasValue ? 128 : 0) | PayloadLength);
    }
    if (Mask.HasValue)
    {
        int mask = Mask.Value;
        buffer[offset++] = (byte)(mask >> 24);
        buffer[offset++] = (byte)(mask >> 16);
        buffer[offset++] = (byte)(mask >> 8);
        buffer[offset++] = (byte)(mask);
    }
    // you might want to manually combine these into 1 packet
    client.Send(buffer, 0, offset, SocketFlags.None);
    client.Send(payload, 0, payload.Length, SocketFlags.None);
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a jquery bug and I've been looking for hours now, I can't
I'm trying to convert HTML to plain text. I get many &\#8217; &\#8220; etc.
Let's say I'm outputting a post title and in our database, it's Hello Y&#8217;all
link Im having trouble converting the html entites into html characters, (&# 8217;) i
Specifically, suppose I start with the string string =hello \'i am \' me And
I have this code to decode numeric html entities to the UTF8 equivalent character.
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
We're building an app, our first using Rails 3, and we're having to build
I have this code: - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock { NSString *someString = [[NSString
I have been unable to fix a problem with Java Unicode and encoding. The

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.