更新几乎在那里,我可以收到消息,我想。当代码可读时,我会把它放进去。也在尝试发送。。
原始问题
我试图连接我的esp8266(@38400波特)(3.5美元的wifi芯片:)),到一个网络插座。该芯片与Arduino pro mini相连。这个设置是确定的,它的工作原理。
多亏了一些代码,我能握手了(https://github.com/ejeklint/ArduinoWebsocketServer).
这就是程序必须做的:
我正在测试webSocket:http://www.websocket.org/echo.html
连接我的wifi模块ws://192.168.1.104:8000
当我向我的Arduino发送3 x信息“aaaa”时,我收到以下信息:
IPD,0,10: | | | q||b|k||c|||
知识产权署,0,10:| | | | | | | 0 | P | | | Q | 1|
IPD,0,10:| | | |Ӛ|±||
我怎样才能破译这个?
#include "sha1.h"
#include "Base64.h"
#include <SoftwareSerial.h>
#include <MemoryFree.h>
SoftwareSerial debug(8, 9); // RX, TX
void setup() {
Serial.begin(38400);
debug.begin(38400);
delay(50);
debug.println("start");
Serial.println("AT+RST");
delay(5000);
Serial.println("AT+CWMODE=1"); // NO CHANGE
delay(1500);
Serial.find("OK");
Serial.println("AT+CIPMUX=1");
Serial.find("OK");
delay(3000);
Serial.println("AT+CIPSERVER=1,8000");
boolean server = Serial.find("OK");
delay(3000);
Serial.println("AT+CIFSR"); // Display the ip please
boolean r = readLines(4);
debug.println("eind setup");
debug.println(server);
boolean found = false;
while(!found) // wait for the link
found = Serial.find("Link");
debug.println("link builded, end setup");
}
void loop() {
String key = "";
boolean isKey = Serial.find("Key: ");
if(isKey) {
debug.println("Key found!");
while(true) {
if(Serial.available()) {
char c = (char)Serial.read();
if(c == '=') {
doHandshake(key + "==");
key = "";
break;
}
if(c != '\r' || c != '\n') {
key = key + c;
}
}
}
// _________________________ PROBLEMO ____________________________________
while(true) { // So far so good. Handshake done Now wait for the message
if(Serial.available()) {
char c = (char)Serial.read();
debug.print(c);
debug.print(" | ");
}
}
}
// _________________________ /PROBLEMO ____________________________________
}
boolean readLines(int lines) {
boolean found = false;
int count = 0;
while(count < lines) {
if(Serial.available()) {
char c = (char)Serial.read();
if(c != '\r') {
debug.write(c);
} else {
count++;
}
}
}
return true;
}
bool doHandshake(String k) {
debug.println("do handshake: " + k);
char bite;
char temp[128];
char key[80];
memset(temp, '\0', sizeof(temp));
memset(key, '\0', sizeof(key));
byte counter = 0;
int myCo = 0;
while ((bite = k.charAt(myCo++)) != 0) {
key[counter++] = bite;
}
strcat(key, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); // Add the omni-valid GUID
Sha1.init();
Sha1.print(key);
uint8_t *hash = Sha1.result();
base64_encode(temp, (char*)hash, 20);
debug.print(temp);
int cc = -1;
while(temp[cc++++] != '\0') {} // cc is length return key
cc = 165 + cc; // length return key + 165 keys for rest of header
Serial.print("AT+CIPSEND=0,");
Serial.println(129); // +30 // was 129
boolean found = false;
while(!found)
found = Serial.find(">"); // Wait until I can send
Serial.print("HTTP/1.1 101 Switching Protocols\r\n");
Serial.print("Upgrade: websocket\r\n");
Serial.print("Connection: Upgrade\r\n");
Serial.print("Sec-WebSocket-Accept: ");
Serial.print(temp);
Serial.print("\r\n\r\n");
return true;
}
您看到的是与HTTP头连接的第一个Web套接字框架(| | | | | q | | b | k | | c | |)。(IPD,0,10:)使用管道(|)进行定界的数据是不可理解的,因为它不是ASCII,也不是UTF8。必须将最后一个冒号(:)后面的数据显示为二进制。那么它应该是完全有意义的。我也在做同样的事情。只有当我把总数据显示为二进制时,我才“得到了”。我使用的是网络上的“网络套接字摇滚”演示。这是一个回音,它只会将“Web Sockets rock”发送到您指定的服务器。我把服务器地址改成了我的ESP8266的IP地址,然后开始查看帧。我为自己做了一点分析(和你一样),看看成功握手后ESP8266会返回什么。(我先学会了握手)下面是TeraTerm的“握手后”列表-
+IPD,0,21:r¨$v%ÍF%ËVÃW (NOTE: Garbage after the :)
我希望能在里面找到“网络插座摇滚”。
下面是我从接收缓冲区提取的转换为二进制的列表-
0 2B 0010 1011
1 49 0100 1001
2 50 0101 0000
3 44 0100 0100
4 2C 0010 1100
5 30 0011 0000
6 2C 0010 1100
7 32 0011 0010 (Ascii for 21 bytes to follow)
8 31 0011 0001 (Ascii for 21 bytes to follow)
9 3A 0011 1010 (Colon)
10 -7F 1000 0001 (Start of actual FRAME)
11 -71 1000 1111
12 72 0111 0010
13 -58 1010 1000
14 24 0010 0100
15 76 0111 0110
16 25 0010 0101
17 -33 1100 1101
18 46 0100 0110
19 25 0010 0101
20 1D 0001 1101
21 -35 1100 1011
22 4F 0100 1111
23 13 0001 0011
24 6 0000 0110
25 -78 1000 1000
26 56 0101 0110
27 19 0001 1001
28 11 0001 0001
29 -3D 1100 0011
30 57 0101 0111
字段的描述-(从冒号后的第一个字节开始。81)
// First byte has FIN bit and frame type opcode = text
// Second byte mask and payload length
// next four bytes for masking key
// So total of 6 bytes for the overhead
// The size of the payload in this case is "F" = 15 (the 4th nibble)
// So total of bytes are (6+15) = 21
// The first byte is saying> FIN bit is set. This is last frame in sequence. The OP code is 1 = TEXT data.
// The second byte is saying> MASK bit is set. The following data will be masked. The data length is "F" = 15
// The 3rd, 4th, 5th, 6th bytes is the masking key. In this case 72, A8, 24, 76.
我现在可以从网络插座发送信息了
boolean getFrame() {
debug.println("getFrame()");
byte bite;
unsigned short payloadLength = 0;
bite = Serial.read();
frame.opcode = bite & 0xf; // Opcode
frame.isFinal = bite & 0x80; // Final frame?
bite = Serial.read();
frame.length = bite & 0x7f; // Length of payload
frame.isMasked = bite & 0x80;
// Frame complete!
if (!frame.isFinal) {
return false;
}
// First check if the frame size is within our limits.
if (frame.length > 126) {
return false;
}
// If the length part of the header is 126, it means it contains an extended length field.
// Next two bytes contain the actual payload size, so we need to get the "true" length.
if (frame.length == 126) {
byte exLengthByte1 = Serial.read();
byte exLengthByte2 = Serial.read();
payloadLength = (exLengthByte1 << 8) + exLengthByte2;
}
// If frame length is less than 126, that is the size of the payload.
else {
payloadLength = frame.length;
}
// Check if our buffer can store the payload.
if (payloadLength > MAX_RECEIVE_MESSAGE_SIZE) {
debug.println("te groot");
return false;
}
// Client should always send mask, but check just to be sure
if (frame.isMasked) {
frame.mask[0] = Serial.read();
frame.mask[1] = Serial.read();
frame.mask[2] = Serial.read();
frame.mask[3] = Serial.read();
}
// Get message bytes and unmask them if necessary
for (int i = 0; i < payloadLength; i++) {
if (frame.isMasked) {
frame.data[i] = Serial.read() ^ frame.mask[i % 4];
} else {
frame.data[i] = Serial.read();
}
}
for (int i = 0; i < payloadLength; i++) {
debug.print(frame.data[i]);
if(frame.data[i] == '/r')
break;
}
return true;
}
// !!!!!!!!!! NOT WORKING
boolean sendMessage(char *data, byte length) {
Serial.print((uint8_t) 0x1); // Txt frame opcode
Serial.print((uint8_t) length); // Length of data
for (int i = 0; i < length ; i++) {
Serial.print(data[i]);
}
delay(1);
return true;
}
看https://github.com/zoutepopcorn/esp8266-Websocket/blob/master/arduino_websocket.ino
现在唯一的问题是arduino的websocket格式
我没有网络套接字的经验,但我认为网络套接字使用UTF-8,而Arduino终端使用ASCII。我在你的代码中没有看到UTF-8和ASCII之间的转换。
消息通常按照批量的方式写入.record batch 是批量消息的技术术语,它包含一条或多条 records.不良情况下, record batch 只包含一条 record.Record batches 和 records 都有他们自己的 headers.在 kafka 0.11.0及后续版本中(消息格式的版本为 v2 或者 magic=2)解释了每种消息格式.点击查看消息格式详情. 5.3.1
我刚刚开始使用使用Apache Camel 2.15.3的应用程序。我是Camel的新手,我正在尝试了解消息是如何发送的,以及路由中组件之间的外观。 应用程序中的路由是使用Spring扩展xml设置的。以下是其中一条路由的示例。 首先是一个简短的术语问题:本示例中的中间bean叫什么?endpoint?组件?还是别的什么?现在我把它们叫做组件。 我现在的主要困惑是理解什么是输入,什么是从一个组件传
1.1.1. 目录 1.1.2. 若琪智能家居协议 1.1.3. 示例 1.1.1. 目录 若琪智能家居协议 请求消息类型 回复消息类型 消息体 示例 一个控制请求 一个控制成功的返回 当发生了错误时的一个返回 1.1.2. 若琪智能家居协议 请求消息类型 命令 Directives 由若琪主动向 Skill 发起的请求,可以是 Skill 开放的 HTTP 服务,或者是 JSON RPC ove
如何格式化WhatsApp Web消息?我试图替换这样的标签: 我试着使用urlencode、htmlspecialchars,什么都没有。 我收到https://api.whatsapp.com/send?phone=XXX
问题内容: JSON.stringify显然不是非常节省空间。例如,当[123456789,123456789]可能需要大约5个字节时,它将占用20+字节。websocket是否在发送到流之前压缩其JSON? 问题答案: 从本质上讲,WebSocket只是用于TEXT或BINARY数据的一组框架。 它本身不执行压缩。 但是,WebSocket规范允许扩展,并且野外有各种各样的压缩扩展(其中一项的正
我有一个来捕获可能发生的: 这里是有问题的对象: 如果在和中发送以下JSON正文: 如何处理在websocket消息上引发的?