1.本段代码采用了 select I/O端口复用

2.含有三种功能:ls,  上传文件, 下载文件。这是拷贝别人的代码,自己添加了注释,随后会进行修改,

  自己需要的功能:上传文件, 下载文件,  (并且在传输途中,对所有的文件进行openssl加密)

 #include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/fcntl.h> #define MAXBUF 1024 //宏大小
#define STDIN_FILENO 1 //标准输入
#define STDOUT_FILENO 0 //标准输出 #define USERNAME 220 //用户名
#define PASSWORD 331 //密码
#define LOGIN 230 //登录
#define PATHNAME 257 //路径名
#define CLOSEDATA 226 //
#define ACTIONOK 250 // char *rbuf,*rbuf1,*wbuf,*wbuf1; char filename[]; //文件名
char *host; //要连接的服务器地址 struct sockaddr_in servaddr; //服务器的地址、端口结构体 //1.第一步,打开一个TCP链接
int cliopen(char *host,int port);
//
int strtosrv(char *str);
int ftp_get(int sck,char *pDownloadFileName);
int ftp_put(int sck,char *pUploadFileName_s);
void cmd_tcp(int sockfd); // //主函数
int main(int argc,char *argv[])
{
int fd; //判断输入参数
if( != argc -)
{
printf("%s\n","missing <hostname>");
exit();
} //指定服务器地址
host = argv[];
//指定端口
int port = ; rbuf = (char *)malloc(MAXBUF*sizeof(char));
rbuf1 = (char *)malloc(MAXBUF*sizeof(char));
wbuf = (char *)malloc(MAXBUF*sizeof(char));
wbuf1 = (char *)malloc(MAXBUF*sizeof(char)); //1.得到已连接的套接字
fd = cliopen(host,port); //2.
cmd_tcp(fd); exit();
} //1.第一步,打开一个TCP链接
int cliopen(char *host,int port)
{
int control_sock; //1.FTP 自己的传输地址结构体
struct hostent *ht = NULL; //2.创建套接字
control_sock = socket(AF_INET,SOCK_STREAM,);
if(control_sock < )
{
printf("socket error\n");
return -;
} //3.将IP地址进行转换,变为FTP地址结构体
ht = gethostbyname(host);
if(!ht)
{
return -;
} //4.连接服务器,返回套接字
memset(&servaddr,,sizeof(struct sockaddr_in));
memcpy(&servaddr.sin_addr.s_addr,ht->h_addr,ht->h_length);
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(port); if(connect(control_sock,(struct sockaddr*)&servaddr,sizeof(struct sockaddr)) == -)
{
return -;
}
return control_sock;
} //匹配下载的文件名
int s(char *str,char *s2)
{
//char s1[100]; return sscanf(str," get %s",s2) == ; } //匹配上传的文件名
int st(char *str,char *s1)
{
return sscanf(str," put %s",s1) == ;
} //获取服务器 发送给 客户端的 IP地址 和 端口;
int strtosrv(char *str)
{
int addr[];
//printf("%s\n",str);
sscanf(str,"%*[^(](%d,%d,%d,%d,%d,%d)",&addr[],&addr[],&addr[],&addr[],&addr[],&addr[]);
bzero(host,strlen(host));
sprintf(host,"%d.%d.%d.%d",addr[],addr[],addr[],addr[]);
int port = addr[]* + addr[];
return port;
} //显示文件列表
void ftp_list(int sockfd)
{
int nread;
for(;;)
{
if((nread = recv(sockfd,rbuf1,MAXBUF,)) < )
{
printf("recv error\n");
}
else if(nread == )
{
//printf("over\n");
break;
}
if(write(STDOUT_FILENO,rbuf1,nread) != nread)
printf("send error to stdout\n");
/*else
printf("read something\n");*/
}
if(close(sockfd) < )
printf("close error\n");
} //下载文件
int ftp_get(int sck,char *pDownloadFileName)
{
int handle = open(pDownloadFileName,O_WRONLY | O_CREAT | O_TRUNC, S_IREAD| S_IWRITE);
int nread;
printf("%d\n",handle);
/*if(handle == -1)
return -1;*/ //2. 猜测 ====================应该是将 ssl 接口放在这里,用来传输数据 for(;;)
{
if((nread = recv(sck,rbuf1,MAXBUF,)) < )
{
printf("receive error\n");
}
else if(nread == )
{
printf("over\n");
break;
}
// printf("%s\n",rbuf1);
if(write(handle,rbuf1,nread) != nread)
printf("receive error from server!");
if(write(STDOUT_FILENO,rbuf1,nread) != nread)
printf("receive error from server!");
}
if(close(sck) < )
printf("close error\n");
} //上传文件
int ftp_put(int sck,char *pUploadFileName_s)
{
//int c_sock;
int handle = open(pUploadFileName_s,O_RDWR);
int nread;
if(handle == -)
return -;
//ftp_type(c_sock,"I"); //3. 猜测 ====================应该是将 ssl 接口放在这里,用来传输数据
for(;;)
{
if((nread = read(handle,rbuf1,MAXBUF)) < )
{
printf("read error!");
}
else if(nread == )
break;
if(write(STDOUT_FILENO,rbuf1,nread) != nread)
printf("send error!");
if(write(sck,rbuf1,nread) != nread)
printf("send error!");
}
if(close(sck) < )
printf("close error\n");
} //各种参数的执行
void cmd_tcp(int sockfd)
{
int maxfdp1,nread,nwrite,fd,replycode,tag=,data_sock;
int port;
char *pathname;
fd_set rset; //可读文件描述符集合
FD_ZERO(&rset); //清空可读文件描述符集合
maxfdp1 = sockfd + ; //最大套接字 for(;;)
{
//1.将 标准输入加入 可读文件描述符集合
FD_SET(STDIN_FILENO,&rset);
//2.将 命令套接字 加入可读文件描述符集合
FD_SET(sockfd,&rset); //3.监听读事件
if(select(maxfdp1,&rset,NULL,NULL,NULL)<)
{
printf("select error\n");
}
//4.判断标准输入是否有读事件
if(FD_ISSET(STDIN_FILENO,&rset))
{
//5.清空读缓冲区 和 写缓冲区
bzero(wbuf,MAXBUF); //zero
bzero(rbuf1,MAXBUF); if((nread = read(STDIN_FILENO,rbuf1,MAXBUF)) <)
printf("read error from stdin\n");
nwrite = nread + ; //=======这里不懂,replycode 什么时候赋的值 //6.命令套接字中 写入 用户名
if(replycode == USERNAME)
{
sprintf(wbuf,"USER %s",rbuf1); if(write(sockfd,wbuf,nwrite) != nwrite)
{
printf("write error\n");
}
//printf("%s\n",wbuf);
//memset(rbuf1,0,sizeof(rbuf1));
//memset(wbuf,0,sizeof(wbuf));
//printf("1:%s\n",wbuf);
} //7.命令套接字中 写入 密码
if(replycode == PASSWORD)
{
//printf("%s\n",rbuf1);
sprintf(wbuf,"PASS %s",rbuf1);
if(write(sockfd,wbuf,nwrite) != nwrite)
printf("write error\n");
//bzero(rbuf,sizeof(rbuf));
//printf("%s\n",wbuf);
//printf("2:%s\n",wbuf);
} if(replycode == || replycode == LOGIN || replycode == CLOSEDATA || replycode == PATHNAME || replycode == ACTIONOK)
{
if(strncmp(rbuf1,"pwd",) == )
{
//printf("%s\n",rbuf1);
sprintf(wbuf,"%s","PWD\n");
write(sockfd,wbuf,);
continue;
}
if(strncmp(rbuf1,"quit",) == )
{
sprintf(wbuf,"%s","QUIT\n");
write(sockfd,wbuf,);
//close(sockfd);
if(close(sockfd) <)
printf("close error\n");
break;
}
if(strncmp(rbuf1,"cwd",) == )
{
//sprintf(wbuf,"%s","PASV\n");
sprintf(wbuf,"%s",rbuf1);
write(sockfd,wbuf,nread); //sprintf(wbuf1,"%s","CWD\n"); continue;
} if(strncmp(rbuf1,"ls",) == )
{
tag = ; //显示文件 标识符
//printf("%s\n",rbuf1);
sprintf(wbuf,"%s","PASV\n");
//printf("%s\n",wbuf);
write(sockfd,wbuf,);
//read
//sprintf(wbuf1,"%s","LIST -al\n");
nwrite = ;
//write(sockfd,wbuf1,nwrite);
//ftp_list(sockfd);
continue;
}
//8.下载文件
if(strncmp(rbuf1,"get",) == )
{
tag = ; //下载文件标识符 //被动传输模式
sprintf(wbuf,"%s","PASV\n");
//printf("%s\n",s(rbuf1));
//char filename[100];
s(rbuf1,filename);
printf("%s\n",filename);
write(sockfd,wbuf,);
continue;
} if(strncmp(rbuf1,"put",) == )
{
tag = ; //上传文件标识符
sprintf(wbuf,"%s","PASV\n"); //把内容赋值给 读缓冲区
st(rbuf1,filename);
printf("%s\n",filename);
write(sockfd,wbuf,);
continue;
}
}
/*if(close(sockfd) <0)
printf("close error\n");*/
}
if(FD_ISSET(sockfd,&rset))
{
//9.清空读缓冲区 和 写缓冲区
bzero(rbuf,strlen(rbuf));
//10.读套接字中的内容
if((nread = recv(sockfd,rbuf,MAXBUF,)) <)
printf("recv error\n");
else if(nread == )
break; //比较
if(strncmp(rbuf,"",) == || strncmp(rbuf,"",)==)
{
/*if(write(STDOUT_FILENO,rbuf,nread) != nread)
printf("write error to stdout\n");*/ //链接字符串
strcat(rbuf,"your name:"); //printf("%s\n",rbuf);
nread += ;
/*if(write(STDOUT_FILENO,rbuf,nread) != nread)
printf("write error to stdout\n");*/
replycode = USERNAME;
}
if(strncmp(rbuf,"",) == )
{
/*if(write(STDOUT_FILENO,rbuf,nread) != nread)
printf("write error to stdout\n")*/;
strcat(rbuf,"your password:");
nread += ;
/*if(write(STDOUT_FILENO,rbuf,nread) != nread)
printf("write error to stdout\n");*/
replycode = PASSWORD;
}
if(strncmp(rbuf,"",) == )
{
/*if(write(STDOUT_FILENO,rbuf,nread) != nread)
printf("write error to stdout\n");*/
replycode = LOGIN;
}
if(strncmp(rbuf,"",) == )
{
/*if(write(STDOUT_FILENO,rbuf,nread) != nread)
printf("write error to stdout\n");*/
replycode = PATHNAME;
}
if(strncmp(rbuf,"",) == )
{
/*if(write(STDOUT_FILENO,rbuf,nread) != nread)
printf("write error to stdout\n");*/
replycode = CLOSEDATA;
}
if(strncmp(rbuf,"",) == )
{
/*if(write(STDOUT_FILENO,rbuf,nread) != nread)
printf("write error to stdout\n");*/
replycode = ACTIONOK;
}
if(strncmp(rbuf,"",) == )
{
replycode = ;
}
/*if(strncmp(rbuf,"150",3) == 0)
{
if(write(STDOUT_FILENO,rbuf,nread) != nread)
printf("write error to stdout\n");
}*/
//fprintf(stderr,"%d\n",1);
if(strncmp(rbuf,"",) == )
{
//printf("%d\n",1);
/*if(write(STDOUT_FILENO,rbuf,nread) != nread)
printf("write error to stdout\n");*/ //获取服务器返回的 接收数据的端口,和地址
int port1 = strtosrv(rbuf);
printf("%d\n",port1);
printf("%s\n",host); //创建新的传输数据的套接字?
//1. 猜测 ====================应该是将 ssl 接口放在这里,用来传输数据
data_sock = cliopen(host,port1); //bzero(rbuf,sizeof(rbuf));
//printf("%d\n",fd);
//if(strncmp(rbuf1,"ls",2) == 0)
if(tag == )
{
write(sockfd,"list\n",strlen("list\n"));
ftp_list(data_sock);
/*if(write(STDOUT_FILENO,rbuf,nread) != nread)
printf("write error to stdout\n");*/ }
//else if(strncmp(rbuf1,"get",3) == 0)
else if(tag == )
{
//sprintf(wbuf,"%s","RETR\n");
//printf("%s\n",wbuf);
//int str = strlen(filename);
//printf("%d\n",str);
sprintf(wbuf,"RETR %s\n",filename);
printf("%s\n",wbuf);
//int p = 5 + str + 1; //命令套接字中写入 下载文件命令
printf("%d\n",write(sockfd,wbuf,strlen(wbuf)));
//printf("%d\n",p); //下载文件
ftp_get(data_sock,filename);
}
else if(tag == )
{ // 上传文件
sprintf(wbuf,"STOR %s\n",filename);
printf("%s\n",wbuf);
write(sockfd,wbuf,strlen(wbuf));
ftp_put(data_sock,filename);
}
nwrite = ;
}
/*if(strncmp(rbuf,"150",3) == 0)
{
if(write(STDOUT_FILENO,rbuf,nread) != nread)
printf("write error to stdout\n");
}*/
//printf("%s\n",rbuf);
if(write(STDOUT_FILENO,rbuf,nread) != nread)
printf("write error to stdout\n");
/*else
printf("%d\n",-1);*/
}
}
}

ftp客户端的创建的更多相关文章

  1. 使用 Socket 通信实现 FTP 客户端程序(来自IBM)

    FTP 客户端如 FlashFXP,File Zilla 被广泛应用,原理上都是用底层的 Socket 来实现.FTP 客户端与服务器端进行数据交换必须建立两个套接字,一个作为命令通道,一个作为数据通 ...

  2. Socket网络编程--FTP客户端

    Socket网络编程--FTP客户端(1)(Windows) 已经好久没有写过博客进行分享了.具体原因,在以后说. 这几天在了解FTP协议,准备任务是写一个FTP客户端程序.直接上干货了. 0.了解F ...

  3. Socket网络编程--FTP客户端(1)(Windows)

    已经好久没有写过博客进行分享了.具体原因,在以后说. 这几天在了解FTP协议,准备任务是写一个FTP客户端程序.直接上干货了. 0.了解FTP作用 就是一个提供一个文件的共享协议. 1.了解FTP协议 ...

  4. 用edtftpj实现Java FTP客户端工具

    edtftpj是一个java FTP工具包,使用非常方便,感觉比Apache的好用,但Apache更灵活.edtftpj有多种版本,分别是java..net和js版本.对于Java版的有一个免费版本. ...

  5. Socket网络编程--FTP客户端(60篇socket博客,而且都比较简单、深入浅出)

    已经好久没有写过博客进行分享了.具体原因,在以后说. 这几天在了解FTP协议,准备任务是写一个FTP客户端程序.直接上干货了. 0.了解FTP作用 就是一个提供一个文件的共享协议. 1.了解FTP协议 ...

  6. [置顶] Ftp客户端概要设计

    Ftp客户端概要设计 1.概述 ftp是基于TCP的文件传输协议,主要是用于控制远程文件,如下载.上传.续传.重命名.删除等.其命令是基于可见字符,易于理解的方式交互的.客户端与服务器端的交互遵循一应 ...

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

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

  8. Jenkins结合.net平台之ftp客户端

    上一节我们讲解了如何配置ftp服务端,本节我们讲解如何使用winscp搭建ftp客户端,为什么使用winscp而不是filezilla客户端版,前面我们简单说过,这里不再赘述. 下载winscp以后我 ...

  9. Socket网络编程--FTP客户端(2)(Windows)

    上一篇FTP客户端讲到如果制作一个简单的FTP客户端,功能实现了,但是后面我们发现了问题,就是FTP是使用明文进行操作的.对于普通情况来说就无所谓了.但有时候要安全的一点的话,就应该使用FTP的安全版 ...

随机推荐

  1. python3-开发进阶Django-form组件中model form组件

    Django的model form组件 这是一个神奇的组件,通过名字我们可以看出来,这个组件的功能就是把model和form组合起来,先来一个简单的例子来看一下这个东西怎么用:比如我们的数据库中有这样 ...

  2. Android如何获取屏幕的分辨

    在实际的项目中,我们经常要得到当前屏幕的分辨率,进行机型适配,得到分辨率其实很简单,主要有两种方法. 方法一: Display mDisplay = getWindowManager().getDef ...

  3. android:scrollbarStyle属性及滚动条和分割线覆盖问题

    android:scrollbarStyle可以定义滚动条的样式和位置,可选值有insideOverlay.insideInset.outsideOverlay.outsideInset四种. 其中i ...

  4. LeetCode 771. 宝石与石头(java)

    给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头. S 中每个字符代表了一种你拥有的石头的类型,你想知道你拥有的石头中有多少是宝石. J 中的字母不重复,J 和 S中的所有字符都是字母 ...

  5. ubuntu系统使用dnw下载程序

    转:http://blog.chinaunix.net/uid-22030783-id-3350840.html 获得dnw4linux.tar.bz2 源码包,可在xcembed论坛下载:http: ...

  6. js模板引擎-art-template常用

    art-template javascript 模板引擎 分为原生语法和简洁语法,本文主要是讲简洁语法 基础数据渲染 输出HTML 流程控制 遍历 调用自定义函数方法 子模板引入 基础数据渲染 一.引 ...

  7. 2014DNIOS视频教程(5-9)

    2014DNIOS视频教程(5-9) 联系2g32@sina.com

  8. 十.spring-boot添加jsp支持

    1.创建maven web project: 2.在添加web依赖 3.配置application.properties支持jsp 4.添加一个controller类 5.加入jsp页面 6.启动类 ...

  9. echarts图形报表缓存问题(option数据缓存)

    这几天我在工作中用到了echarts开发报表.每次查询出来的数据都是新的,但是echart展现的图形报表却还是之前的数据.网上找了搜索了很多次也没能解决,后面加了技术群才解决的. 我开始已经确定是报表 ...

  10. thinkphp5.0 中使用第三方无命名空间的类库

    ThinkPHP5建议所有的扩展类库都使用命名空间定义,如果你的类库没有使用命名空间,则不支持自动加载,必须使用Loader::import方法先导入文件后才能使用. 首先要在文件头部使用loader ...