我开始为 Arduino 编写一个 websocket 库。 目前它已经工作了一半。我创建了一个 node.js websocket 服务器,在其中测试客户端。 我的问题出在数据处理部分,它将垃圾打印到串行,我不知道为什么。 连接和文本发送部分工作正常,服务器正常接收文本数据。但是当服务器发送一些文本数据时,我得到的只是垃圾。可能是处理函数中的屏蔽或其他逻辑出了问题。
这是
processData()
和 processCompleteFrame()
函数。
void HsHSocketClient::processData() {
static uint8_t fragmentedOpcode;
static String fragmentedPayload;
while (client.available()) {
uint8_t opcode = client.read();
bool fin = (opcode & 0x80) != 0;
opcode &= 0x0F;
uint8_t payloadLen = client.read() & 0x7F;
if (payloadLen == 126) {
payloadLen = (client.read() << 8) | client.read();
payloadLen -= 2; // Subtract 2 to account for the two additional bytes read for length
} else if (payloadLen == 127) {
payloadLen = (client.read() << 24) | (client.read() << 16) | (client.read() << 8) | client.read();
payloadLen -= 8; // Subtract 8 to account for the eight additional bytes read for length
}
uint8_t maskingKey[4];
client.readBytes(maskingKey, 4);
Serial.print("[Ws] - Masking Key: ");
for (size_t i = 0; i < 4; ++i) {
Serial.print(maskingKey[i], HEX);
Serial.print(" ");
}
Serial.println();
uint8_t payload[payloadLen];
client.readBytes(payload, payloadLen);
for (size_t i = 0; i < payloadLen; ++i) {
payload[i] ^= maskingKey[i % 4];
}
Serial.print("[Ws] - Unmasked Payload: ");
for (size_t i = 0; i < payloadLen; ++i) {
Serial.print(payload[i], HEX);
Serial.print(" ");
}
Serial.println();
if (fin) {
if (fragmentedPayload.length() > 0) {
fragmentedPayload += String(payload, payloadLen);
processCompleteFrame(fragmentedOpcode, fragmentedPayload.c_str(),payloadLen);
fragmentedPayload = "";
} else {
processCompleteFrame(opcode, reinterpret_cast<const char*>(payload),payloadLen);
}
} else {
fragmentedOpcode = opcode;
fragmentedPayload += String(payload, payloadLen);
}
}
}
void HsHSocketClient::processCompleteFrame(uint8_t opcode, const char* payload, size_t payloadLen) {
Serial.print("[Ws] - Received frame, Opcode: 0x");
Serial.println(opcode, HEX);
Serial.print("[Ws] - Payload Hex: ");
for (size_t i = 0; i < payloadLen; ++i) {
Serial.print(payload[i], HEX);
Serial.print(" ");
}
Serial.println();
if (opcode == 0x1) { // Text frame
Serial.print("[Ws] - Received text frame: ");
Serial.println(payload);
}else if (opcode == 0x2) { // Binary frame
Serial.print("[Ws] - Received binary frame: ");
Serial.println(payload);
} else if (opcode == 0x8) { // Close frame
Serial.print("[Ws] - Received close frame: ");
Serial.println(payload);
sendCloseFrame();
client.stop();
} else if (opcode == 0x9) { // Ping frame
Serial.print("[Ws] - Received ping frame: ");
Serial.println(payload);
} else if (opcode == 0xA) { // Pong frame
Serial.print("[Ws] - Received pong frame: ");
Serial.println(payload);
} else {
Serial.print("[Ws] - Received unknown frame: ");
Serial.println(payload);
}
}
node.js ws 服务器代码,没什么花哨的
wss.on('connection', function(ws) {
console.log("Client connected!");
ws.on('error', console.error);
ws.on('message', function(data) {
let msg;
try {
msg = JSON.parse(data);
} catch (error) {
msg = data;
}
console.log('received: %s', msg);
});
ws.on("close", function() {
console.log("Client disconnected!");
});
setInterval(() => {
ws.send('Test message');
}, 5000);
});
我在序列中得到的数据:
[Ws] - Connecting to server: 192.168.10.104:80
[Ws] - Connected to server
[Ws] - Masking Key: 54 50 2F 31
[Ws] - Unmasked Payload: 7A 61 F 0 64 61 F 62 23 39 5B 52 3C 39 41 56 74 0 5D 5E 20 3F 4C 5E 38 23 22 3B 1 20 48 43 35 34 4A B 74 27 4A 53 27 3F 4C 5A 31
24 22 3B 17 3F 41 5F 31 33 5B 58 3B 3E 15 11 1 20 48 43 35 34 4A 3C 5E 3 4A 52 79 7 4A 53 7 3F 4C 5A 31 24 2 70
[Ws] - Masking Key: 65 70 74 3A
[Ws] - Unmasked Payload: 45 34 4D E 33 3B 3D 59 3C 14 23 77 57 40 43 5D 1 22
3B 6D 1 35 46 6B 6 22 3F 63 58 7D 7E 37 6F 5B 66 BA B5 39 8F 5 C9 1 88 5 A1 B8 37 5 75 70 74 3A 64 70 74 3A 6E 71 74 3A ED CC F4 5 FF 5D 66 BA 95 39 8F 5
51 2C 88 5 6 70 74 3A 75 70 74 3A F1 2C 88 5 64 70 74 3A 45 73 8F 5 1B C1 60
[Ws] - Masking Key: 54 65 73 74
[Ws] - Unmasked Payload: 74 8 16 7 27 4 14 11 60 39 8F 4B
[Ws] - Received frame, Opcode: 0x3
[Ws] - Payload Hex: 7A 61 F 0 64 61 F 62 23 39 5B 52
[Ws] - Received unknown frame: za
[Ws] - Masking Key: 54 65 73 74
[Ws] - Unmasked Payload: 74 8 16 7 27 4 14 11 60 39 8F 4B
[Ws] - Received frame, Opcode: 0x1
[Ws] - Payload Hex: 74 8 16 7 27 4 14 11 60 39 8F 4B
[Ws] - Received text frame: '`9�K
[Ws] - Masking Key: 54 65 73 74
[Ws] - Unmasked Payload: 74 8 16 7 27 4 14 11 60 39 8F 4B
[Ws] - Received frame, Opcode: 0x1
[Ws] - Payload Hex: 74 8 16 7 27 4 14 11 60 39 8F 4B
[Ws] - Received text frame: '`9�K
事实证明我不需要做任何遮蔽
void HsHSocketClient::processData() {
static uint8_t fragmentedOpcode;
static uint8_t fragmentedPayload[1024];
static size_t fragmentedPayloadLen = 0;
while (client.available()) {
uint8_t opcode = client.read();
bool fin = (opcode & 0x80) != 0;
opcode &= 0x0F;
uint8_t payloadLen = client.read() & 0x7F;
if (payloadLen == 126) {
payloadLen = (client.read() << 8) | client.read();
payloadLen -= 2;
} else if (payloadLen == 127) {
payloadLen = (client.read() << 24) | (client.read() << 16) | (client.read() << 8) | client.read();
payloadLen -= 8;
}
uint8_t payload[payloadLen];
client.readBytes(payload, payloadLen);
if (fin) {
if (fragmentedPayloadLen > 0) {
processCompleteFrame(fragmentedOpcode, (char*)fragmentedPayload, fragmentedPayloadLen);
fragmentedPayloadLen = 0;
} else {
processCompleteFrame(opcode, (char*)payload, payloadLen);
}
} else {
fragmentedOpcode = opcode;
fragmentedPayloadLen = payloadLen;
memcpy(fragmentedPayload, payload, payloadLen);
}
}
}