#http #post #arduino-uno
#http #Публикация #arduino-uno
Вопрос:
Я пытаюсь отправить большой файл на сервер, используя HTTP POST. Я могу отправлять файлы размером 4 КБ или меньше, но когда я пытаюсь отправить файл размером 1,5 МБ, кажется, что время ожидания истекло. Сервер отключается без отправки данных
Кто-нибудь знает, как это исправить?
Код: void readdata() {
//Variables for WiFi Shield
char ssid[] = "Example"; //your network SSID (name)
char pass[] = "Example1";
char server[] = "http://example.com";
while (status != WL_CONNECTED) {
Serial.print(F("Attempting to connect to SSID: "));
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
// wait 1 second for connection:
delay(1000);
}
Serial.println(F("Connected to wifi"));
// #endif
// check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println(F("WiFi shield not present"));
// don't continue:
while (true);
}
logfile=SD.open("LOG0038.CSV");
filesize=logfile.size();
logfile.close();
int fileLength = 0;
fileLength = 137 filesize 40;
Serial.println(filesize);
Serial.println(F("nStarting connection to server..."));
Serial.println(server);
// if you get a connection, report back via serial:
if (client.connect(server, 80)) {
Serial.println(F("connected to server"));
// Make a HTTP request:
client.setTimeout(Time);
client.print(F("POST /uploadf HTTP/1.1rn"));
client.print(F("Host: example.comrn"));
client.print(F("User-Agent: Frank/1.0rn"));
client.print(F("Accept-Encoding: gzip, deflatern"));
client.print(F("Accept: */*rn"));
client.print(F("Connection: keep-alivern"));
client.print(F("Content-Length: "));
client.print(fileLength);
client.print(F("rn"));
client.print(F("Content-Type: multipart/form-data; boundary=710ff0c6cf2d4c73b12db64cab12e58crn"));
client.print(F("rn"));
client.print(F("--710ff0c6cf2d4c73b12db64cab12e58crnContent-Disposition: form-data; name="file"; filename=""));
client.print("1000LOG0032.CSV");
client.print(F("""));
client.print(F("rn"));
client.print(F("Content-Type: text/plainrnrn"));
logfile=SD.open("LOG0038.CSV");
while(logfile.available()){
while(logfile.position() < logfile.size()){
String dataBuff = logfile.readStringUntil('n');
client.print(dataBuff);
// Serial.println(dataBuff);
client.print("n");
}
}
client.print(F("rn--710ff0c6cf2d4c73b12db64cab12e58c--rn"));
//client.flush();
}
while(client.connected()){
while (client.available()amp;amp; status==WL_CONNECTED) {
char c = client.read();
Serial.write(c);
}
}
// if the server's disconnected, stop the client:
if (!client.connected()) {
Serial.print(F("rn"));
Serial.println(F("disconnecting from server."));
// client.flush();
client.stop();
}
logfile.close();
while (true);
}
Комментарии:
1. Сервер закрывает соединение? Вы проверяли, есть ли ограничение на размер HTTP post на вашем сервере
2. Я проверил сервер, и у него нет ограничений на размер HTTP POST — похоже, что arduino будет отправлять только 20 КБ данных за раз
Ответ №1:
Возможно, это не настоящий ответ, но, к сожалению, у меня нет необходимой репутации, чтобы написать это в качестве комментария.
Я ничего не знаю об arduino, но всякий раз, когда вы работаете с POST, должна быть возможность ограничить max_post_size. В базовой настройке LAMP это обычно находится в .httaccess.
Я надеюсь, что это поможет вам в устранении неполадок.
Ответ №2:
Можно отправить запрос POST с полями данных, дополненными двоичными данными, как показано в приведенном ниже коде. Представленный код был создан для отправки запроса POST в репозиторий Dataverse (dataverse.org ), однако, может быть легко адаптирован к любому другому запросу POST. И последнее замечание: приведенный ниже код оптимизирован для микропроцессоров Xtensa LX6 / 7 от Tensilica по сравнению с ESP32.
Полный код можно найти здесь:
// *********************************************************
// Upload Dataset to Harvard's Dataverse
// *********************************************************
void UploadToDataverse() {
//Check WiFi connection status
if(WiFi.status() != WL_CONNECTED){
mserial.printStrln("WiFi Disconnected");
if (connect2WIFInetowrk()){
UploadToDataverse();
}
}
// Start sending dataset file
File datasetFile = FFat.open("/" EXPERIMENTAL_DATA_FILENAME, FILE_READ);
if (!datasetFile){
mserial.printStrln("Dataset file not found");
return;
}
String boundary = "7MA4YWxkTrZu0gW";
String contentType = "text/csv";
// DATASET_REPOSITORY_URL = "/api/files/:persistentId/replace?persistentId=" PERSISTENT_ID;
DATASET_REPOSITORY_URL = "/api/datasets/:persistentId/add?persistentId=" PERSISTENT_ID;
String datasetFileName = datasetFile.name();
String datasetFileSize = String(datasetFile.size());
mserial.printStrln("Dataset File Details:");
mserial.printStrln("Filename:" datasetFileName);
mserial.printStrln("size (bytes): " datasetFileSize);
mserial.printStrln("");
WiFiClientSecure client;
int str_len = SERVER_URL.length() 1; // Length (with one extra character for the null terminator)
char SERVER_URL_char [str_len]; // Prepare the character array (the buffer)
SERVER_URL.toCharArray(SERVER_URL_char, str_len); // Copy it over
client.stop();
client.setCACert(HARVARD_ROOT_CA_RSA_SHA1);
if (!client.connect(SERVER_URL_char, SERVER_PORT)) {
mserial.printStrln("Cloud server URL connection FAILED!");
mserial.printStrln(SERVER_URL_char);
int server_status = client.connected();
mserial.printStrln("Server status code: " String(server_status));
return;
}
mserial.printStrln("Connected to the dataverse of Harvard University");
mserial.printStrln("");
// We now create a URI for the request
mserial.printStr("Requesting URL: ");
mserial.printStrln(DATASET_REPOSITORY_URL);
// Make a HTTP request and add HTTP headers
// post header
String postHeader = "POST " DATASET_REPOSITORY_URL " HTTP/1.1rn";
postHeader = "Host: " SERVER_URL ":" String(SERVER_PORT) "rn";
postHeader = "X-Dataverse-key: " API_TOKEN "rn";
postHeader = "Content-Type: multipart/form-data; boundary=" boundary "rn";
postHeader = "Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8rn";
postHeader = "Accept-Encoding: gzip,deflatern";
postHeader = "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7rn";
postHeader = "User-Agent: AeonLabs LDAD Smart DAQ devicern";
postHeader = "Keep-Alive: 300rn";
postHeader = "Connection: keep-alivern";
postHeader = "Accept-Language: en-usrn";
// jsonData header
String jsonData = "{"description":"LIVE Experimental data upload from LDAD Smart 12bit DAQ ","categories":["Data"], "restrict":"false", "tabIngest":"false"}";
String jsonDataHeader = "--" boundary "rn";
jsonDataHeader = "Content-Disposition: form-data; name="jsonData"rnrn";
jsonDataHeader = jsonData "rn";
// dataset header
String datasetHead = "--" boundary "rn";
datasetHead = "Content-Disposition: form-data; name="file"; filename="" datasetFileName ""rn";
datasetHead = "Content-Type: " contentType "rnrn";
// request tail
String tail = "rn--" boundary "--rnrn";
// content length
int contentLength = jsonDataHeader.length() datasetHead.length() datasetFile.size() tail.length();
postHeader = "Content-Length: " String(contentLength, DEC) "nn";
// send post header
int postHeader_len=postHeader.length() 1;
char charBuf0[postHeader_len];
postHeader.toCharArray(charBuf0, postHeader_len);
client.print(charBuf0);
mserial.printStr(charBuf0);
// send key header
char charBufKey[jsonDataHeader.length() 1];
jsonDataHeader.toCharArray(charBufKey, jsonDataHeader.length() 1);
client.print(charBufKey);
mserial.printStr(charBufKey);
// send request buffer
char charBuf1[datasetHead.length() 1];
datasetHead.toCharArray(charBuf1, datasetHead.length() 1);
client.print(charBuf1);
mserial.printStr(charBuf1);
// create buffer
const int bufSize = 2048;
byte clientBuf[bufSize];
int clientCount = 0;
while (datasetFile.available()) {
clientBuf[clientCount] = datasetFile.read();
clientCount ;
if (clientCount > (bufSize - 1)) {
client.write((const uint8_t *)clientBuf, bufSize);
clientCount = 0;
}
}
datasetFile.close();
if (clientCount > 0) {
client.write((const uint8_t *)clientBuf, clientCount);
mserial.printStrln("[binary data]");
}
// send tail
char charBuf3[tail.length() 1];
tail.toCharArray(charBuf3, tail.length() 1);
client.print(charBuf3);
mserial.printStr(charBuf3);
// Read all the lines of the reply from server and print them to mserial
mserial.printStrln("");
mserial.printStrln("Response Headers:");
String responseHeaders = "";
while (client.connected()) {
// mserial.printStrln("while client connected");
responseHeaders = client.readStringUntil('n');
mserial.printStrln(responseHeaders);
if (responseHeaders == "r") {
mserial.printStrln("====== end of headers ======");
break;
}
}
String responseContent = client.readStringUntil('n');
mserial.printStrln("Harvard University's Dataverse reply was:");
mserial.printStrln("==========");
mserial.printStrln(responseContent);
mserial.printStrln("==========");
mserial.printStrln("closing connection");
client.stop();
}