HTML and CSS Reference
0x2 indicates a binary payload
0x8 indicates the connection is being closed
0x9 specifies the message is a ping
0xA specifies the message is a pong
The first bit of the second byte indicates that masking is used. I will describe masking later. The remainder of
the byte specifies the payload length. For payloads less than 126 bytes, the length is specified here. However, if the
length is between 126 and 32,183 the length is set to 126 and the actual length is provided in the next two bytes.
For messages longer than that, the length is set to 127 and the actual length is specified in the next eight bytes. So,
depending on how long the message is, the frame will contain between 0 and 8 extra bytes.
The next four bytes contain the masking key. This is omitted if masking is not used. After that comes the
For a simple, unmasked message containing the text “Hello”, the frame would contain the following bytes:
0x81, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f
The first byte, 0x81, in binary is 10000001 . The first bit is set indicating this is the final frame and the last bit is
set to indicate the payload contains text. The next byte specifies a payload length of five characters, which follow
immediately. The remaining five bytes contain the “H”, “e”, “l”, “l”, and “o” characters.
Unmasking a Frame
For security reasons, all frames from the client should be masked. Masking is a simple encoding scheme that uses
a masking key that is different with each frame. The browser will take care of this for you; however, the server will
need to unmask the data. Frames sent to the client should not be masked.
The masking key is provided in the four bytes directly following the length. The masking key is randomly
generated by the client. To unmask the data, for each byte in the payload, the XOR operator is applied to the byte
and the corresponding byte in the masking key. The first payload byte is XOR'ed with the first byte of the masking
key, the second byte is XOR'ed with the second byte of the mask, an so on. The fifth byte is the XOR'ed with the
first byte of the mask.
This can be done with the following C# expression. This assumes that payload contains an array of
masked data and mask contains the 4-byte masking key.
for (int i=0; i<length; i++)
payload[i]=(byte)(payload[i] ^ masks[i % 4]);
The i % 4 expression gets the appropriate masking byte and the ^ operator performs the XOR operation.
After processing all of the bytes, the payload array will contain the unmasked data.
To use websockets you will need to provide an application that will implement the server-side protocol. I will
show you how to build your own using .NET and hosted in a console application. As you are probably expecting,
there is a bit of bit and byte manipulation necessary (no pun intended).