I am trying to do TCP transmission from Photon to computer (with my computer as the server), and I was able to connect the Photon by Serial and retrieve data and I was able to read a string from client.println(“HelloWorld”); but when I put the statement in a loop to read sensor data, it is transmitting nothing. Do you know what is going on? How to fix this?
Also, on the side, sometimes when I put my delay under 100ms putty/Serial-connection doesn’t want to connect. Is this normal? I thought Serial can go up to 9600 Baud.
Particle code:
int sensor1 = A1;
int sensorV = 0;
char sensorStr[64];
int data;
int i;
char * buffer;
TCPClient client;
byte server[] = { 10,0,0,3}; // IP address
void server_connect()
{
Serial.println("connecting...");
if (client.connect(server, 6780))
{
Serial.println("connected");
client.println("HELLO");
}
else
{
Serial.println("connection failed");
}
}
void setup()
{
// Make sure your Serial Terminal app is closed before powering your device
Serial.begin(9600);
// Now open your Serial Terminal, and hit any key to continue!
//while(!Serial.available())
Particle.process();
server_connect();
}
void loop()
{
// Sleep 1 sec
// byte[] data = sensor.read();
// client.println(data);
if (client.available())
{
data = analogRead(sensor1);
Serial.println(data);
client.println(data);
delay(1);
}
if (!client.connected())
{
Serial.println("disconnecting.");
client.stop();
server_connect();
}
}
Java TCPServer code:
class TCPServer
{
public static void main(String argv[]) throws Exception
{
String clientSentence;
String capitalizedSentence;
ServerSocket welcomeSocket = new ServerSocket(6780);
System.out.println("TCP server running");
while(true)
{
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient =
new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
System.out.println("Received: " + clientSentence);
capitalizedSentence = clientSentence + '\n';
outToClient.writeBytes(capitalizedSentence);
}
}
}
I think the problem is that in loop, you have a test for if (client.available())
. This will only read the sensor and print a response when the server has sent bytes. And the server doesn’t appear to send anything; it just immediately waits for data.
But the serial command in the loop still works/transmits… So I know it’s working. Just the client.println() isnt.
And I tried removing the if(client.available()), but it did nothing.
I now see that you send HELLO from connect, which is what’s causing data to be transmitted to the Photon, which is why client.available() returns true.
But the Java code seems to only read a single line per connection. The while(true) loop accepts multiple connections from different devices, but the code only reads one line from each, and that’s the HELLO line.
1 Like
Ahh I see. So do you have any ideas on how to modify the code so that it reads mulitiple lines for a connection? All I can think of is changing the inFromClient.readLine(); but that shouldn’t matter as the statement is already in a loop.
Just for testing purposes, I’d put this:
clientSentence = inFromClient.readLine();
if (clientSentence == null)
break;
System.out.println("Received: " + clientSentence);
capitalizedSentence = clientSentence + '\n';
outToClient.writeBytes(capitalizedSentence);
in another while(true)
loop to see if it work better. There are two loops, one for connections and one for lines on connections, nested within each other.
But the actual solution is much more complicated, probably involving threads.
Ok. So it works. YAY. It is able to transmit data to the server; however, it can only transmit 50 data points before timingout. To fix the timeout issue the only suggestion online that I could find was to use a try-catch exception. But they described it poorly and they said that the exception still pops-up every 7 seconds. Any clue on how to fix the timeout exception in my code?
Exception in thread “main” java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at TCPServer.main(TCPServer.java:26)
Java TCPServer code:
import java.io.;
import java.net.;
class TCPServer
{
public static void main(String argv[]) throws Exception
{
String clientSentence;
String capitalizedSentence;
ServerSocket welcomeSocket = new ServerSocket(6780);
System.out.println(“TCP server running”);
while(true)
{
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient =
new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
System.out.println("Received: " + clientSentence);
capitalizedSentence = clientSentence + '\n';
outToClient.writeBytes(capitalizedSentence);
while(true)
{
clientSentence = inFromClient.readLine();
if (clientSentence == null)
break;
System.out.println("Received: " + clientSentence);
capitalizedSentence = clientSentence + '\n';
outToClient.writeBytes(capitalizedSentence);
}
}
}
}
Here’s an example of how I would structure a TCP server listener in Java:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashSet;
public class JavaServerSample {
private int portNumber = 7123;
private ServerSocket serverSocket;
private HashSet<ClientThread> clientThreads = new HashSet<ClientThread>();
public void start() throws IOException {
//
serverSocket = new ServerSocket(portNumber);
serverSocket.setReuseAddress(true);
addClientThread();
}
public void addClientThread() {
ClientThread ct = new ClientThread();
synchronized(clientThreads) {
clientThreads.add(ct);
}
(new Thread(ct)).start();
}
public void removeClientThread(ClientThread ct) {
synchronized(clientThreads) {
clientThreads.remove(ct);
}
}
public class ClientThread implements Runnable {
private boolean keepRunning = true;
private Thread thread;
private Socket socket;
private BufferedReader br = null;
private PrintWriter pw = null;
public void destroy() {
keepRunning = false;
if (thread != null) {
thread.interrupt();
}
}
@Override
public void run() {
thread = Thread.currentThread();
try {
socket = serverSocket.accept();
// Add another client thread after accepting a connection so we always have numThreads spare threads
addClientThread();
System.out.println("connection from " + socket.getRemoteSocketAddress().toString());
// Use br to read from the remote TCP client (Photon)
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// Use pw to print to the remote TCP client (Photon)
pw = new PrintWriter(socket.getOutputStream());
while(keepRunning) {
String line = br.readLine();
if (line == null) {
break;
}
System.out.println("got: " + line);
pw.println("you sent: " + line);
pw.flush();
}
}
catch(Exception e) {
System.out.println("exception " + e.toString());
}
finally {
try {
if (pw != null) {
pw.close();
}
if (br != null) {
br.close();
}
if (socket != null) {
socket.close();
}
}
catch(IOException e2) {
}
}
System.out.println("cleaning up client");
removeClientThread(this);
}
}
public static void main(String[] args) {
JavaServerSample sample = new JavaServerSample();
try {
sample.start();
}
catch(IOException e) {
System.out.println("failed to start listening " + e.toString());
System.exit(1);
}
while(true) {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
break;
}
}
}
}
1 Like
Sorry for my abscess, I took a break. However, I’m not sure how to integrate the code before into the new code… The code before worked but exceptions were being thrown; but the new code nothing is getting transmitted and I’m not sure what to change in the new code to get it to transmit as before. Any ideas on how to change the new code to transmit data like before?