简体   繁体   中英

How do I make a java app communicate with an ESP32 board?

I've been trying to establish a TCP socket connection between an ESP32 board and a Java server. After establishing the connection, I want the server to send a packet to the ESP32 to request its ID (I use the ID to identify the clients, as there are going to be more of them), but the server doesn't seem to be transmitting anything (ESP32 isn't receiving anything). I even tried using Wireshark to track the packets, but upon connection, there is no message to be seen. Sorry for the horrible code, I'm still a beginner, when it comes to communication programming. Thanks in advance for your help.

Here is the code for the ESP32:

#include <WiFi.h>

WiFiClient client;

// network info
char *ssid = "SSID";
char *pass = "Password";

// wifi stats
int wifiStatus;
int connAttempts = 0;

// Client ID
int id = 128;

IPAddress server(192,168,1,14);
int port = 3241;

String inData;

void setup() {
  Serial.begin(115200); // for debug

  // attempting to connect to the network
  wifiStatus = WiFi.begin(ssid, pass);
  while(wifiStatus != WL_CONNECTED){
    Serial.print("Attempting to connect to the network, attempt: ");
    Serial.println(connAttempts++);
    wifiStatus = WiFi.begin(ssid, pass);
    delay(1000);
  }

  // info
  Serial.print("Connected to the network, IP address is: '");
  Serial.print(WiFi.localIP());
  Serial.print("', that took ");
  Serial.print(connAttempts);
  Serial.println(" attempt(s).");
  connAttempts = 0;

  // connection to the main server
  Serial.println("Starting connection to the server...");
  while(!client.connect(server, port)){
    Serial.print("Attempting connection to the server, attempt no. ");
    Serial.println(connAttempts++);
    delay(1000);
  }
  Serial.print("Connection successful after ");
  Serial.print(connAttempts);
  Serial.println(" attempt(s)!");
}

void loop() {
  if(client.available()){
    Serial.println("Incoming data!");
    inData = client.readString();
  }
  if(inData != ""){
    Serial.print("Incoming data: ");
    Serial.println(inData);

    if(inData == "REQ_ID"){
      String msg = "INTRODUCTION;"
      strcat(msg, m);
      client.print(msg);
    }
    inData = "";
  }
  if(!client.connected()){
    Serial.println("Lost connection to the server! Reconnecting...");
    connAttempts = 0;
    while(!client.connect(server, port)){
      Serial.print("Attempting connection to the server, attempt no. ");
      Serial.println(connAttempts++);
      delay(1000);
    }
    Serial.print("Reconnection successful after ");
    Serial.print(connAttempts);
    Serial.println(" attempt(s)!");
  }
  delay(10);
}

And here is the client handler class from the Java server:

package org.elektrio.vsd2020;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;

public class ClientHandler implements Runnable {

    public Socket netSocket;
    public BufferedInputStream in;
    public BufferedOutputStream out;

    private int clientID;

    public ClientHandler(Socket skt) throws IOException {
        this.netSocket = skt;

        this.in = new BufferedInputStream(this.netSocket.getInputStream());
        this.out = new BufferedOutputStream(this.netSocket.getOutputStream());
    }

    public void close() throws IOException{
        this.in.close();
        this.out.close();
        this.netSocket.close();
    }

    @Override
    public void run() {
        while(netSocket.isConnected()){
            try{
                byte[] arr = new byte[2048];
                in.read(arr);
                String[] input = new String(arr, StandardCharsets.US_ASCII).split(";");

                // if the message is tagged as "INTRODUCTION", it identifies a reply from the ESP32, which contains the client ID
                if(input[0].equals("INTRODUCTION")){
                    clientID = Integer.parseInt(input[1]);
                }
            }
            catch (IOException e) {
                System.out.println("[" + LocalDateTime.now() + " at ClientHandler] Exception at client ID '" + clientID + "'!");
                e.printStackTrace();
            }
        }
        System.out.println("[" + LocalDateTime.now() + " at ClientHandler] Client ID '" + clientID + "' disconnected!");
        Tools.clients.remove(this);
    }

    public int getID(){
        return clientID;
    }

    public int reqID() throws IOException{
        String req = "REQ_ID";
        out.write(req.getBytes(StandardCharsets.US_ASCII));
    }
}

Server's main class:

package org.elektrio.vsd2020;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main {

    public static ServerSocket server;
    public static ServerSocket remoteAccessServer;

    public static ExecutorService pool;

    public static boolean serviceRunning = true;

    public static void main(String[] args) {
        try{
            // startup args
            int port = args.length > 0 ? Integer.parseInt(args[0]) : 3241;                  
            int maxClients = args.length > 1 ? Integer.parseInt(args[2]) : 10;

            // startup parameters info
            Tools.log("Main", "Server started with parameters: ");
            if(args.length > 0) Tools.log("Main", args);
            else Tools.log("Main", "Default parameters");

            // server socket and the threadpool, where the client threads get executed
            server = new ServerSocket(port);
            pool = Executors.newFixedThreadPool(maxClients);

            // main loop
            while(true){
                if(Tools.clients.size() < maxClients){

                    // connection establishment
                    Socket clientSocket = server.accept();
                    ClientHandler client = new ClientHandler(clientSocket);

                    Tools.log("Main", "New client connected from " + clientSocket.getRemoteSocketAddress());

                    // starting the client operation
                    pool.execute(client);
                    Tools.clients.add(client);
                    Thread.sleep(500);
                    client.reqID();
                }
            }
        }
        catch (IOException | InterruptedException ioe){
            Tools.log("Main", "IOException at MAIN");
            ioe.printStackTrace();
        }
    }
}

And lastly, the Tools class

package org.elektrio.vsd2020;

import java.time.LocalDateTime;
import java.util.ArrayList;

public class Tools {

    public static ArrayList<ClientHandler> clients = new ArrayList<>();

    public static void log(String origin, String message){
        System.out.println("[" + LocalDateTime.now() + " at " + origin + "] " + message);
    }

    public static void log(String origin, String[] messages){
        for(String msg : messages) System.out.println("[" + LocalDateTime.now() + " at " + origin + "] " + msg);
    }

}

I have some recommendations:

I- Your server implementation, ie while(true){... Thread.sleep(500); ... }, resembles microcontroller-style programming. Java has much more powerful tools for socket communication, such as reactive frameworks. I suggest using frameworks like Netty:

Netty 4 User Guide

Introduction to Netty

It may require some effort to learn these but their performance is much better.

And also there exists modern protocols for IoT systems, like MQTT or even RSocket. You can use them instead of plain TCP connection.

II: In IoT systems, isolating the problem is very important. So in your case, using TCP terminal tools like Hercules helps a lot. These tools can act as both server and client; so you can use them instead of ESP32 and Java Server and test if the other side works well.

III: In IoT communications, try to limit the messages. Thus Instead of this conversion between ESP32 and Java:

ESP32: Hi

Java: Hello, who are you?

. My ID is...

. Pass me the data...

. Here is the data...

Use this:

ESP32: Hi. I am ID.. and This is my data

Server: OK Thanks!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM