我试图在C#中自己创建一个WebSocket协议,以了解它是如何工作的。
我做了服务器和客户端。
我能够握手,发送和接收消息(客户端和服务器都运行良好)但我在向客户端发送屏蔽消息时遇到问题。
以下是我使用NetworkStream.Write
创建要发送的框架的代码:
private byte[] EncodeOutgoingMessage(string text, bool masked = false)
{
/* this is how and header should be made:
* - first byte -> FIN + RSV1 + RSV2 + RSV3 + OPCODE
* - second byte -> MASK + payload length (only 7 bits)
* - third, fourth, fifth and sixth bytes -> (optional) XOR encoding key bytes
* - following bytes -> the encoded (if a key has been used) payload
*
* FIN [1 bit] -> 1 if the whole message is contained in this frame, 0 otherwise
* RSVs [1 bit each] -> MUST be 0 unless an extension is negotiated that defines meanings for non-zero values
* OPCODE [4 bits] -> defines the interpretation of the carried payload
*
* MASK [1 bit] -> 1 if the message is XOR masked with a key, 0 otherwise
* payload length [7 bits] -> can be max 1111111 (127 dec), so, the payload cannot be more than 127 bytes per frame
*
* valid OPCODES:
* - 0000 [0] -> continuation frame
* - 0001 [1] -> text frame
* - 0010 [2] -> binary frame
* - 0011 [3] to 0111 [7] -> reserved for further non-control frames
* - 1000 [8] -> connection close
* - 1001 [9] -> ping
* - 1010 [A] -> pong
* - 1011 [B] to 1111 [F] -> reserved for further control frames
*/
// in our case the first byte will be 10000001 (129 dec = 81 hex).
// the length is going to be (masked)1 << 7 (OR) 0 + payload length.
byte[] header = new byte[] { 0x81, (byte)((masked ? 0x1 << 7 : 0x0) + text.Length) };
// by default the mask array is empty...
byte[] maskKey = new byte[4];
if(masked)
{
// but if needed, let's create it properly.
Random rd = new Random();
rd.NextBytes(maskKey);
}
// let's get the bytes of the message to send.
byte[] payload = Encoding.UTF8.GetBytes(text);
// this is going to be the whole frame to send.
byte[] frame = new byte[header.Length + (masked ? maskKey.Length : 0) + payload.Length];
// add the header.
Array.Copy(header, frame, header.Length);
// add the mask if necessary.
if(maskKey.Length > 0)
{
Array.Copy(maskKey, 0, frame, header.Length, maskKey.Length);
// let's encode the payload using the mask.
for(int i = 0; i < payload.Length; i++)
{
payload[i] = (byte)(payload[i] ^ maskKey[i % maskKey.Length]);
}
}
// add the payload.
Array.Copy(payload, 0, frame, header.Length + (masked ? maskKey.Length : 0), payload.Length);
return frame;
}
所以...使用
byte[] answer = EncodeOutgoingMessage("Ciao !! :)");
stream.Write(answer, 0, answer.Length);
效果很好,但
byte[] answer = EncodeOutgoingMessage("Ciao !! :)", true);
stream.Write(answer, 0, answer.Length);
将导致客户端收到错误的字符串。
请有人发现我做错了吗?
答案 0 :(得分:0)