Loubear
Loubear

Reputation: 71

Sending data from Java server to ESP8266

This is my first post here so bear with me if I make any mistakes...

Okay so I'm simply trying to have a Java program running on my computer send information to an ESP8266 running the arduino software. First off, here's the code.

ESP8266(Arduino):

#include <ESP8266WiFi.h>

#define NAME "********"
#define PASS "********"

const char* host = "192.168.1.6";

WiFiClient client;

void setup() {
  Serial.begin(115200);
  Serial.println();
  WiFi.begin(NAME, PASS);
  Serial.print("Connecting");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();
  Serial.print("Connected, IP address: ");
  Serial.println(WiFi.localIP());

  if (client.connect(host, 9090)) {
    Serial.print("Connected to: ");
    Serial.println(host);
    String data = "No Message";
    client.print("ESP8266 connected!");
    if(client.available()) {
      data = client.readStringUntil('\n');
    }
    Serial.print("Host message: ");
    Serial.println(data);
    client.stop();
  } else {
    client.stop();
  }
}

void loop() {
}

Java Server:

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

    public static void main(String[] args) throws IOException {

        ServerSocket listener = new ServerSocket(9090);
        try{
            while(true){
                Socket socket = listener.accept();
                socket.setKeepAlive(true);
                try{
                    BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                    out.write("Hello from Java!\n");
                } finally {
                    socket.close();
                }
            }
        } finally {
            listener.close();
        }
    }

}

The problem is that client.available() never returns true, even when information is sent by the Java server to the client. I have tried sending data from the Arduino to the server and that works just fine. I also made a quick Java program that could run as a client and ran this on another computer on the network. The Java server and client in this case communicated just fine. So the problem lies somewhere in the Arduino, but I'm at a loss as to what it is.

Upvotes: 3

Views: 6485

Answers (3)

Loubear
Loubear

Reputation: 71

The issue here appears to have been with

client.print() 

Replacing that with

client.println()

Fixed my issue.

I believe this was somehow stalling the input buffer server side as it was waiting for a newline but never getting one. I'll post the updated code that works below for any having this issue.

ESP8266:

#include <ESP8266WiFi.h>

#define NAME "********"
#define PASS "********"

const char* host = "10.0.0.15";

WiFiClient client;

void setup() {
  Serial.begin(115200);
  Serial.println();

  /* Set Client up as station */
  WiFi.mode(WIFI_STA);

  WiFi.begin(NAME, PASS);

  /* Connect to the network */
  Serial.print("Connecting");
  while(WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println();

  Serial.print("Connected, IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  if (client.connect(host, 9090))
  {
    Serial.print("Connected to: ");
    Serial.println(host);

    /* Send "connected" to the server so it knows we are ready for data */
    client.println("deviceconnected"); //USE client.println()!!
    Serial.println("Host message: \n");

    /* Wait for data for 5 seconds at most before timing out */
    unsigned long timeout = millis();
    while(client.available() == 0)
    {
      if(millis() - timeout > 5000)
      {
        Serial.println("Timeout to server!");
        break;
      }
    }

    /* Read in the data in the stream */
    while(client.available() > 0)
    {
      Serial.println(client.readStringUntil('\n'));
    }
    client.stop();
  }
  else
  {
    client.stop();
  }
  delay(5000);
}

Java Server:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

    public static void main(String[] args) throws IOException {

        ServerSocket listener = new ServerSocket(9090);
        try{
            while(true){
                Socket socket = listener.accept();
                socket.setKeepAlive(true);
                System.out.println("Client Connected");
                try{
                    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    System.out.println("Client response: " + in.readLine());

                    BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                    System.out.println("Sending Message...");
                    out.write("Hello\n from Java!\n");
                    out.flush();
                } finally {
                    socket.close();
                }
            }
        } finally {
            listener.close();
        }
    }

}

Upvotes: 4

Its Me
Its Me

Reputation: 56

I had the same problem, here is my solution:
Java only updates the outputstream when you add out.flush(); after out.write();

Also

client.available()

is returning 0 until you read something. For example

String first_line = client.readStringUntil('\n');

After this you can use the available() method.


Test with the String "Hello,\nthis is a text\n":

client.println(client.available()); // 0

String first_line = client.readStringUntil('\n');

client.println(first_line); // Hello,
client.println(client.available()); // 17

To send all messages back to the client:

client.print("First: ");
client.println(first_line);

while(client.available() > 0) {
  client.println("Next: " + client.readStringUntil('\n'));
}

Output:

First: Hello,
Next: this is a text
Next: 

Upvotes: 0

dda
dda

Reputation: 6203

That part of your code belongs to the loop() event:

  if (client.connect(host, 9090)) {
    Serial.print("Connected to: ");
    Serial.println(host);
    String data = "No Message";
    client.print("ESP8266 connected!");
    if(client.available()) {
      data = client.readStringUntil('\n');
    }
    Serial.print("Host message: ");
    Serial.println(data);
    client.stop();
  } else {
    client.stop();
  }

The setup() function is run once only. After it moves on to loop() and stays there. And your loop() function is empty...

Upvotes: 0

Related Questions