ESP8266客户端通过网络连接(无库,只有AT命令)



我正在使用AT命令在客户端实现websocket
我已经将此作为基线并阅读了此内容
硬件:ESP8266+arduino uno。

代码:

String cmd = "AT+CIPSTART="TCP",""; cmd += SERVER_IP; cmd += "",81"; //Start a TCP connection.  to server SERVER_IP on port 81
if (!sendCommand(cmd, "OK", CONTINUE))
return;
delay(2000);
if (!sendCommand("AT+CIPSTATUS", "OK", CONTINUE))// Check for TCP Connection status.
return;
cmd = "GET 192.168.43.228:81 HTTP/1.1rn";
cmd += "Host: 192.168.43.228:81rn";
cmd += "Upgrade: websocketrn";
cmd += "Connection: Upgradernrn";
if (!sendCommand("AT+CIPSEND=" + String(cmd.length()), ">", CONTINUE)) {
sendCommand("AT+CIPCLOSE", "", CONTINUE);
Serial.println("Connection timeout.");
return;
}
sendCommand(cmd, "OK", CONTINUE);// Send data to server.
delay(1000);
readResponseData("");

登录arduino端:

ESP8266 Demo
AT+RST
OK
bBֆ@⸮Sc⸮⸮⸮ȤS⸮⸮⸮ɥ⸮⸮⸮⸮H⸮
[System Ready
, Vendo:⸮ݹ⸮⸮⸮ɹcom]
AT+GMR
0018000902
OK
AT+CWMODE?
+CWMODE:1
OK
AT+CWMODE=1
no change
AT+CWMODE=1
no change
AT+CIPMUX=0
OK
AT+CWJAP="AndroidAP","xxxx"
OK
Connected to WiFi.
AT+CWJAP="AndroidAP","xxxxx"
OK
AT+CWSAP=?
no this fun
AT+CIFSR
192.168.43.29
OK
Module is ready.
AT+CIPSTART="TCP","192.168.43.228",81
OK
Linked
AT+CIPSTATUS
STATUS:3
+CIPSTATUS:0,"TCP","192.168.43.228",81,0
OK
AT+CIPSEND=100
>
GET 192.168.43.228:81 HTTP/1.1
Host: 192.168.43.228:81
Upgradewrong syntax
ERROR
SEND OK

OK
Unlink

服务器端:

WiFi connected
IP address:
192.168.43.228
Server available at ws://192.168.43.228:81
Accepted new web sockets client at index 0

--

而不是来自服务器的任何其他信息,该服务器应该在接受websocket后立即发送消息。

请给我一些见解:(

我找到了一个解决方案。

事实上,我并不知道RFC4566 的所有细节

在成功握手之后,您需要符合框架要求。它不仅仅是原始文本:(

对于有限的用例(即长度<125(,以下是解决方案的概述:

char str[] = "Hello";
char buf[125];
bool toMask = true;
uint8_t extra = toMask ? 6 : 2;
buildFrame(str, buf, WS_OPCODE_TEXT, toMask);   
ESP8266SendData(0, buf, str.length() + extra);

我已经测试过了:

void buildFrame(char *str, uint8_t *ret, uint8_t opcode, bool maskon) {
uint8_t mask[4];
int size = strlen(str);
// Opcode; final fragment
ret[0] = opcode | WS_FIN;
ret[1] = (uint8_t) (size) | (maskon == true ? WS_MASK : 0);
if (maskon) {
mask[0] = random(0, 256);
mask[1] = random(0, 256);
mask[2] = random(0, 256);
mask[3] = random(0, 256);
for (int i = 2; i < 4 + 2; ++i) {
ret[i] = mask[i - 2];
}
for (int i = 6; i < size + 6; i++) {
ret[i] = str[i - 6] ^ mask[(i - 6) % 4];
}
}
else {
for (int i = 2; i < size + 2; ++i) {
ret[i] = (uint8_t) str[i - 2];
}
}
}

对于帧解码:

uint8_t extractPayload(String buffer, String& payload) {
// here only payloads whose size < 125
bool FIN = buffer[0] & WS_FIN;
uint8_t opcode = buffer[0]  & ~WS_FIN;
bool hasMask = buffer[1] & WS_MASK;
uint8_t len = buffer[1]  & ~WS_MASK;
uint8_t mask[4];
if (hasMask) {
mask[0] = buffer[2];
mask[1] = buffer[3];
mask[2] = buffer[4];
mask[3] = buffer[5];
for (int i = 6; i < len + 6; i++) {
payload += (char) (buffer[i] ^ mask[(i - 6) % 4]);
}
}
else {
payload = buffer.substring(2);
}
Serial.print("FIN = "); Serial.println(FIN, HEX);
Serial.print("Opcode = "); Serial.println(opcode, HEX);
Serial.print("Mask = "); Serial.println(hasMask, HEX);
Serial.print("Payload length = "); Serial.println(len, HEX);

return opcode;
}

最新更新