How I (Almost) Built an IoT Smart Light Sensor in Java… and What I Learned
The Problem: An Java Networking Exam Question About a Smart Light Sensor
It started as a straightforward exam question:
“You are tasked with developing a Java command-line application that communicates with a smart home IoT device. The device is built on embedded C firmware and runs a lightweight communication driver called ‘Light control v.2.3’. It listens for incoming connections on IP address 192.168.1.100 and port 5000. The device expects a single byte of data: Sending 1 turns ON the smart light, and sending 0 turns OFF the smart light.”
Seemed simple enough. I knew I had to use sockets, so I wrote a program that:
✅ Created a server socket on port 5000
.
✅ Created a client socket to connect to 5000
.
✅ Sent data (1
or 0
) to indicate the light’s state.
Sounds great, right?
Well… I completely misunderstood the question. 💀
Where I Went Wrong
Here is what I wrote as my answer for this question. I thought it required a server implementation instead of a client one and confidently typed all of this out:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import java.io.*;
import java.net.*;
public class ClassExample {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(5000);
Socket socket = new Socket("191.162.1.10", 5000);
serverSocket.accept();
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter output = new PrintWriter(socket.getOutputStream(), true);
int data;
data = input.read();
if (data == 1) {
System.out.println("The light sensor is turned ON");
}
else if (data == 0) {
System.out.println("The light sensor is turned OFF");
}
else {
System.out.println("Error. Expected input is 1 or 0");
}
serverSocket.close();
socket.close;
}
catch(IOException e) {
e.printStackTrace();
}
}
}
This is obviously wrong. I had the right idea, kind of, but my implementation was totally off.
1️⃣ I Accidentally Made Both a Server and a Client in One Program
This was really my biggest mistake. My code tried to be both the client and the server at the same time. I wrote:
1
2
ServerSocket serverSocket = new ServerSocket(5000);
Socket socket = new Socket("192.168.1.100", 5000);
🚨 Mistake:
- A server listens for connections. A client connects to a server.
- The server doesn’t need to create a client socket; it just waits for clients to connect.
- Instead of
Socket socket = new Socket(...)
, I should’ve usedserverSocket.accept()
to wait for a client.
2️⃣ I Used Byte
Instead of int
for Input
Since the question asked for “a single byte of data,” I declared my variable like this:
1
2
Byte data;
data = input.read();
🚨 Mistake:
Byte
in Java is a wrapper class, not a primitive type.input.read()
returns an integer (ASCII value), not aByte
.
✅ Fix: Change Byte
to int
:
1
int data = input.read();
✅ The Correct Client-Side Code
If I had understood this question correctly, here’s what my answer would look like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
public class LightSensorClient {
public static void main(String[] args) {
String deviceIP = "192.168.1.100"; // IP of the IoT device
int port = 5000; // The device listens on this port
try (Socket socket = new Socket(deviceIP, port)) {
OutputStream outputStream = socket.getOutputStream();
Scanner scanner = new Scanner(System.in);
System.out.print("Enter sensor value (1 for ON, 0 for OFF): ");
int userInput = scanner.nextInt();
if (userInput == 1 || userInput == 0) {
outputStream.write(userInput); // Send a single byte (1 or 0)
outputStream.flush();
System.out.println("Command sent successfully.");
} else {
System.out.println("Invalid input. Please enter 1 or 0.");
}
scanner.close();
} catch (Exception e) {
System.out.println("Error: Unable to connect to the IoT device.");
e.printStackTrace();
}
}
}
This Implemetation:
- Connects to the IoT device on IP
192.168.1.100
, port5000
. - Asks the user for
1
or0
. - Sends the value as a single byte to the device.
What I Learned
- Always read the question carefully. The IoT device itself was the server, meaning I only needed to write a client.
- When communicating with IoT devices, check if the device expects raw byte data instead of string data. I unfortunately couldn’t run the code during the exam, so there was no way for me to actually check.
- Don’t overcomplicate the solution—focus only on what’s asked! I feel so stupid for making such a noob mistake, but sh*t happens. Hopefully I’ll get a few marks for at least having the right idea, sort of.