ESP8266和Android套接字无法通信

时间:2018-01-03 20:19:50

标签: java android sockets esp8266

我在使用我的Android设备和ESP8266使用套接字进行通信时遇到问题。以下是ESP8266的代码:

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsServer.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <Hash.h>

ESP8266WebServer server = ESP8266WebServer(80);
WebSocketsServer webSocket = WebSocketsServer(81);

void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
  switch (type) {
    case WStype_DISCONNECTED:
      Serial.printf("[%u] Disconnected!\n", num);
      break;
    case WStype_CONNECTED: {
        IPAddress ip = webSocket.remoteIP(num);
        Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);

        // send message to client
        webSocket.sendTXT(num, "Connected");
      }
      break;
    case WStype_TEXT:
      IPAddress ip = webSocket.remoteIP(num);
      Serial.printf("$%s?\n", payload);
      webSocket.sendTXT(num, payload, sizeof(payload), false);
      break;
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println();
  Serial.println();
  for (uint8_t t = 4; t > 0; t--) {
    Serial.printf("[SETUP] BOOT WAIT %d...\n", t);
    Serial.flush();
    delay(1000);
  }
  Serial.println("Starting AP");
  WiFi.mode(WIFI_AP);
  WiFi.softAP("Alpine_SIM_CNTRL", "12345678");
  Serial.println("AP Started");

  Serial.println("Starting Socket");
  // start webSocket server
  webSocket.begin();
  webSocket.onEvent(webSocketEvent);
  Serial.println("Socket Started");

  if (MDNS.begin("simcontrol")) {
    Serial.println("MDNS responder started");
  }
  Serial.println("Starting Server");
  //handle index
  server.on(
  "/", []() {
    server.send(200, "text/plain", "You are connected");
  });

  server.begin();
  Serial.println("Server Started");

  //Add service to MDNS
  MDNS.addService("http", "tcp", 80);
  MDNS.addService("ws", "tcp", 81);
}

void loop() {
  webSocket.loop();
  server.handleClient();
}

以下是适用于Android的套接字的Java代码:

public class WriteToServer extends AsyncTask<MyTaskParams, Void, String> {
  Context context;
  Socket socket;

  public WriteToServer(MyTaskParams Params) {
  }

  @Override
  protected String doInBackground(MyTaskParams... params) {
    socket = null;
    DataInputStream in = null;
    DataOutputStream out = null;
    context = params[0].context;
    String command = params[0].cmd;
    String response = null;
    try {
      socket = new Socket("192.168.4.1", 81);
      out = new DataOutputStream(socket.getOutputStream());
      in = new DataInputStream(socket.getInputStream());
      out.writeUTF(command);
      Log.i("Command", "Command sent: " + command);
      while (in.available() > 0) {
        response = in.readUTF();
      }
    } catch (IOException e) {
      e.printStackTrace();
      Log.e("Error", "There was an error writing to the socket. Thrown IO exception");
    } finally {
      if (socket != null) {
        try {
          Log.i("INFO", "closing the socket");
          socket.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (in != null) {
        try {
          in.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (out != null) {
        try {
          out.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
    return response;
  }
}

任何人都可以指出为什么我没有得到任何沟通?在Android Studio中使用调试器我可以看到套接字连接到正确的地址和端口,但是当我向ESP发送内容时,它不会打印出我发送或回复的内容。如果我用我的电脑连接ESP并输入192.168.4.1:81/***,我会收到一条回复,声明“这只是一个websocket服务器”。所以我认为套接字服务器应该基于此启动并运行。任何帮助将不胜感激。

[编辑] 感谢Codo的回复,我知道我在服务器和客户端上使用了两种不同的套接字技术。我现在正在使用Java WebSockets。我现在可以在ESP上看到Android设备正在尝试连接,但ESP立即关闭连接。以下是来自ESP设备的调试:

[WS-Server][0] new client from 192.168.4.2
[WS-Server][0][handleHeader] RX: GET / HTTP/1.1
[WS-Server][0][handleHeader] RX: Connection: Upgrade
[WS-Server][0][handleHeader] RX: Host: 192.168.4.1:81
[WS-Server][0][handleHeader] RX: Sec-WebSocket-Key: LmtO2xH7n9k+KKJNN/4+GA==
[WS-Server][0][handleHeader] RX: Sec-WebSocket-Version: 8
[WS-Server][0][handleHeader] RX: Upgrade: websocket
[WS-Server][0][handleHeader] Header read fin.
[WS-Server][0][handleHeader]  - cURL: /
[WS-Server][0][handleHeader]  - cIsUpgrade: 1
[WS-Server][0][handleHeader]  - cIsWebsocket: 1
[WS-Server][0][handleHeader]  - cKey: LmtO2xH7n9k+KKJNN/4+GA==
[WS-Server][0][handleHeader]  - cProtocol:
[WS-Server][0][handleHeader]  - cExtensions: <null>
[WS-Server][0][handleHeader]  - cVersion: 8
[WS-Server][0][handleHeader]  - base64Authorization:
[WS-Server][0][handleHeader]  - cHttpHeadersValid: 1
[WS-Server][0][handleHeader]  - cMandatoryHeadersCount: 0
[WS-Server][0][handleHeader] no Websocket connection close.
[WS-Server][0] client disconnected.

任何人都可以帮我弄清楚为什么ESP正在关闭连接吗?

[更新并修复] 我已经解决了这个问题。使用org.java.websockets在Android设备上创建套接字时我正在使用:

mWebSocketClient = new WebSocketClient(uri)

我发现如果你在创建套接字时没有分配草稿版本,它默认为websockets版本8,它不适用于ESP8266(至少没有使用arduinowebsockets库。我必须使用以下内容:

mWebSocketClient = new WebSocketClient(uri, new Draft_17())

在此之后,websocket被创建为版本13,现在可以正常工作。

问题现已解决!

1 个答案:

答案 0 :(得分:0)

您正在混合两个不同的概念:在Java中,您使用相当低级的Unix套接字,在ESP上使用与HTTP密切相关的WebSocket。获取适合Java的WebSocket客户端库。 - Codo 1月4日17:33