ftp升级方案
一 单片机做 ftp_server, agile_ftp 基于RT-Thread,运行在嵌入式上的高并发高性能轻量级FTP服务器。ART-PI线下培训就演示过。
1 单片机有mcu_boot.bin,mcu_app.bin,且在app上实现了ftp server.
2 用rt-thread的打包工具QBootPackager_V1.02.exe将mcu_app.bin变成mcu_app.rbl.
3利用FileZilla工具连接到单片机ftp server,将本地要升级的rbl上传到单片机指定的文件系统目录下(上传即升级策略触发条件)
4将rbl文件解压拷贝到单片机指定的app分区并完成跳转。
二 :单片机做tfp_client: C语言实现的简易FTP客户端
1 //应用层下载文件的调用流程(仅供参考) 2 #include "socket.h" 3 void main() 4 { 5 int ret; 6 ftp_init(); 7 ret = ftp_login("192.168.0.1", 21, "admin", "admin"); 8 int size = ftp_filesize("/dir/filename.bin"); 9 char *buf = malloc(size); 10 ret = ftp_download("/dir/filename.bin", buf, size); 11 ftp_quit(); 12 free(buf); 13 }
1 /*socket.h*/ 2 #ifndef __SOCKET_H 3 #define __SOCKET_H 4 5 int socket_create(void); 6 void socket_delete(int sock); 7 int socket_connect(int sock, const char *addr, int port); 8 void socket_close(int sock); 9 int socket_send(int sock, void *data, int len); 10 int socket_recv(int sock, void *data, int len); 11 12 #endif
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include "socket.h" 5 #include "log.h" 6 #include "ftp.h" 7 8 static int m_socket_cmd; 9 static int m_socket_data; 10 static char m_send_buffer[1024]; 11 static char m_recv_buffer[1024]; 12 13 //命令端口,发送命令 14 static int ftp_send_command(char *cmd) 15 { 16 int ret; 17 LOG_INFO("send command: %s\r\n", cmd); 18 ret = socket_send(m_socket_cmd, cmd, (int)strlen(cmd)); 19 if(ret < 0) 20 { 21 LOG_INFO("failed to send command: %s",cmd); 22 return 0; 23 } 24 return 1; 25 } 26 27 //命令端口,接收应答 28 static int ftp_recv_respond(char *resp, int len) 29 { 30 int ret; 31 int off; 32 len -= 1; 33 for(off=0; off<len; off+=ret) 34 { 35 ret = socket_recv(m_socket_cmd, &resp[off], 1); 36 if(ret < 0) 37 { 38 LOG_INFO("recv respond error(ret=%d)!\r\n", ret); 39 return 0; 40 } 41 if(resp[off] == '\n') 42 { 43 break; 44 } 45 } 46 resp[off+1] = 0; 47 LOG_INFO("respond:%s", resp); 48 return atoi(resp); 49 } 50 51 //设置FTP服务器为被动模式,并解析数据端口 52 static int ftp_enter_pasv(char *ipaddr, int *port) 53 { 54 int ret; 55 char *find; 56 int a,b,c,d; 57 int pa,pb; 58 ret = ftp_send_command("PASV\r\n"); 59 if(ret != 1) 60 { 61 return 0; 62 } 63 ret = ftp_recv_respond(m_recv_buffer, 1024); 64 if(ret != 227) 65 { 66 return 0; 67 } 68 find = strrchr(m_recv_buffer, '('); 69 sscanf(find, "(%d,%d,%d,%d,%d,%d)", &a, &b, &c, &d, &pa, &pb); 70 sprintf(ipaddr, "%d.%d.%d.%d", a, b, c, d); 71 *port = pa * 256 + pb; 72 return 1; 73 } 74 75 //上传文件 76 int ftp_upload(char *name, void *buf, int len) 77 { 78 int ret; 79 char ipaddr[32]; 80 int port; 81 82 //查询数据地址 83 ret=ftp_enter_pasv(ipaddr, &port); 84 if(ret != 1) 85 { 86 return 0; 87 } 88 ret=socket_connect(m_socket_data, ipaddr, port); 89 if(ret != 1) 90 { 91 return 0; 92 } 93 //准备上传 94 sprintf(m_send_buffer, "STOR %s\r\n", name); 95 ret = ftp_send_command(m_send_buffer); 96 if(ret != 1) 97 { 98 return 0; 99 } 100 ret = ftp_recv_respond(m_recv_buffer, 1024); 101 if(ret != 150) 102 { 103 socket_close(m_socket_data); 104 return 0; 105 } 106 107 //开始上传 108 ret = socket_send(m_socket_data, buf, len); 109 if(ret != len) 110 { 111 LOG_INFO("send data error!\r\n"); 112 socket_close(m_socket_data); 113 return 0; 114 } 115 socket_close(m_socket_data); 116 117 //上传完成,等待回应 118 ret = ftp_recv_respond(m_recv_buffer, 1024); 119 return (ret==226); 120 } 121 122 //下载文件 123 int ftp_download(char *name, void *buf, int len) 124 { 125 int i; 126 int ret; 127 char ipaddr[32]; 128 int port; 129 130 //查询数据地址 131 ret = ftp_enter_pasv(ipaddr, &port); 132 if(ret != 1) 133 { 134 return 0; 135 } 136 //连接数据端口 137 ret = socket_connect(m_socket_data, ipaddr, port); 138 if(ret != 1) 139 { 140 LOG_INFO("failed to connect data port\r\n"); 141 return 0; 142 } 143 144 //准备下载 145 sprintf(m_send_buffer, "RETR %s\r\n", name); 146 ret = ftp_send_command(m_send_buffer); 147 if(ret != 1) 148 { 149 return 0; 150 } 151 ret = ftp_recv_respond(m_recv_buffer, 1024); 152 if(ret != 150) 153 { 154 socket_close(m_socket_data); 155 return 0; 156 } 157 158 //开始下载,读取完数据后,服务器会自动关闭连接 159 for(i=0; i<len; i+=ret) 160 { 161 ret = socket_recv(m_socket_data, ((char *)buf) + i, len); 162 LOG_INFO("download %d/%d.\r\n", i + ret, len); 163 if(ret < 0) 164 { 165 LOG_INFO("download was interrupted.\r\n"); 166 break; 167 } 168 } 169 //下载完成 170 LOG_INFO("download %d/%d bytes complete.\r\n", i, len); 171 socket_close(m_socket_data); 172 ret = ftp_recv_respond(m_recv_buffer, 1024); 173 return (ret==226); 174 } 175 176 //返回文件大小 177 int ftp_filesize(char *name) 178 { 179 int ret; 180 int size; 181 sprintf(m_send_buffer,"SIZE %s\r\n",name); 182 ret = ftp_send_command(m_send_buffer); 183 if(ret != 1) 184 { 185 return 0; 186 } 187 ret = ftp_recv_respond(m_recv_buffer, 1024); 188 if(ret != 213) 189 { 190 return 0; 191 } 192 size = atoi(m_recv_buffer + 4); 193 return size; 194 } 195 196 //登陆服务器 197 int ftp_login(char *addr, int port, char *username, char *password) 198 { 199 int ret; 200 LOG_INFO("connect...\r\n"); 201 ret = socket_connect(m_socket_cmd, addr, port); 202 if(ret != 1) 203 { 204 LOG_INFO("connect server failed!\r\n"); 205 return 0; 206 } 207 LOG_INFO("connect ok.\r\n"); 208 //等待欢迎信息 209 ret = ftp_recv_respond(m_recv_buffer, 1024); 210 if(ret != 220) 211 { 212 LOG_INFO("bad server, ret=%d!\r\n", ret); 213 socket_close(m_socket_cmd); 214 return 0; 215 } 216 217 LOG_INFO("login...\r\n"); 218 //发送USER 219 sprintf(m_send_buffer, "USER %s\r\n", username); 220 ret = ftp_send_command(m_send_buffer); 221 if(ret != 1) 222 { 223 socket_close(m_socket_cmd); 224 return 0; 225 } 226 ret = ftp_recv_respond(m_recv_buffer, 1024); 227 if(ret != 331) 228 { 229 socket_close(m_socket_cmd); 230 return 0; 231 } 232 233 //发送PASS 234 sprintf(m_send_buffer, "PASS %s\r\n", password); 235 ret = ftp_send_command(m_send_buffer); 236 if(ret != 1) 237 { 238 socket_close(m_socket_cmd); 239 return 0; 240 } 241 ret = ftp_recv_respond(m_recv_buffer, 1024); 242 if(ret != 230) 243 { 244 socket_close(m_socket_cmd); 245 return 0; 246 } 247 LOG_INFO("login success.\r\n"); 248 249 //设置为二进制模式 250 ret = ftp_send_command("TYPE I\r\n"); 251 if(ret != 1) 252 { 253 socket_close(m_socket_cmd); 254 return 0; 255 } 256 ret = ftp_recv_respond(m_recv_buffer, 1024); 257 if(ret != 200) 258 { 259 socket_close(m_socket_cmd); 260 return 0; 261 } 262 return 1; 263 } 264 265 void ftp_quit(void) 266 { 267 ftp_send_command("QUIT\r\n"); 268 socket_close(m_socket_cmd); 269 } 270 271 void ftp_init(void) 272 { 273 m_socket_cmd = socket_create(); 274 m_socket_data= socket_create(); 275 }
引申阅读:
FileZilla及FileZilla server:FileZilla中文网。
手机端ftp server软件的测试:
- 手机端安装手机FTP服务端app(WiFi Pro FTP Server) v1.9.4 专业版:手机wifi服务管理软件,用户可以使用该软件将Android手机/平板电脑转换成一个FTP服务器;电脑端安装FileZilla FTP Client。
- 用微信给手机传文件test.txt.安卓手机的文件目录位
/Android/data/com.tencent.mm/MicroMsg/Download/test.txt
- 手机端打开并设置便携式WLAN热点,PC端连接该热点,
- PC端打开FileZilla FTP Client设置本地接收文件位置,服务器的ip地址端口,用户名密码,然后连接,在远端文件浏览器中双击要下载的文件,则该文件就会被下载在指定位置。