ESP8266, Arduino IDE and client.write() problem

Hi forum,

I'm new to Arduino, and I'm using the IDE with the ESP8266.

I'm trying to let the ESP serve a PNG file for a browser. For this I have created the entire HTTP response including the binary data for the PNG in a char array. I quickly discovered that I cannot use client.print() since this will stop sending data when it encounters a null character (like a null terminated string) and the PNG data does contain nulls. I converted the char array to string when I used client.print().

Then I found client.write() which should take a buf and len: client.write(buf, len). But this won't compile.

What am I doing wrong?

Code example:

char testdata[] = {'T','e','s','t'};

client.write(testdata, 4)

Compiler error:

In file included from C:\Users\Martin\AppData\Roaming\Arduino15\packages\esp8266\hardware\esp8266\1.6.5-947-g39819f0\libraries\ESP8266WiFi\src/ESP8266WiFi.h:32:0,
                 from WiFi_print_http.ino:1:
C:\Users\Martin\AppData\Roaming\Arduino15\packages\esp8266\hardware\esp8266\1.6.5-947-g39819f0\libraries\ESP8266WiFi\src/WiFiClient.h: In instantiation of 'size_t WiFiClient::write(T&, size_t) [with T = char [4]; size_t = unsigned int]':
WiFi_print_http.ino:140:23:   required from here
C:\Users\Martin\AppData\Roaming\Arduino15\packages\esp8266\hardware\esp8266\1.6.5-947-g39819f0\libraries\ESP8266WiFi\src/WiFiClient.h:113:36: error: request for member 'available' in 'source', which is of non-class type 'char [4]'
     size_t left = source.available();
                                    ^
C:\Users\Martin\AppData\Roaming\Arduino15\packages\esp8266\hardware\esp8266\1.6.5-947-g39819f0\libraries\ESP8266WiFi\src/WiFiClient.h:117:5: error: request for member 'read' in 'source', which is of non-class type 'char [4]'
     source.read(buffer.get(), will_send);
     ^
Error compiling.

What am I doing wrong?

Just about everything. You posted a snippet that is completely unrelated to the error messages.

Post the code that ACTUALLY generated the error messages, if you REALLY can't understand the blindingly obvious messages.

PaulS:
Just about everything. You posted a snippet that is completely unrelated to the error messages.

Post the code that ACTUALLY generated the error messages, if you REALLY can't understand the blindingly obvious messages.

I will overlook the harsh tone from you, as you might actually end up helping me with this. I'm new to Arduino, remember?

Complete code:

#include <ESP8266WiFi.h>
const char ssid[] = "test";
const char pass[] = "12345678";

char Response[] = {'t','e','s','t'};
String Request;

WiFiServer server(80);
void setup() 
{
  setupWiFi();
  server.begin();
}

void loop() 
{
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client)
    return;

  // Read the first line of the request
  Request = client.readStringUntil('\r');
  client.flush();

  // If client requests the PNG file
  if(Request.indexOf("GET /test.png") != -1)
  {
    client.write(Response);
  }
}

void setupWiFi()
{
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);
}

Actual error message for the above code:

In file included from C:\Users\Martin\AppData\Roaming\Arduino15\packages\esp8266\hardware\esp8266\1.6.5-947-g39819f0\libraries\ESP8266WiFi\src/ESP8266WiFi.h:32:0,
                 from client_write.ino:1:
C:\Users\Martin\AppData\Roaming\Arduino15\packages\esp8266\hardware\esp8266\1.6.5-947-g39819f0\libraries\ESP8266WiFi\src/WiFiClient.h: In instantiation of 'size_t WiFiClient::write(T&) [with T = char [4]; size_t = unsigned int]':
client_write.ino:30:26:   required from here
C:\Users\Martin\AppData\Roaming\Arduino15\packages\esp8266\hardware\esp8266\1.6.5-947-g39819f0\libraries\ESP8266WiFi\src/WiFiClient.h:73:28: error: request for member 'available' in 'src', which is of non-class type 'char [4]'
     while (src.available() > 1460){
                            ^
C:\Users\Martin\AppData\Roaming\Arduino15\packages\esp8266\hardware\esp8266\1.6.5-947-g39819f0\libraries\ESP8266WiFi\src/WiFiClient.h:74:7: error: request for member 'read' in 'src', which is of non-class type 'char [4]'
       src.read(obuf, 1460);
       ^
C:\Users\Martin\AppData\Roaming\Arduino15\packages\esp8266\hardware\esp8266\1.6.5-947-g39819f0\libraries\ESP8266WiFi\src/WiFiClient.h:82:38: error: request for member 'available' in 'src', which is of non-class type 'char [4]'
     uint16_t leftLen = src.available();
                                      ^
C:\Users\Martin\AppData\Roaming\Arduino15\packages\esp8266\hardware\esp8266\1.6.5-947-g39819f0\libraries\ESP8266WiFi\src/WiFiClient.h:83:5: error: request for member 'read' in 'src', which is of non-class type 'char [4]'
     src.read(obuf, leftLen);
     ^
Error compiling.

The error messages are not blindingly obvious to me. Yeah, I can see there is mention of a "type", but it took some looking around before I figured that I might have looked at documentation for the wrong class. So the WiFiClient does not support (buf, len) arguments, but only a single char or string as types?

So how can I send my PNG data when I can't put the data in a string?

I have looked at the code in WiFiClient.h and it is not obvious to me how it works.

There appear to be a number of ESP8266WiFi libraries available. Which one are you using?

Well, I followed a guide on how to get started with Arduino IDE and ESP8266. I have this link inserted into Preferences->Additional Boards Manager URLs:

http://arduino.esp8266.com/versions/1.6.5-947-g39819f0/package_esp8266com_index.json

I also started out with a simple example sketch from here:

https://learn.sparkfun.com/tutorials/esp8266-thing-hookup-guide/example-sketch-ap-web-server

But today I found out about the (called library?) ESP8266WebServer where I don't have to manually enter the HTTP headers. But even the server.send() function used there, is terminating when it encounters a 0x00 in the data. I also found a lot of threads about the ESP8266WebServer on esp8266.com so maybe that's a more correct place to ask my questions since I think I'm going to use the ESP8266WebServer functions from now on.

I's all new to me, and I'm learning every time I fire up the ESP.

Ok, so I was just about to go to bed when I found this example:

I just need to make the char array a const, and everything works now :slight_smile:

Hi, I am having the same problem, but with a character buffer[64], so I cannot declare a const.
I will get no compilation error when I declare "const char buffer[64] = "123".

wifi_FTP_client.ino:

10 #include <ESP8266WiFi.h>

WiFiClient client;

char clientBuf[64];

281 dclient.write(clientBuf, sizeof(clientBuf));

ESP8266WiFi.h:

32 #include "WiFiClient.h"

gives compilation error on Arduino 1.6.5 with ESP8266 package

In file included from /Volumes/DAT/Users/rudi/Documents/Arduino/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h:32:0,
                 from /Volumes/DAT/Users/rudi/Documents/Arduino/wifi_FTP_client/wifi_FTP_client.ino:10:
/Volumes/DAT/Users/rudi/Documents/Arduino/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.h: In instantiation of 'size_t WiFiClient::write(T&, size_t) [with T = char [64]; size_t = unsigned int]':
/Volumes/DAT/Users/rudi/Documents/Arduino/wifi_FTP_client/wifi_FTP_client.ino:281:49:   required from here
/Volumes/DAT/Users/rudi/Documents/Arduino/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.h:119:36: error: request for member 'available' in 'source', which is of non-class type 'char [64]'
     size_t left = source.available();
                                    ^
/Volumes/DAT/Users/rudi/Documents/Arduino/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.h:123:5: error: request for member 'read' in 'source', which is of non-class type 'char [64]'
     source.read(buffer.get(), will_send);
     ^

The header file WiFiClient.h, function "write"

template <typename T>
inline size_t WiFiClient::write(T& source, size_t unitSize) {
  std::unique_ptr<uint8_t[]> buffer(new uint8_t[unitSize]);
  size_t size_sent = 0;
  while(true) {
119    size_t left = source.available();
    if (!left)
      break;
    size_t will_send = (left < unitSize) ? left : unitSize;
123    source.read(buffer.get(), will_send);
    size_t cb = write(buffer.get(), will_send);
    size_sent += cb;
    if (cb != will_send) {
      break;
    }
  }
  return size_sent;
}

Unfortunately I cannot find the reason for that error, and no example giving a hint.

May be an experienced programmer can help please. :slight_smile:
Regards, Rudolf

I'm sure that the fine folks at http://snippets-r-us.com can help you with your snippets.

For the not-really-an-Arduino-ESPthing, templates are involved, and the write() function expects the first argument to be an instance of a class that has a method called available() and one called read().

Those are methods that the Stream class has. So, it appears that you are supposed to call client.write() with a Stream object, NOT a character array.

Hello PaulS,

Thank you very much for your help.

Regarding the snippets I have my own homepage, please see:
http://www.rudiswiki.de/wiki9/WiFiTelnetServer

When I read, that client.write() needs a stream object, how come, that a declaration
const char buffer[64] = "123" works without compilation error?

Do you please have an example how to code it, that when I read from the Flash File System
a file, to send the data (ASCII) via FTP to an FTP server with that command:
dclient.write(clientBuf, sizeof(clientBuf));

I forgot to mention the original program:
http://playground.arduino.cc/Code/FTP

Regards, Rudolf

oid loop() {
{
Serial.print("connecting to ");
Serial.println(host);

// Use WiFiClient class to create TCP connections
WiFiClient client;
const int httpPort = 80;
if (!client.connect(host, httpPort)) {
Serial.println("connection failed");
return;
}
byte mec[2];
mec[0]=1;
mec[1]=2;
client.write(mec,sizeof(mec));

if (client.available()) {
char c = client.read();
Serial.print(c);
}

if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
for(;:wink:
;
}
}
}

getting error as

Arduino: 1.6.6 (Windows 7), Board: "Generic ESP8266 Module, Serial, 80 MHz, 40MHz, DIO, 115200, 512K (64K SPIFFS), ck"

In file included from C:\Users\Manjunatha\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/ESP8266WiFi.h:32:0,

from C:\Users\Manjunatha\Desktop\WiFiClient_pra_jan\WiFiClient_pra_jan.ino:9:

C:\Users\Manjunatha\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/WiFiClient.h: In instantiation of 'size_t WiFiClient::write(T&, size_t) [with T = unsigned char [2]; size_t = unsigned int]':

C:\Users\Manjunatha\Desktop\WiFiClient_pra_jan\WiFiClient_pra_jan.ino:58:31: required from here

C:\Users\Manjunatha\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/WiFiClient.h:119:36: error: request for member 'available' in 'source', which is of non-class type 'unsigned char [2]'

size_t left = source.available();

^

C:\Users\Manjunatha\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266WiFi\src/WiFiClient.h:123:5: error: request for member 'read' in 'source', which is of non-class type 'unsigned char [2]'

source.read(buffer.get(), will_send);

^

exit status 1
Error compiling.

This report would have more information with
"Show verbose output during compilation"
enabled in File > Preferences.

WiFiClient_pra_jan.ino (1.42 KB)

@sgravi2: Did you read reply #7? Do it now.

i ma getting error in client.write(buf ,len)..please help me

byte m[2];
m[0]=1;
m[1]=2
client.write(m, 3);

getting error as
request for member 'read' in 'source', which is of non-class type 'unsigned char [2]'

source.read(buffer.get(), will_send);

I had the same issue. Use write_P :slight_smile:

i have an issue esp826 generic module
if i use client.write(&a[0],10); to sent 10 byte array elements, it will send only one time to the server but not continuously , what should i do so that i can send continuously

please help me for this issue ,Thanks

rudolf48:
Hi, I am having the same problem, but with a character buffer[64], so I cannot declare a const.
I will get no compilation error when I declare "const char buffer[64] = "123".

wifi_FTP_client.ino:

10 #include <ESP8266WiFi.h>

WiFiClient client;

char clientBuf[64];

281 dclient.write(clientBuf, sizeof(clientBuf));

ESP8266WiFi.h:

32 #include "WiFiClient.h"



gives compilation error on Arduino 1.6.5 with ESP8266 package


In file included from /Volumes/DAT/Users/rudi/Documents/Arduino/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h:32:0,
                from /Volumes/DAT/Users/rudi/Documents/Arduino/wifi_FTP_client/wifi_FTP_client.ino:10:
/Volumes/DAT/Users/rudi/Documents/Arduino/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.h: In instantiation of 'size_t WiFiClient::write(T&, size_t) [with T = char [64]; size_t = unsigned int]':
/Volumes/DAT/Users/rudi/Documents/Arduino/wifi_FTP_client/wifi_FTP_client.ino:281:49:  required from here
/Volumes/DAT/Users/rudi/Documents/Arduino/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.h:119:36: error: request for member 'available' in 'source', which is of non-class type 'char [64]'
    size_t left = source.available();
                                    ^
/Volumes/DAT/Users/rudi/Documents/Arduino/hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/WiFiClient.h:123:5: error: request for member 'read' in 'source', which is of non-class type 'char [64]'
    source.read(buffer.get(), will_send);
    ^



The header file WiFiClient.h, function "write"


template
inline size_t WiFiClient::write(T& source, size_t unitSize) {
  std::unique_ptr<uint8_t[]> buffer(new uint8_t[unitSize]);
  size_t size_sent = 0;
  while(true) {
119    size_t left = source.available();
    if (!left)
      break;
    size_t will_send = (left < unitSize) ? left : unitSize;
123    source.read(buffer.get(), will_send);
    size_t cb = write(buffer.get(), will_send);
    size_sent += cb;
    if (cb != will_send) {
      break;
    }
  }
  return size_sent;
}



Unfortunately I cannot find the reason for that error, and no example giving a hint.

May be an experienced programmer can help please. :-)
Regards, Rudolf

Unfortunately there is a bad function overload n the library,
but you can just typecast the clientbuf to overcome this problem.....

client.write((const uint8_t*)clientBuf, sizeof(clientBuf));

Great, the cast solves the issue! Thank you a lot!!!

pgScorpio:
Unfortunately there is a bad function overload n the library,
but you can just typecast the clientbuf to overcome this problem.....

client.write((const uint8_t*)clientBuf, sizeof(clientBuf));

Thanks @pgScorpio

The cast works. Which I chose to use instead of changing the library file.

@pgScorpio you are a hero! That's one nasty bug in the libraries. Thank you for providing this working solution. Hats off!

(Unlike some other ivory tower posters that provide snarky remarks, but no solutions.)

pgScorpio, this is my first post in the forum, but I felt in my heart that I should THANK YOU!!! I was already brainf*cked with this problem. It worked great!