TCPClient to connect to webserver

I’m new here and i’m writing a firmware to store some info to my webserver/mysql
I’ve written simple php code and i’ve tested successful on my local server with a browser with a link like this:
http://ubuntu.ashnet/spark/add_data.php?dt=1421681848&id_spark=1234568ff&id_user=788

On Spark Core i’ve this code:

Serial.println("Connecting to web server: ");
if (client.connect(server, port)) {
    Serial.println("Connected...");
    client.println("GET /spark/add_data.php?dt=1421688456&id_spark=1234568ff&id_user=788 HTTP/1.1");
    client.print(" Host: ubuntu.ashnet");
    client.println("User-Agent: Spark/1.0");
    client.println("Content-Type: text/html;");
    client.println("Connection: close");
    client.println();
    client.println();
    Serial.println("Send data to server - valore: " + io );        
Serial.println("Closing Connection...");
delay(500);
while (client.available()) client.read();
client.flush();
delay(400);
    client.stop();
} 
else {
Serial.println("Connection failed");
Serial.println("Disconnecting.");
client.stop();
}

And looking apache access log file i see this event:
192.168.1.14 - - [19/Jan/2015:19:44:01 +0100] “GET /spark/add_data.php?dt=1421688456&id_spark=1234568ff&id_user=788 HTTP/1.1” 400 0

Something wrong !! where ??

Thanks for help
Blondie

Try removing the leading space before Host from client.print(" Host: ubuntu.ashnet");
Might work, might not.
Tim.

Try setting a content-length header: client.println("Content-Length: 0"). My HTTP is rusty, so you may have to change the length value to whatever the length of the querystring is. A quick function I wrote for this in another script uses 0 (zero) and the NodeJS web server seems okay with that, but Apache may be pickier than a 10-line NodeJS script!

I've solved adding this line, thanks very much !

Out of interest, did you also remove that leading space?
Reason for asking is that I tried a similar header (send from a PC rather than a Core) to an Apache web server and I got 400 until I removed that space.
Tim.

i’ve done some test and the behavior is very strange:
first i’ve a working firmware with that space
i’ve deleted it, recompile and flash my core, i see it working fine but more slow
I’ve add again the space, recompile and flash my core, i got err 400 :frowning:
I turn off/on my core with same firmware and now working fine & fast !
Is it possible there’s some buffer issue?
Mauro

try this code instead, add these 2 functions after the main loop() function. To make sure we are going super fast in the out() function we are using client.write instead of client.print and the in() function makes sure everything gets flushed nicely and has some timeouts so we dont hang the core if the server doesn’t reply.

/*----------------------------------------------------------------------*/
/* out - outputs supplied string to TCPclient */
void out(const char *s) {

client.write( (const uint8_t*)s, strlen(s) );

if (DEBUG)Serial.write( (const uint8_t*)s, strlen(s) );

}
/*----------------------------------------------------------------------*/

/*----------------------------------------------------------------------*/
/* in - reads from TCPclient, with timeout */
void in(char *ptr, uint8_t timeout) {
        int pos = 0;
        unsigned long lastTime = millis();
        
        while( client.available()==0 && millis()-lastTime<timeout) { //timeout
        }  //do nothing
        lastTime = millis();
        unsigned long lastdata = millis();
        
        while ( client.available() || (millis()-lastdata < 500)) {  //500 millisecond timeout
            if (client.available()) {
                char c = client.read();
                if(DEBUG)Serial.print(c);
                lastdata = millis();
                ptr[pos] = c;
                pos++;
            }
            if (pos >= 512 - 1)
            break;
        }
        ptr[pos] = '\0'; //end the char array
        while (client.available()) client.read(); // makeshift client.flush()
        client.flush();  //for safety
        delay(400);
        client.stop();
        if(DEBUG){
            Serial.println();
            Serial.print("Done, Total bytes: ");
            Serial.println(pos);
        }
        
}
/*-----------------------------------------------------------------------*/

and here is your code from above modified to use the 2 new functions

Serial.println("Connecting to web server: ");
if (client.connect(server, port)) {
    Serial.println("Connected...");
    out("GET /spark/add_data.php?dt=1421688456&id_spark=1234568ff&id_user=788 HTTP/1.1\r\n");
    out("Host: ubuntu.ashnet\r\n");
    out("User-Agent: Spark/1.0\r\n");
    out("Content-Type: text/html\r\n");
    out("Connection: close\r\n\r\n");
    Serial.println("Send data to server - valore: " + io );        
Serial.println("Closing Connection...");
in(reply, 3000);
} 
else {
Serial.println("Connection failed");
Serial.println("Disconnecting.");
client.stop();
}

and add this before setup()

boolean DEBUG = false; // enable or disable Debug output
char reply[512]; // the server reply is saved in this.. you could parse it for data if needed.
1 Like

Thanks !

because i’ve splitted code, can i use something like this?

    out("GET /spark/add_data.php?");
    out("dt=" + String(dt) );
    out("&");
    out("id_spark=" + myID );
    out("&");
    out("id_user=" + String(id_user) );

you can use sprintf, here is an example of how i use it for one of my projects using the out function.

char line[255]; 
sprintf(line, "Host: %s:%d\r\n", hostname, port);
out(line);

i think for your function it could be

char line[255];
sprintf(line, "GET /spark/add_data.php?dt=%s&id_spark=%s&id_user=%s", dt, myID, id_user);
out(line);

but you may need to something like this to convert the string to a char array… i haven’t tested this out… dtAsCharArray would be the one you use in the sprintf

dt.toCharArray(dtAsCharArray, dt.length());
2 Likes