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

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 24151|回复: 14

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

[复制链接]
发表于 2015-11-14 22:09 | 显示全部楼层 |阅读模式
本帖最后由 某1o 于 2015-11-14 22:16 编辑

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

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

注意!访问不要太频繁,在上一个文件未完全关闭的情况下打开下一个文件可能会抽风!代码难免不出错,大家不要喷我~ Debug很累的
[mw_shl_code=c,true]#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 />ATH:" + 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();
}[/mw_shl_code]

运行
QQ截图20151114215516.png
出现文件列表

打开个图片看看
QQ截图20151114215552.png
加载速度有些坑爹了27KB文件要加载9秒多

做个死 加载个大图片看看
QQ截图20151114220126.png

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


打开文本文件
QQ截图20151114220330.png







发表于 2015-11-14 22:46 | 显示全部楼层
膜拜一下高级东东
 楼主| 发表于 2015-11-15 00:27 | 显示全部楼层
seesea 发表于 2015-11-14 22:46
膜拜一下高级东东

看海大大老是调侃我 给个精好不好啊~~?么么么
发表于 2015-11-15 20:32 | 显示全部楼层
某十大神威武
发表于 2015-11-15 21:52 | 显示全部楼层
某1o 发表于 2015-11-15 00:27
看海大大老是调侃我 给个精好不好啊~~?么么么

某10大威武!
 楼主| 发表于 2015-11-17 07:19 | 显示全部楼层

爱卓泰 爱生活!!
发表于 2015-11-17 22:06 | 显示全部楼层
某1o 发表于 2015-11-17 07:19
爱卓泰 爱生活!!

哈哈,好基友,一辈子
发表于 2015-11-25 13:50 | 显示全部楼层
好基友,一被子
发表于 2016-2-13 12:09 | 显示全部楼层
seesea 发表于 2015-11-17 22:06
哈哈,好基友,一辈子

都在啊
发表于 2016-2-14 21:21 | 显示全部楼层

昨天不在
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-27 22:28 , Processed in 0.109499 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表