【328P+W5100】在web中读取SD卡的文件-Arduino中文社区 - Powered by Discuz! Archiver

某1o 发表于 2015-11-14 22:09

【328P+W5100】在web中读取SD卡的文件

本帖最后由 某1o 于 2015-11-14 22:16 编辑

磨磨唧唧写了一个礼拜,弄出来这个了,总之SD.h这个库是各种玄学。直接上代码!代码有点长 大家可以去github下载项目文件https://github.com/mo10/SDwebserver

关于请求地址 表单 路径 后缀名截取方法 可以参考http://www.arduino.cn/thread-18012-1-1.html

注意!访问不要太频繁,在上一个文件未完全关闭的情况下打开下一个文件可能会抽风!代码难免不出错,大家不要喷我~ Debug很累的
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};//mac地址
IPAddress ip(192, 168, 31, 177);//ip地址
EthernetServer server(80);//访问端口
String fakename = "Nginx/1.8.0 (ATmega328p/Ubuntu 12.04 LTS)"; //装逼参数(伪装服务器)
String res = "", path = "";
EthernetClient client;
void setup() {
Serial.begin(9600);
while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
}
//启动sd
Serial.print("init sd:");
if (!SD.begin(4)) {
    Serial.println("failed");
    return;
}
Serial.println("done");
//启动eth
Ethernet.begin(mac, ip);
server.begin();
Serial.print("ip:");
Serial.println(Ethernet.localIP());

}


void loop() {
client = server.available();
if (client) {
    Serial.println("new client");
   
    delay(200);
    res = ""; path = ""; /*httpget = "", */
    int resend = 1;
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
      char c = client.read();
      //Serial.write(c);
      //只读取一行
      if (c != '\n' && resend) {
          res += c;
      } else {
          resend = 0;
      }

      if (c == '\n' && currentLineIsBlank) {
          //判断GET头完整性
          if ((res.indexOf("GET ") != -1) && (res.indexOf(" HTTP") != -1)) {
            //判断是否存在get参数
            if (res.indexOf('?') != -1) {
            //httpget = res.substring(res.indexOf('?') + 1, res.indexOf(" HTTP"));
            path = res.substring(res.indexOf("GET ") + 4, res.indexOf('?'));
            } else {
            path = res.substring(res.indexOf("GET ") + 4, res.indexOf(" HTTP"));
            }
            Serial.println(res);
            //Serial.println("GET:" + httpget);
            Serial.println("path:" + path);
            //delay(100);
            File s = SD.open(path);
            if (s) {
            webprintDirectory(s);
            } else {
            client.println(s);
            s.rewindDirectory();
            s.close();
            }
            //client.println("<p>" + fakename + "</p></body></html>");
            break;
          }
      }
      if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
      }
      else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
      }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disconnected");

}
}

void webprintDirectory(File dir) {
//判断是否为文件
if (!dir.isDirectory()) {

    if (path.indexOf('.') != -1) {
      //获取后缀名
      http_header("200 OK", path.substring(path.indexOf('.') + 1));
    } else {
      http_header("200 OK", "txt");//文件没有后缀名 默认显示文本格式
    }
    //读文件
    while (dir.available()) {
      char sc = dir.read();
      client.print(sc);
    }
    dir.close();
    dir.rewindDirectory();
    return;//退出
}
//判断不是文件
http_header("200 OK", "htm");
client.print("<!DOCTYPE HTML><html><body><h1>200 Success</h1><br />;PATH:" + path + "<hr />");
dir.rewindDirectory();//索引回到第一个位置
while (true) {
    File entry =dir.openNextFile();
    if (!entry) {
      //没有下一个索引了
      client.print("<br />No more files");
      dir.rewindDirectory();
      break;
    }
    if (path == "/") {
      client.print("<br /><a href=\"" + path);
    } else {
      client.print("<br /><a href=\"" + path + "/");
    }
    client.print(entry.name());
    client.print("\"target=\"_self\">");
    client.print(entry.name());
    client.print("</a>");
    if (!entry.isDirectory()) {
      // files have sizes, directories do not
      client.print("");
      client.println(entry.size(), DEC);
    }

    entry.close();
}
client.println("<p>" + fakename + "</p></body></html>");
dir.close();
delay(200);
}

void http_header(String statuscode, String filetype) {
filetype.toLowerCase();//把后缀名变小写
client.println("HTTP/1.1 " + statuscode);
client.print("Content-Type: ");
//判断文件mime类型
if (filetype == "htm" || filetype == "html") {
    client.println("text/html");
}
if (filetype == "png" || filetype == "jpg" || filetype == "bmp" || filetype == "gif") {
    client.println("image/" + filetype);
} else {
    client.println("text/plain");
}
client.println("Connection: close");
client.println();
}

运行

出现文件列表

打开个图片看看

加载速度有些坑爹了27KB文件要加载9秒多

做个死 加载个大图片看看


3MB用了17分钟,还是不要加载太大的图,慢死~~


打开文本文件








seesea 发表于 2015-11-14 22:46

膜拜一下高级东东

某1o 发表于 2015-11-15 00:27

seesea 发表于 2015-11-14 22:46
膜拜一下高级东东

看海大大老是调侃我:shutup: 给个精好不好啊~~?么么么:kiss:

卓泰科技 发表于 2015-11-15 20:32

某十大神威武

seesea 发表于 2015-11-15 21:52

某1o 发表于 2015-11-15 00:27
看海大大老是调侃我 给个精好不好啊~~?么么么

某10大威武!

某1o 发表于 2015-11-17 07:19

seesea 发表于 2015-11-15 21:52
某10大威武!

爱卓泰 爱生活!!:Q

seesea 发表于 2015-11-17 22:06

某1o 发表于 2015-11-17 07:19
爱卓泰 爱生活!!

哈哈,好基友,一辈子

炫Q 发表于 2015-11-25 13:50

好基友,一被子

Or2 发表于 2016-2-13 12:09

seesea 发表于 2015-11-17 22:06
哈哈,好基友,一辈子

都在啊

seesea 发表于 2016-2-14 21:21

Or2 发表于 2016-2-13 12:09
都在啊

昨天不在 :D
页: [1] 2
查看完整版本: 【328P+W5100】在web中读取SD卡的文件