代码之家  ›  专栏  ›  技术社区  ›  PL76

ESP8266和Android socket无法通信

  •  2
  • PL76  · 技术社区  · 7 年前

    我在使用套接字与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 socket的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服务器”。因此,我认为socket服务器应该基于此启动并运行。任何帮助都将不胜感激。

    [编辑] 感谢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在Android设备上创建套接字时。Java语言我使用的websockets:

    mWebSocketClient = new WebSocketClient(uri)
    

    我发现,如果在创建套接字时不指定草稿版本,则默认为websockets版本8,该版本不适用于ESP8266(至少不适用于arduinowebsockets库)。我必须使用以下方法创建套接字:

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

    在此之后,websocket被创建为现在可以使用的版本13。

    问题现已解决!

    1 回复  |  直到 7 年前
        1
  •  3
  •   PL76    7 年前

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