Here I am trying to let the two photons communicate with each other with one being server and the other one as a client. But I am really confused by the fact that the client just connect to the server and send data three times and then disconnect.
Here are my code: two parts:server and client
tcp-client.ino
SYSTEM_MODE(MANUAL);
TCPClient client;
byte server[] = { 192, 168, 1, 133 }; // to the queen(one as a server photon) wlan IP
char* c = "1";
void setup()
{
pinMode(D7,OUTPUT);
// Make sure your Serial Terminal app is closed before powering your device
Serial.begin(9600);
WiFi.connect();
// Now open your Serial Terminal, and hit any key to continue!
while(!Serial.available()) Particle.process();
//connect to local wifi and show the status
Serial.println("connecting to wifi");
//while(!WiFi.ready());
Serial.println(WiFi.localIP());
Serial.println(WiFi.subnetMask());
Serial.println(WiFi.gatewayIP());
Serial.println(WiFi.SSID());
Serial.println("connecting to server");
if (client.connect(server, 80))
{
Serial.println("server connected");
/*
client.println("GET /search?q=unicorn HTTP/1.0");
client.println("Host: www.google.com");
client.println("Content-Length: 0");
client.println();
*/
}
else
{
Serial.println("connection failed");
}
}
void loop()
{
Particle.process();
digitalWrite(D7,HIGH);
client.write(c);
/*
if(client.available() > 0){
Serial.println("write successfully");
Serial.println(client.read());
client.flush();
}
*/
/*
if (!client.connected())
{
Serial.println();
Serial.println();
Serial.println("reconnecting.");
//client.stop();
//for(;;);
if(client.connect(server,80)){
Serial.println("connected");
}
else
{
Serial.println("connection failed");
}
}*/
delay(100);
digitalWrite(D7,LOW);
delay(100);
}
part 2 ============================================
SYSTEM_MODE(MANUAL);
TCPServer server = TCPServer(80);
//TCPClient client;
void setup()
{
WiFi.connect();
pinMode(D7,OUTPUT);
// 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.proceshttps://build.particle.io/build/562c90a9bbdd36b4af0023fc#flashs();
Serial.println(WiFi.localIP());
Serial.println(WiFi.subnetMask());
Serial.println(WiFi.gatewayIP());
Serial.println(WiFi.SSID());
// start listening for clients
server.begin();
}
void loop()
{
// check for a new client to our server
TCPClient client = server.available();
if (client.connected())
{
// we got a new client
// find where the client's remote address
IPAddress clientIP = client.remoteIP();
// print the address to Serial
Serial.println(clientIP);
}
Particle.process();
digitalWrite(D7,HIGH);
Serial.println(WiFi.localIP());
Serial.println(WiFi.subnetMask());
Serial.println(WiFi.gatewayIP());
Serial.println(WiFi.SSID());
Serial.println(client.connected());
if (client.connected()) {
// echo all available bytes back to the client
while (client.available()) {
char c = client.read();
server.write(c);
Serial.print("message recieved:");
Serial.println(c);
}
} else {
// if no client is yet connected, check for a new connection
client = server.available();
}
delay(1000);
digitalWrite(D7,LOW);
delay(1000);
}
Could it be that you are running out of free sockets, since you don’t seem to free them after usage?
If the connection times out connected() will turn false, but the socket doesn’t get freed - I think.
SYSTEM_MODE(MANUAL);
TCPServer server = TCPServer(80);
//TCPClient client;
void setup()
{
WiFi.connect();
pinMode(D7,OUTPUT);
// 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.proceshttps://build.particle.io/build/562c90a9bbdd36b4af0023fc#flashs();
Serial.println(WiFi.localIP());
Serial.println(WiFi.subnetMask());
Serial.println(WiFi.gatewayIP());
Serial.println(WiFi.SSID());
// start listening for clients
server.begin();
}
void loop()
{
// check for a new client to our server
TCPClient client = server.available();
if (client.connected())
{
// we got a new client
// find where the client's remote address
IPAddress clientIP = client.remoteIP();
// print the address to Serial
Serial.println(clientIP);
}
Particle.process();
digitalWrite(D7,HIGH);
Serial.println(WiFi.localIP());
Serial.println(WiFi.subnetMask());
Serial.println(WiFi.gatewayIP());
Serial.println(WiFi.SSID());
Serial.println(client.connected());
if (client.connected()) {
// echo all available bytes back to the client
while (client.available()) {
char c = client.read();
server.write(c);
Serial.print("message recieved:");
Serial.println(c);
}
} else {
// if no client is yet connected, check for a new connection
client = server.available();
}
delay(1000);
digitalWrite(D7,LOW);
delay(1000);
}
Try client.stop(); and a short delay before reconnecting.
You can imagine a TCP client like a plugbar the has only a limited number of free sockets and when you plug in a device but never take the plug out even after switching the device of you’ll be running out of places to plug in new devices.
Here is the sample code in the particle reference, I don’t understand what the ‘for(;;)’ for.It seems like a endless for loop. Am I right?
and…
here is my latest result:
And I had my client code modified too, like this::
// EXAMPLE USAGE
SYSTEM_MODE(MANUAL);
TCPClient client;
byte server[] = { 192, 168, 1, 133 }; // to the queen(one as a server photon) wlan IP
char* c = "1";
void setup()
{
pinMode(D7,OUTPUT);
// Make sure your Serial Terminal app is closed before powering your device
Serial.begin(9600);
WiFi.connect();
// Now open your Serial Terminal, and hit any key to continue!
while(!Serial.available()) Particle.process();
//connect to local wifi and show the status
Serial.println("connecting to wifi");
//while(!WiFi.ready());
Serial.println(WiFi.localIP());
Serial.println(WiFi.subnetMask());
Serial.println(WiFi.gatewayIP());
Serial.println(WiFi.SSID());
Serial.println("connecting to server");
if (client.connect(server, 80))
{
Serial.println("server connected");
/*
client.println("GET /search?q=unicorn HTTP/1.0");
client.println("Host: www.google.com");
client.println("Content-Length: 0");
client.println();
*/
}
else
{
Serial.println("connection failed");
}
}
void loop()
{
Particle.process();
digitalWrite(D7,HIGH);
client.write(c);
if(client.available() > 0){
Serial.println("reading back");
Serial.println(client.read());
client.flush();
}
if (!client.connected())
{
Serial.println();
Serial.println();
Serial.println("reconnecting.");
client.stop();
for(;;);
if(client.connect(server,80)){
Serial.println("connected");
}
else
{
Serial.println("connection failed");
}
}
delay(500);
digitalWrite(D7,LOW);
delay(500);
}
The server does not stop since it needs to be on duty for whenever a client demands its services, but internally it makes use of a TCPClient which lifecycle it controls.
To know exactly what’s going on inside TCPServer you could look into the open source implementation.
And for your code change I suggested the client.stop() with a short delay but not the for(;;); since this just traps the code in an endless loop (not a very short delay ).
The examples just show one very simplistic use case (one time communication) but your use case (multiple communication turns) is different, so the code needs to be different.
Thank you, I really appreciate your help! And I modified the server.ino as well and I find out that it seems not probably to initiate TCPClient client every loop,like the code part haven’t been commented before.And here is my latest server code and it is working now. By the way, I will change the For(; to a shorter delay and check it if it work.
SYSTEM_MODE(MANUAL);
TCPServer server = TCPServer(80);
TCPClient client;
void setup()
{
WiFi.connect();
pinMode(D7,OUTPUT);
// 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.proceshttps://build.particle.io/build/562c90a9bbdd36b4af0023fc#flashs();
Serial.println(WiFi.localIP());
Serial.println(WiFi.subnetMask());
Serial.println(WiFi.gatewayIP());
Serial.println(WiFi.SSID());
// start listening for clients
server.begin();
}
void loop()
{
// check for a new client to our server
/*TCPClient client = server.available();
if (client.connected())
{
// we got a new client
// find where the client's remote address
IPAddress clientIP = client.remoteIP();
// print the address to Serial
Serial.println(clientIP);
}
*/
Particle.process();
digitalWrite(D7,HIGH);
Serial.println(WiFi.localIP());
Serial.println(WiFi.subnetMask());
Serial.println(WiFi.gatewayIP());
Serial.println(WiFi.SSID());
Serial.println(client.connected());
if (client.connected()) {
// echo all available bytes back to the client
while (client.available()) {
char c = client.read();
server.write(c);
Serial.print("message recieved:");
Serial.println(c);
}
} else {
// if no client is yet connected, check for a new connection
client = server.available();
}
delay(1000);
digitalWrite(D7,LOW);
delay(1000);
}
Just had another check and in fact client.connect() does implicitly perform a client.stop() so no need to do it there - sorry for the wrong track
Only if you’d happened to use a non-global client you should issue a client.stop() before your client object would go out of scope because the TCPClient destructor doesn’t do anything.
and it`s been running for over 8000 seconds now without any problems
MAYBE NOT , a can see client says it`s connected to the server , and the server is getting a incoming connection from the client , BUT the serial say the incoming ip is 0.0.0.0 .
@peter_a and @particle_adam: I cobbled together some simple photon tcp client and server code that appears to work well on 0.4.7, after reading through lots of posts by way smarter folks than I over the past months on this subject. It’s real simple but might be of use to you. It’s at https://github.com/bprobbins/photon-simple-tcpclientserver
Well, it may be just unnecessary to print out remote IP but I wanna figure it out how it works. And now I want to move a further step to connect two photon as clients. However, I don’t have any clue right now.
yeah, I think it’s what you mention that cause the disconnection in my project. If I create a client object locally, then I may need to destroy the object every loop, right?
By the way, how could I connect two photon as clients to one photon as a server. To be precise, how could the server tell the different ID between the two clients respectively and response to them seperately?
How does it know which client is connected ? , the remote ip address.
I know what you mean about the example , I had to play with it to work out what was happening, talk about cryptic.
After a while it stops telling me the remotes ip.
BUT it is still connecting and still getting data in and out , so the link is still working.
I will try counting the number the of times client.remoteip works before going to 0.0.0.0