由于工作需要,需要做一个从ftp服务器下载相关文件内容,保存本地

ftp.h


#ifndef TIANJING_FTP_H
#define TIANJING_FTP_H#include <stdio.h>//链接服务器
int ftp_connect( char *host, int port, char *user, char *pwd );
//断开服务器
int ftp_quit( int c_sock);
//设置表示类型
int ftp_type( int c_sock, char mode );
//改变工作目录
int ftp_cwd( int c_sock, char *path );
//回到上一层目录
int ftp_cdup( int c_sock );
//创建目录
int ftp_mkd( int c_sock, char *path );
//列表
int ftp_list( int c_sock, char *path, void **data, unsigned long long *data_len);
//下载文件
int ftp_retrfile( int c_sock, char *s, char *d ,unsigned long long *stor_size, int *stop);
//上传文件
int ftp_storfile( int c_sock, char *s, char *d ,unsigned long long *stor_size, int *stop);
//修改文件名&移动目录
int ftp_renamefile( int c_sock, char *s, char *d );
//删除文件
int ftp_deletefile( int c_sock, char *s );
//删除目录
int ftp_deletefolder( int c_sock, char *s );#define __PRINTF__ printf("\n--%s---%s----%s---%s--%d---\n",__FILE__,__DATE__,__TIME__,__FUNCTION__,__LINE__);#define __printf__ printf("\n--%s---%s----%s---%s--%d---\n",__FILE__,__DATE__,__TIME__,__FUNCTION__,__LINE__);#endif //TIANJING_FTP_H

ftp.c


#include "ftp.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>//创建一个socket并返回
int socket_connect(char *host,int port)
{struct sockaddr_in address;int s, opvalue;socklen_t slen;opvalue = 8;slen = sizeof(opvalue);memset(&address, 0, sizeof(address));if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0 ||setsockopt(s, IPPROTO_IP, IP_TOS, &opvalue, slen) < 0)return -1;//设置接收和发送超时struct timeval timeo = {15, 0};setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo));setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));address.sin_family = AF_INET;address.sin_port = htons((unsigned short)port);struct hostent* server = gethostbyname(host);if (!server)return -1;memcpy(&address.sin_addr.s_addr, server->h_addr, server->h_length);if (connect(s, (struct sockaddr*) &address, sizeof(address)) == -1)return -1;return s;
}
//连接到一个ftp的服务器,返回socket
int connect_server( char *host, int port )
{int       ctrl_sock;char      buf[512];int       result;ssize_t   len;ctrl_sock = socket_connect(host, port);if (ctrl_sock == -1) {return -1;}len = recv( ctrl_sock, buf, 512, 0 );buf[len] = 0;sscanf( buf, "%d", &result );if ( result != 220 ) {close( ctrl_sock );return -1;}return ctrl_sock;
}
//发送命令,返回结果
int ftp_sendcmd_re( int sock, char *cmd, void *re_buf, ssize_t *len)
{char        buf[512];ssize_t     r_len;if ( send( sock, cmd, strlen(cmd), 0 ) == -1 )return -1;r_len = recv( sock, buf, 512, 0 );if ( r_len < 1 ) return -1;buf[r_len] = 0;if (len != NULL) *len = r_len;if (re_buf != NULL) sprintf(re_buf, "%s", buf);return 0;
}
//发送命令,返回编号
int ftp_sendcmd( int sock, char *cmd )
{char     buf[512];int      result;ssize_t  len;result = ftp_sendcmd_re(sock, cmd, buf, &len);if (result == 0){sscanf( buf, "%d", &result );}return result;
}
//登录ftp服务器
int login_server( int sock, char *user, char *pwd )
{char    buf[128];int     result;sprintf( buf, "USER %s\r\n", user );result = ftp_sendcmd( sock, buf );if ( result == 230 ) return 0;else if ( result == 331 ) {sprintf( buf, "PASS %s\r\n", pwd );if ( ftp_sendcmd( sock, buf ) != 230 ) return -1;return 0;}elsereturn -1;
}
int create_datasock( int ctrl_sock )
{int     lsn_sock;int     port;int     len;struct sockaddr_in sin;char    cmd[128];lsn_sock = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );if ( lsn_sock == -1 ) return -1;memset( (char *)&sin, 0, sizeof(sin) );sin.sin_family = AF_INET;if( bind(lsn_sock, (struct sockaddr *)&sin, sizeof(sin)) == -1 ) {close( lsn_sock );return -1;}if( listen(lsn_sock, 2) == -1 ) {close( lsn_sock );return -1;}len = sizeof( struct sockaddr );if ( getsockname( lsn_sock, (struct sockaddr *)&sin, (socklen_t *)&len ) == -1 ){close( lsn_sock );return -1;}port = sin.sin_port;if( getsockname( ctrl_sock, (struct sockaddr *)&sin, (socklen_t *)&len ) == -1 ){close( lsn_sock );return -1;}sprintf( cmd, "PORT %d,%d,%d,%d,%d,%d\r\n",sin.sin_addr.s_addr&0x000000FF,(sin.sin_addr.s_addr&0x0000FF00)>>8,(sin.sin_addr.s_addr&0x00FF0000)>>16,(sin.sin_addr.s_addr&0xFF000000)>>24,port>>8, port&0xff );if ( ftp_sendcmd( ctrl_sock, cmd ) != 200 ) {close( lsn_sock );return -1;}return lsn_sock;
}
//连接到PASV接口
int ftp_pasv_connect( int c_sock )
{int     r_sock;int     send_re;ssize_t len;int     addr[6];char    buf[512];char    re_buf[512];//设置PASV被动模式bzero(buf, sizeof(buf));sprintf( buf, "PASV\r\n");send_re = ftp_sendcmd_re( c_sock, buf, re_buf, &len);if (send_re == 0) {sscanf(re_buf, "%*[^(](%d,%d,%d,%d,%d,%d)",&addr[0],&addr[1],&addr[2],&addr[3],&addr[4],&addr[5]);}//连接PASV端口bzero(buf, sizeof(buf));sprintf( buf, "%d.%d.%d.%d",addr[0],addr[1],addr[2],addr[3]);r_sock = socket_connect(buf,addr[4]*256+addr[5]);return r_sock;
}
//表示类型
int ftp_type( int c_sock, char mode )
{char    buf[128];sprintf( buf, "TYPE %c\r\n", mode );if ( ftp_sendcmd( c_sock, buf ) != 200 )return -1;elsereturn 0;
}
//改变工作目录
int ftp_cwd( int c_sock, char *path )
{char    buf[128];int     re;sprintf( buf, "CWD %s\r\n", path );re = ftp_sendcmd( c_sock, buf );if ( re != 250 )return -1;elsereturn 0;
}
//回到上一层目录
int ftp_cdup( int c_sock )
{int     re;re = ftp_sendcmd( c_sock, "CDUP\r\n" );if ( re != 250 )return re;elsereturn 0;
}
//创建目录
int ftp_mkd( int c_sock, char *path )
{char    buf[512];int     re;sprintf( buf, "MKD %s\r\n", path );re = ftp_sendcmd( c_sock, buf );if ( re != 257 )return re;elsereturn 0;
}
//列表
int ftp_list( int c_sock, char *path, void **data, unsigned long long *data_len)
{int     d_sock;char    buf[512];int     send_re;int     result;ssize_t     len,buf_len,total_len;//连接到PASV接口d_sock = ftp_pasv_connect(c_sock);if (d_sock == -1) {return -1;}//发送LIST命令bzero(buf, sizeof(buf));sprintf( buf, "LIST %s\r\n", path);send_re = ftp_sendcmd( c_sock, buf );if (send_re >= 300 || send_re == 0)return send_re;len=total_len = 0;buf_len = 512;void *re_buf = malloc(buf_len);while ( (len = recv( d_sock, buf, 512, 0 )) > 0 ){if (total_len+len > buf_len){buf_len *= 2;void *re_buf_n = malloc(buf_len);memcpy(re_buf_n, re_buf, total_len);free(re_buf);re_buf = re_buf_n;}memcpy(re_buf+total_len, buf, len);total_len += len;}close( d_sock );//向服务器接收返回值bzero(buf, sizeof(buf));len = recv( c_sock, buf, 512, 0 );buf[len] = 0;sscanf( buf, "%d", &result );if ( result != 226 ){free(re_buf);return result;}*data = re_buf;*data_len = total_len;return 0;
}
//下载文件
int ftp_retrfile( int c_sock, char *s, char *d ,unsigned long long *stor_size, int *stop)
{int     d_sock;ssize_t     len,write_len;char    buf[512];int     handle;int     result;//打开本地文件handle = open( d,  O_WRONLY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE );if ( handle == -1 ) return -1;//设置传输模式ftp_type(c_sock, 'I');//连接到PASV接口d_sock = ftp_pasv_connect(c_sock);if (d_sock == -1){close(handle);return -1;}//发送STOR命令bzero(buf, sizeof(buf));sprintf( buf, "RETR %s\r\n", s );result = ftp_sendcmd( c_sock, buf );if (result >= 300 || result == 0){close(handle);return result;}//开始向PASV读取数据bzero(buf, sizeof(buf));while ( (len = recv( d_sock, buf, 512, 0 )) > 0 ) {write_len = write( handle, buf, len );if (write_len != len || (stop != NULL && *stop)){close( d_sock );close( handle );return -1;}if (stor_size != NULL){*stor_size += write_len;}}close( d_sock );close( handle );//向服务器接收返回值bzero(buf, sizeof(buf));len = recv( c_sock, buf, 512, 0 );buf[len] = 0;sscanf( buf, "%d", &result );if ( result >= 300 ) {return result;}return 0;
}
//上传文件
int ftp_storfile( int c_sock, char *s, char *d ,unsigned long long *stor_size, int *stop)
{int     d_sock;ssize_t     len,send_len;char    buf[512];int     handle;int send_re;int result;//打开本地文件handle = open( s,  O_RDONLY);if ( handle == -1 ) return -1;//设置传输模式ftp_type(c_sock, 'I');//连接到PASV接口d_sock = ftp_pasv_connect(c_sock);if (d_sock == -1){close(handle);return -1;}//发送STOR命令bzero(buf, sizeof(buf));sprintf( buf, "STOR %s\r\n", d );send_re = ftp_sendcmd( c_sock, buf );if (send_re >= 300 || send_re == 0){close(handle);return send_re;}//开始向PASV通道写数据bzero(buf, sizeof(buf));while ( (len = read( handle, buf, 512)) > 0){send_len = send(d_sock, buf, len, 0);if (send_len != len ||(stop != NULL && *stop)){close( d_sock );close( handle );return -1;}if (stor_size != NULL){*stor_size += send_len;}}close( d_sock );close( handle );//向服务器接收返回值bzero(buf, sizeof(buf));len = recv( c_sock, buf, 512, 0 );buf[len] = 0;sscanf( buf, "%d", &result );if ( result >= 300 ) {return result;}return 0;
}
//修改文件名&移动目录
int ftp_renamefile( int c_sock, char *s, char *d )
{char    buf[512];int     re;sprintf( buf, "RNFR %s\r\n", s );re = ftp_sendcmd( c_sock, buf );if ( re != 350 ) return re;sprintf( buf, "RNTO %s\r\n", d );re = ftp_sendcmd( c_sock, buf );if ( re != 250 ) return re;return 0;
}
//删除文件
int ftp_deletefile( int c_sock, char *s )
{char    buf[512];int     re;sprintf( buf, "DELE %s\r\n", s );re = ftp_sendcmd( c_sock, buf );if ( re != 250 ) return re;return 0;
}
//删除目录
int ftp_deletefolder( int c_sock, char *s )
{char    buf[512];int     re;sprintf( buf, "RMD %s\r\n", s );re = ftp_sendcmd( c_sock, buf );if ( re != 250 ) return re;return 0;
}
//链接服务器
int ftp_connect( char *host, int port, char *user, char *pwd )
{int     c_sock;c_sock = connect_server( host, port );if ( c_sock == -1 ) return -1;if ( login_server( c_sock, user, pwd ) == -1 ) {close( c_sock );return -1;}return c_sock;
}
//断开服务器
int ftp_quit( int c_sock)
{int re = 0;re = ftp_sendcmd( c_sock, "QUIT\r\n" );close( c_sock );return re;
}

以下是调用方式 main.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "ftp.h"//gcc -o ftp ftp.h ftp.c main.cint main(){char host[13] = {0};memcpy(host,"192.168.1.190",strlen("192.168.1.190"));  //ipint port = 21;char user[5] = {0};memcpy(user,"admin",strlen("admin"));   //用户char pwd[5] = {0};memcpy(pwd,"admin",strlen("admin"));    //密码int ret = ftp_connect(host, port, user,pwd );   //连接printf("ret=%d\n",ret);char s[32] = {0};char d[32] = {0};long long unsigned int fileSize;int stop;memcpy(s,"nginx.conf",strlen("nginx.conf")); //ftp上的源文件memcpy(d,"/home/ftp/cli/demo.conf",strlen("/home/ftp/cli/demo.conf"));  //下载下来的保存文件路径int down = ftp_retrfile( ret, s,d ,&fileSize, &stop);printf("\ndown = %d,fileSize=%d,stop=%d\n",down,(int)fileSize,stop);return  0;}
gcc -o ftp ftp.h ftp.c main.c
./ftproot1@ubuntu:/home/ftp/cli$ ./ftp
ret=3down = 0,fileSize=7815,stop=0
root1@ubuntu:/home/ftp/cli$ ls
demo.conf  ftp  ftp.c  ftp.h  main.c  ng.conf
root1@ubuntu:/home/ftp/cli$

下载成功,ftp服务器自己去搭建一下就可以了。代码里的ftp用户和密码,ip地址,以及下载的文件进行参数调整就好了

以前认为ftp还是蛮复杂的,自己实现一下,感觉还是蛮简单的。有时候还是要沉下心。心静容易把事情想明白。。。。。

c语言实现ftp客户端,下载ftp的文件内容信息相关推荐

  1. 用windows系统下的DOS命令将腾讯视频客户端下载的qlv文件转换成MP4格式(图文详解)

    用windows系统下的DOS命令将腾讯视频客户端下载的qlv文件转换成MP4格式(图文详解) 前言 原理 工具 步骤 延伸 博主联系方式 前言 本人喜欢收集各种优秀的视频,但是很多情况下我们看到的视 ...

  2. FTP客户端--实现FTP文件的上传下载功能

    现在是2017.6.16的1点多,这几天刚好做了个FTP客户端的计网实验,就把思路过程和源码发上来吧! 一.设计思路:首先,登陆指定的FTP服务器(指定服务器的IP和用户名,密码,端口号若无就默认为2 ...

  3. 从手机用FTP客户端下载服务器中的文件

    所需工具: FileZilla Server 下载链接:https://pan.baidu.com/s/122K6Zim9xLJtJp5_pOBqwQ 提取码:bpya 手机软件:AndFTP And ...

  4. filezilla 定时上传_FileZilla Server安装教程 - FtpCopy数据自动备份软件(FTP定时备份)|FTP自动下载|FTP自动上传|FTP自动备份...

    FileZilla Server的视频版安装教程,请查看<FileZilla Server视频安装教程> 1. FileZilla介绍 FileZilla是一款免费开源的FTP软件,分为客 ...

  5. ftp客户端与服务器传文件在哪里,中国大学MOOC: FTP在客户端和服务器端传输文件时,使用的是...

    摘要: 仍不任工能胜作的,中国或者工作岗位培训经过调整,合同解除用人劳动单位随时可以,任工能胜者不作劳动.功率也适用于的计算,客户于电不仅流和叠加定律电压的计适用算.服务向正中电极流极源内由负部的不一 ...

  6. java 点击a标签下载文档_使用a标签进行下载excel文件,打开下载后的文件内容为空,这是为什么?...

    前端代码:下载 后端代码: 接口:@ApiOperation(value = "下载") @GetMapping("/down") public void do ...

  7. 应用层——使用 Socket 通信实现 FTP 客户端程序

    转自:http://blog.csdn.net/yixijide/article/details/8280263 简介: FTP 客户端如 FlashFXP,File Zilla 被广泛应用,原理上都 ...

  8. ftp软件下载,推荐5款免费的ftp软件下载工具

    免费工具是非常吸引人的,现在大部分的软件都是需要充值才能使用的,抓住了免费就是抓住了很多用户的心.而免费ftp下载工具吸引的就是一些机房管理.站长.运维工作.程序员,等需要大量服务器或者电脑的用户朋友 ...

  9. ftp客户端软件有哪些,有哪些ftp客户端软件值得推荐?

    不知道大家对于ftp客户端软件的要求普遍是什么,但是我的要求是很简单的,主要就是好用,方便容易上手,使用起来很容易,不要太复杂的.其实我对于ftp软件的要求应该是大部分网站工作者的基本要求吧.下面是我 ...

  10. 【RL-TCPnet网络教程】第37章 RL-TCPnet之FTP客户端

    第37章      RL-TCPnet之FTP客户端 本章节为大家讲解RL-TCPnet的FTP客户端应用,学习本章节前,务必要优先学习第35章的FTP基础知识.有了这些基础知识之后,再搞本章节会有事 ...

最新文章

  1. Python读excel——xlrd
  2. AV1为何有信心打败H.265?
  3. 软件是否有必要进行性能测试
  4. ElasticSearch Java Api(四) -删除索引
  5. 在html中 标题字体标记的最大取值,西南大学网络教育2020年春0834]《网页设计》作业标准答案...
  6. sqlMapConfig.xml配置文件详解
  7. RabbitMQ(五) 订阅发布者模式介绍以及代码实现
  8. ros如何订阅关节力矩信息_ROS中阶笔记(二):机器人系统设计—URDF机器人建模...
  9. 互联网寒冬资讯分析报告!如何在“大裁员”下逆势而为?
  10. 2006毕业设计Delphi篇(二)
  11. 借用implicit创建我们自己的布尔数据类型-create MyBool data type by implicit
  12. PHP的威胁函数与PHP代码审计
  13. 计算机机房配电计算,银行计算机房动力配电系统浅析
  14. Failed to connect to repository : Error performing git command: git.exe
  15. 《秘密全在小动作上》读书笔记
  16. 数组中a与a[0]的区别
  17. 1000多块整个插板,arduino + android 蓝牙插板的实现--屌丝版
  18. 有效数字修约,按四舍六入五成双原则
  19. 关于c++中的一个母牛生小牛的问题详细解答与体会
  20. POJO有哪些要求?

热门文章

  1. VSCode下载与安装及安装汉化包
  2. Java后台入坑二:renrenfast后台打包和前端打包运行
  3. 十六进制的字符对照表
  4. 刷脸支付打造了一个无卡交易的时代
  5. python 斯皮尔曼相关系数_斯皮尔曼等级相关系数(Spearmansrankcorrelationcoefficient)
  6. webUploader大文件断点续传学习心得 多文件
  7. 软件研发管理:置身其中看问题
  8. IDEA从零到精通(34)之IDEA 强大的文件对比功能
  9. PMP考试题型是如何分布的?
  10. JAVA导入gpx文件_用于Java的GPX解析器?[关闭]