目录
一、FTP文件传输协议简介
一、FTP的连接方式
1. 控制连接
2. 数据连接
二、FTP文件传输模式
一、ASCII传输方式:
二、进制传输模式:
二、函数库ftplib-4.0-1的使用
函数库ftplib-4.0-1链接:
https://download.csdn.net/download/qq_43445867/85126269
FTP文件传输协议(File Transfer Protocol,FTP)是用于在网络上进行文件传输的一套标准协议,可以使用户以文件操作的方式(增删改查)访问远程主机资源,而用户并不需要登录主机。
可以使用 ftp 命令使用“文件传送协议”(FTP) 在本地和远程主机或远程主机之间传送文件。
FTP协议是C/S架构,即客户端/服务器模式,是基于TCP的应用层传输协议。
FTP采用双TCP的连接方式;
控制连接采用的TCP端口号是21
数据连接采用的TCP端口号是20
一个完整的FTP文件传输需要建立两种类型的连接,一种为文件传输下命令,称为控制连接,另一种实现真正的文件传输,称为数据连接。
用于在FTP客户端和FTP服务器之间传输FTP控制命令及命令执行信息。控制连接在整个FTP会话期间一直保持打开
客户端希望与FTP服务器建立上传下载的数据传输时,它首先向服务器的TCP 21端口发起一个建立连接的请求,FTP服务器接受来自客户端的请求,完成连接的建立过程,这样的连接就称为FTP控制连接。
用于传输数据,包括数据上传、下载、文件列表发送等。数据传输结束后数据连接终止。 FTP控制连接建立之后,即可开始传输文件,传输文件的连接称为FTP数据连接。FTP数据连接就是FTP传输数据的过程,它有两种传输模式
PORT(主动)方式的连接过程是:
客户端向服务器的FTP端口(默认是21)发送连接请求,服务器接受连接,建立一条命令链路。当需要传送数据时,客户端在命令链路上用PORT命令告诉服务器:“我打开了XXXX端口,你过来连接我”。于是服务器从20端口向客户端的XXXX端口发送连接请求,建立一条数据链路来传送数据。
PASV(被动)方式的连接过程是:
客户端向服务器的FTP端口(默认是21)发送连接请求,服务器接受连接,建立一条命令链路。当需要传送数据时,服务器在命令链路上用PASV命令告诉客户端:“我打开了XXXX端口,你过来连接我”。于是客户端向服务器的XXXX端口发送连接请求,建立一条数据链路来传送数据。
FTP可用多种格式传输文件,通常由系统决定,大多数系统(包括UNIX系统)只有两种模式:文本模 式(ASCll模式)和二进制模式。
假定用户正在拷贝的文件包含的简单ASCII码文本,如果在远程机器上运行的不是UNIX,当文件传输时ftp通常会自动地调整文件的内容以便于把文件解释成另外那台计算机存储文本文件的格式。
但是常常有这样的情况,用户正在传输的文件包含的不是文本文件,它们可能是程序,数据库,字处理文件或者压缩文件(尽管字处理文件包含的大部分是文本,其中也包含有指示页尺寸,字库等信息的非打印字符)。在拷贝任何非文本文件之前,用binary 命令告诉ftp逐字拷贝,不要对这些文件进行处理,这也是下面要讲的二进制传输:
在二进制传输中,保存文件的位序,以便原始和拷贝的是逐位一一对应的。即使目的地机器上包含位序列的文件是没意义的。例如,macintosh以二进制方式传送可执行文件到Windows系统,在对方系统上,此文件不能执行。
如果你在ASCII方式下传输二进制文件,即使不需要也仍会转译。这会使传输稍微变慢 ,也会损坏数据,使文件变得不能用。(在大多数计算机上,ASCII方式一般假设每一字符的第一有效位无意义,因为ASCII字符组合不使用它。如果你传输二进制文件,所有的位都是重要的。)如果你知道这两台机器是同样的,则二进制方式对文本文件和数据文件都是有效的。
GLOBALREF int ftplib_debug;
//在调用库函数先使用这个函数初始化
GLOBALREF void FtpInit(void);
GLOBALREF char *FtpLastResponse(netbuf *nControl);
//使用这个函数建立FTP连接,成功返回1失败返回0
GLOBALREF int FtpConnect(const char *host, netbuf **nControl);
/*USAGE
host:服务器地址
conn:连接句柄,唯一标识
*/
static char *host = "xxx.xxx.xx.xxx";
static netbuf *conn = NULL;
if (!FtpConnect(host,&conn))
{
printf("Unable to connect to node %s\n",host);
}
GLOBALREF int FtpOptions(int opt, long val, netbuf *nControl);
GLOBALREF int FtpSetCallback(const FtpCallbackOptions *opt, netbuf *nControl);
GLOBALREF int FtpClearCallback(netbuf *nControl);
//使用这个函数登陆到FTP服务器,成功返回1失败返回0
GLOBALREF int FtpLogin(const char *user, const char *pass, netbuf *nControl);
GLOBALREF int FtpAccess(const char *path, int typ, int mode, netbuf *nControl,
netbuf **nData);
GLOBALREF int FtpRead(void *buf, int max, netbuf *nData);
GLOBALREF int FtpWrite(const void *buf, int len, netbuf *nData);
GLOBALREF int FtpClose(netbuf *nData);
GLOBALREF int FtpSite(const char *cmd, netbuf *nControl);
GLOBALREF int FtpSysType(char *buf, int max, netbuf *nControl);
GLOBALREF int FtpMkdir(const char *path, netbuf *nControl);
GLOBALREF int FtpChdir(const char *path, netbuf *nControl);
GLOBALREF int FtpCDUp(netbuf *nControl);
GLOBALREF int FtpRmdir(const char *path, netbuf *nControl);
GLOBALREF int FtpPwd(char *path, int max, netbuf *nControl);
GLOBALREF int FtpNlst(const char *output, const char *path, netbuf *nControl);
//使用完这个命令会把服务器的根文件列表打印到屏幕上(如何去获取这些文件的更新ing.....)
GLOBALREF int FtpDir(const char *output, const char *path, netbuf *nControl);
char buff_list[100][100];在ftp头文件定义一个全局二维数组用来存放文件名
在ftplib.c中的FtpXfer最后添加以下代码即可把打印的数据存放到buff_list
else
{
for(int i=0;(l = FtpRead(dbuf, FTPLIB_BUFSIZ, nData)) > 0;i++)
{
//printf("-----------------------------------------------%s",dbuf);
strcpy(buff_list[i],dbuf);
fwrite(dbuf, 1, l, local);
num=i;
}
}
free(dbuf);
fflush(local);
if (localfile != NULL)
fclose(local);
FtpClose(nData);
return rv;
}
此时buff_list中的内容格式为
04-13-22 05:18PM abcd
04-13-22 05:26PM 4 dtdt.c
04-13-22 05:26PM 4 uuu.c
需要递归遍历处理才能收发文件如何处理(有时间就更新吧)
GLOBALREF int FtpSize(const char *path, unsigned int *size, char mode, netbuf *nControl);
#if defined(__UINT64_MAX)
GLOBALREF int FtpSizeLong(const char *path, fsz_t *size, char mode, netbuf *nControl);
#endif
GLOBALREF int FtpModDate(const char *path, char *dt, int max, netbuf *nControl);
//使用这个命令获取FTP服务器的文件
/*USAGE:
output:服务器文件名
path:文件路径
mode:传输模式1是ascll 2是二进制
nControl:唯一标识
*/
GLOBALREF int FtpGet(const char *output, const char *path, char mode,netbuf *nControl);
if(FtpGet(name,strippath ? basename(directory) : root_directory,mode,conn))
{
printf("successful get files : %s\n",name);
}
//同get的方法一样
GLOBALREF int FtpPut(const char *input, const char *path, char mode,netbuf *nControl);
GLOBALREF int FtpRename(const char *src, const char *dst, netbuf *nControl);
GLOBALREF int FtpDelete(const char *fnm, netbuf *nControl);
GLOBALREF void FtpQuit(netbuf *nControl);