Добрый день. Идея следующая) контролер смотрит в инет и позволяет удалённо (через web интерфейс) включать компы. Как работает http протокол (его хедеры) я знаю. Вот код разбора запроса: Код (Text): void query_analysis(EthernetClient client){ String first_line = ""; String query = ""; String location = ""; int cookie_index = 0; while(true){ char r = client.read(); if(r != '\r' && client.available() > 0){ first_line += r; } else break; } if(first_line.indexOf("GET") == 0) http_query_type = "GET"; else if(first_line.indexOf("POST") == 0) http_query_type = "POST"; if(http_query_type == "GET" || http_query_type == "POST"){ location = first_line.substring(http_query_type.length() + 1, first_line.lastIndexOf(" ")); [SIZE=5] while(client.available()>0) query += String(char(client.read()));[/SIZE] Serial.print(query); cookie_index = query.indexOf("Cookie:"); } else{ //не поддерживаемый тип запроса } client.println("HTTP/1.1 200 OK"); client.println(); client.print(location); client.print("index of cookie: " + String(cookie_index)); client.print(query); first_line = ""; query = ""; location = ""; cookie_index = 0; client.stop(); } Проблема в строчке, к которой я пытался применить bb-код)) Если её заменить на: Код (Text): while(client.available()>0) Serial.print(String(char(client.read()))); То в сериал выводится весь запрос браузера (т.е. выходит что запросы полностью доходят до дуни), однако если оставить как есть и в сериал кинуть "query", то в ней не окажется доброй половины запроса! Причём, вся эта катавасия начинается со второго запроса (после включения), первый же и так и так приходит полностью.
Полагаю, что ваш оригинальный код значительно быстрее, чем побуквенный вывод в Serial (не нужно на каждой итерации взаимодействовать с медленным IO), поэтому в оригинальном коде вы успеваете вычитывать всё полностью из первой порции данных, serial.available() начинает говорить о пустом буфере, вы выходите из цикла и понеслось… Порций может быть много и их будет много. Вам нужно ориентироваться не на serial.available(), а на логический конец запроса: считывать Content-Length из заголовка и затем считывать именно такой объём payload'а в запросе.
Точно, всегда на этом available = 0 попадаюсь))) А про content-length я совсем забыл, спасибо. Только вот незадача, ни один браузер не передаёт этот параметр( Придётся читать/ждать байты пока не придёт конец запроса (пустая строка).
Как ни странно, но новый вариант выдаёт тот же результат Код (Text): while(true){ if(client.available()>0){ now_byte = char(client.read()); if(now_byte == '\r' && last_byte == '\n') break; query += now_byte; last_byte = now_byte; } else { Serial.println("delaing"); delay(30); } } Причём "delaing" ни разу не вывелся. Вот что осталось в сериал: Первый запрос: Host: --------------------- Connection: keep-alive Cache-Control: max-age=0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.56 Safari/537.17 Accept-Encoding: gzip,deflate,sdch Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4 Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.3 Второй запрос (кстати, этим запросом хром пытается загрузить favicon): Host: -------------------- Connection: keep-alive Accept: */* User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.17 (KHTML, like Gecko) Ch
Теория номер два. Вы имеете дело с фрагментацией памяти от использования класса String и аккурат на момент, когда «Ethernet больше ничего не получает» на самом деле МК падает в segfault в результате out of memory. Рекомендация: выделить заранее буфер побольше под получение запросов и использовать низкоуровневые функции типа `strcat` для его наполнения. То есть не использовать `String` вовсе, использовать `char*`.
Ух ты, не знал у стрингов всё так сложно)) Согласен с Unixon, так и сделал... Вот код, если кому интересно: Код (Text): while(q_param_host == "" && q_param_cookie == ""){ if(client.available() > 0){ tmp_char = client.read(); if(!key_is_set){ if(tmp_char != ':') key += tmp_char; else key_is_set = true; } else{ if(tmp_char != '\r') value += tmp_char; else{ client.read(); // Избавляемся от ненужного нам символа "\n" key_is_set = false; if(key == "Host") q_param_host = value; if(key == "Cookie") q_param_cookie = value; key = ""; value = ""; } } } else delay(30); } Time out потом приделаю, как и все обработчики ошибок)