ftp客户端的创建
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客户端的创建的更多相关文章
- 使用 Socket 通信实现 FTP 客户端程序(来自IBM)
FTP 客户端如 FlashFXP,File Zilla 被广泛应用,原理上都是用底层的 Socket 来实现.FTP 客户端与服务器端进行数据交换必须建立两个套接字,一个作为命令通道,一个作为数据通 ...
- Socket网络编程--FTP客户端
Socket网络编程--FTP客户端(1)(Windows) 已经好久没有写过博客进行分享了.具体原因,在以后说. 这几天在了解FTP协议,准备任务是写一个FTP客户端程序.直接上干货了. 0.了解F ...
- Socket网络编程--FTP客户端(1)(Windows)
已经好久没有写过博客进行分享了.具体原因,在以后说. 这几天在了解FTP协议,准备任务是写一个FTP客户端程序.直接上干货了. 0.了解FTP作用 就是一个提供一个文件的共享协议. 1.了解FTP协议 ...
- 用edtftpj实现Java FTP客户端工具
edtftpj是一个java FTP工具包,使用非常方便,感觉比Apache的好用,但Apache更灵活.edtftpj有多种版本,分别是java..net和js版本.对于Java版的有一个免费版本. ...
- Socket网络编程--FTP客户端(60篇socket博客,而且都比较简单、深入浅出)
已经好久没有写过博客进行分享了.具体原因,在以后说. 这几天在了解FTP协议,准备任务是写一个FTP客户端程序.直接上干货了. 0.了解FTP作用 就是一个提供一个文件的共享协议. 1.了解FTP协议 ...
- [置顶] Ftp客户端概要设计
Ftp客户端概要设计 1.概述 ftp是基于TCP的文件传输协议,主要是用于控制远程文件,如下载.上传.续传.重命名.删除等.其命令是基于可见字符,易于理解的方式交互的.客户端与服务器端的交互遵循一应 ...
- 【RL-TCPnet网络教程】第37章 RL-TCPnet之FTP客户端
第37章 RL-TCPnet之FTP客户端 本章节为大家讲解RL-TCPnet的FTP客户端应用,学习本章节前,务必要优先学习第35章的FTP基础知识.有了这些基础知识之后,再搞本章节会有事 ...
- Jenkins结合.net平台之ftp客户端
上一节我们讲解了如何配置ftp服务端,本节我们讲解如何使用winscp搭建ftp客户端,为什么使用winscp而不是filezilla客户端版,前面我们简单说过,这里不再赘述. 下载winscp以后我 ...
- Socket网络编程--FTP客户端(2)(Windows)
上一篇FTP客户端讲到如果制作一个简单的FTP客户端,功能实现了,但是后面我们发现了问题,就是FTP是使用明文进行操作的.对于普通情况来说就无所谓了.但有时候要安全的一点的话,就应该使用FTP的安全版 ...
随机推荐
- mybatis异常: invalid comparison: java.util.ArrayList and java.lang.String] with root cause
mybatis中使用动态sql,报错: invalid comparison: java.util.ArrayList and java.lang.String] with root cause 是由 ...
- zk选举过程
1. 服务器启动时期的Leader选举 若进行Leader选举,则至少需要两台机器,这里选取3台机器组成的服务器集群为例.在集群初始化阶段,当有一台服务器Server1启动时,其单独无法进行和完成Le ...
- nodejs+mysql入门实例
此前我已准备好mysql,使用的是PHP的组合包Appserv 手动添加数据库依赖: 在package.json的dependencies中新增, “mysql” : “latest”, { &quo ...
- go语言基础之匿名变量和多重赋
1.匿名变量 package main //必须有一个main包 import "fmt" func test() (a, b, c int) { return 1, 2, 3 } ...
- SpringMVC防止XSS注入
xss(Cross Site Scripting)注入就是,跨站脚本攻击,和sql注入类似的,在请求中添加恶意脚本,实现控制用户. XssHttpServletRequestWrappe.java 重 ...
- 查询mysql数据库中所有表名
查找所有表的语句 select table_name from information_schema.tables where table_schema='当前数据库';
- hive中的concat,concat_ws,collect_set用法
select id, str_to_map(concat_ws(',',collect_set(concat(substr(repay_time,0,7), ':',round(interest,2) ...
- C#/Sqlite-单机Window 程序 sqlite 数据库实现
数据库分析和选择 Excel 文件 做数据源 限制性比较强,且不适合查询,分析 等操作 Access 数据库 Access 管理数据界面和功能不强 mysql 和sql server 功能满足,但需要 ...
- (转)IntelliJ IDEA下的使用git
1.git简介 Git是目前流行的分布式版本管理系统.它拥有两套版本库,本地库和远程库,在不进行合并和删除之类的操作时这两套版本库互不影响.也因此其近乎所有的操作都是本地执行,所以在断网的情况下任然可 ...
- 在笛卡尔坐标系上描绘y=x^2-4/x^2-2x-3曲线
<!DOCTYPE html> <html lang="utf-8"> <meta http-equiv="Content-Type&quo ...