I'm attempting to create a server using the Arduino R4 Wifi, and have a Java program on my laptop connect to this server (or vice versa, however I feel like a Arduino server with a Java client is more useful, and I already tried to swap the server and client roles and couldn't get that to work). Both of them are on the same local network. Unfortunately, when I run the java program, I get a connection refused exception. I assume it is related to the program not being able to find the Arduino server on my network.
What I have:
A windows 11 HP laptop
An Arduino R4 Wifi
Arduino server code:
#include <WiFiS3.h>
#include "secrets.h"
WiFiServer server(80);
char ssid[] = SECRET_SSID; //My Network's name stored in "secrets.h"
char pass[] = SECRET_PASS; //My Network's password stored in "secrets.h"
int status = WL_IDLE_STATUS;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
while(!Serial) {
;
}
connectWifi();
server.begin();
printWiFiStatus();
}
void printWiFiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi shield's IP address:
IPAddress local = WiFi.localIP();
Serial.print("Local IP Address: ");
Serial.println(local);
// IPAddress gateway = WiFi.gatewayIP();
// Serial.print("Gateway IP Address: ");
// Serial.println(gateway); //Returns 000.000.0.0 for some reason
}
void connectWifi() {
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
while (true);
}
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}
Serial.print("Creating access point named: ");
Serial.println(ssid);
status = WiFi.beginAP(ssid, pass);
if (status != WL_AP_LISTENING) {
Serial.println("Creating access point failed");
// don't continue
while (true);
}
}
void loop() {
// put your main code here, to run repeatedly:
if (status != WiFi.status()) {
// it has changed update the variable
status = WiFi.status();
if (status == WL_AP_CONNECTED) {
// a device has connected to the AP
Serial.println("Device connected to AP");
} else {
// a device has disconnected from the AP, and we are back in listening mode
Serial.println("Device disconnected from AP");
}
}
// Serial.println("Listening for a connection!");
WiFiClient client = server.available();
if(client) {
Serial.println("A client has connected!");
Serial.println(client.remoteIP());
}
}
As you can tell, most of this code is copied from examples because 1. It works, and 2. I want to get the basics working before I move on.
Java client code:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
int port = 80; //The arduino server's port
String ipAddress = "192.168.4.1"; //The suppossed IPAddress of the Arduino server
BufferedReader reader;
BufferedWriter writer;
public Client() {
initConnection();
}
private void initConnection() {
try {
//Attempt to connect to the arduino server (Unlike the WiFiS3 library which consistently calls a command listening for clients, this command waits until it finds a server to connect to, holding up the rest of the program)
Socket connection = new Socket(ipAddress, port); //This is the line that is generating the 'Timeout error'.
System.out.println("Connected to server!");
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream()));
sendMessage();
} catch (UnknownHostException e) {
System.out.println("Unable to connect to server\nExiting program ):");
e.printStackTrace();
System.exit(0);
} catch (IOException e) {
System.out.println("Error when attempting to create IO streams maybe?\nExiting program ):");
e.printStackTrace();
System.exit(0);
}
}
void sendMessage() {
try {
writer.write("Java client has connected.");
writer.newLine();
writer.flush();
} catch (IOException e) {
System.out.println("Failed to write ):");
e.printStackTrace();
}
}
}
When running the java program, I get this output:
Error when attempting to create IO streams maybe?
Exiting program ):
java.net.ConnectException: Connection refused: connect
at java.base/sun.nio.ch.Net.connect0(Native Method)
at java.base/sun.nio.ch.Net.connect(Net.java:589)
at java.base/sun.nio.ch.Net.connect(Net.java:578)
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:583)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
at java.base/java.net.Socket.connect(Socket.java:760)
at java.base/java.net.Socket.connect(Socket.java:695)
at java.base/java.net.Socket.<init>(Socket.java:564)
at java.base/java.net.Socket.<init>(Socket.java:328)
at Client.initConnection(Client.java:24)
at Client.<init>(Client.java:18)
at App.main(App.java:3)
PS C:\Users\(The director of the program)
Programs\clientForArduino>
What I tried:
- Before starting the client, I tested a modified version of the java program with a java server, and it successfully connected.
- I looked through a lot of online examples, although I had trouble finding content related to my topic.
- I attempted to assign an IPAddress for the Arduino R4 in code, however I wasn't able to get that working.
- I changed the IPAddress in the java client code to each of the following:
- In my wifi router's app (I have an eero), I checked for connected devices and found 2 ESPs, and used their IPAddresses, however that didn't connect. Also, when unplugging the Arduino from my computer, presumably the connected device list in the app would change, however both ESPs remained online, and no device was added or removed.
- Turning off my windows firewall to see if the device would connect, although this still failed.
Something interesting I noticed is that a few hours after attempting to fix the problem, the Arduino's IPAddress (it's printed to the serial monitor) randomly changed from 192.168.4.1 to 192.168.4.41, although for only 2 iterations of running the program, then it reverted back to the IP ending in '.4.1'. When attempting to connect the java program using this new IPAddress, I got a new error:
Error when attempting to create IO streams maybe?
Exiting program ):
java.net.ConnectException: Connection timed out: connect
at java.base/sun.nio.ch.Net.connect0(Native Method)
at java.base/sun.nio.ch.Net.connect(Net.java:589)
at java.base/sun.nio.ch.Net.connect(Net.java:578)
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:583)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
at java.base/java.net.Socket.connect(Socket.java:760)
at java.base/java.net.Socket.connect(Socket.java:695)
at java.base/java.net.Socket.<init>(Socket.java:564)
at java.base/java.net.Socket.<init>(Socket.java:328)
at Client.initConnection(Client.java:23)
at Client.<init>(Client.java:18)
at App.main(App.java:3)
Furthermore, on my wifi router's app, it says the router itself has 192.168.4.1 as the IPAddress, so the Arduino should definitely not be printing out that as its IP.
When researching, I found that Arduino R4s on default should have 192.168.4.1 as the IP, however, another google query says that the R4 WiFi should have a dynamic IP, not a static one. I'm pretty sure there's a difference between the local IP Address and the one used to connect to the internet, so perhaps that explains it?
To clarify my questions, I'm asking:
- Why can't the Java client find the Arduino R4 server on the network, and is it a problem relating to how IPAddresses, routers, and ports work, or is it a problem in the code?
- Why is the Arduino WiFi's IPAddress the same as the router, and why did it change for a short time?
- Is the IPAddress for the Arduino static or dynamic?
P.S. If I wrote too much, it would be helpful to tell me what to get rid of (I have no clue if this enough, too little, or too much info).