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. 关于Mysort实验的补发博客

    关于本次课后的一些话 关于这次课上的关于sort -nk 2 -t: sort.txt的实验没能在课上做出,有自身的知识不够,没能灵活运用所学知识,以及在当时课上走了会神,回过头来已经不知道该干些什么 ...

  2. (小规模)b牌棋盘完美覆盖数

    (小规模)b牌棋盘完美覆盖数 考虑一个普通的国际象棋棋盘,它被分成8*8(8行8列)的64个正方形.设有形状一样的多米诺骨牌,每张牌恰好覆盖棋盘上相邻的两个方格(即1*2的骨牌).那么能否把32个这样 ...

  3. linux禁ping与限制ip登录

    以root进入linux系统,然后编辑文件icmp_echo_ignore_allvi /proc/sys/net/ipv4/icmp_echo_ignore_all将其值改为1后为禁止PING将其值 ...

  4. Web安全测试指南--认证

    认证: 5.1.1.敏感数据传输: 编号 Web_Authen_01_01 用例名称 敏感数据传输保密性测试 用例描述 测试敏感数据是否通过加密通道进行传输以防止信息泄漏. 严重级别 高 前置条件 1 ...

  5. 基于t-io的MI工具实现

    原文:https://my.oschina.net/u/2984386/blog/1630300 背景介绍 t-io是一款国产开源的网络编程框架,主要是特点:简单,易上手,AIP封装通俗易懂,适合一般 ...

  6. [转]SQLServer和Oracle,存储过程区别,常用函数对比

    本文转自:http://www.cnblogs.com/neru/archive/2011/08/18/2144049.html 以前一直用sqlserver,只有很少的一点oracle的经验,现在要 ...

  7. phpstorm不安装apache就可以本地测试PHP

    最近再搞个PHP的项目,找了很多发现phpstorm这个非常小巧而且很好用,,顺便推荐一下idea开发android非常不错,这2个IDE都是一家公司的.本文由智动软件(zdexe.com)原创,转载 ...

  8. 取url中的参数值

    string url = "https://i.cnblogs.com/EditPosts.aspx?opt=1";//key不区分大小string key="opt&q ...

  9. 机器学习:K-近邻算法(KNN)

    机器学习:K-近邻算法(KNN) 一.KNN算法概述 KNN作为一种有监督分类算法,是最简单的机器学习算法之一,顾名思义,其算法主体思想就是根据距离相近的邻居类别,来判定自己的所属类别.算法的前提是需 ...

  10. 在Spring3中使用注解(@Scheduled)创建计划任务

    Spring3中加强了注解的使用,其中计划任务也得到了增强,现在创建一个计划任务只需要两步就完成了: 创建一个Java类,添加一个无参无返回值的方法,在方法上用@Scheduled注解修饰一下: 在S ...