连接服务器
[11:27:55] [R] 正在连接到 192.168.217.135 -> IP=192.168.217.135 PORT=21
[11:27:55] [R] 已连接到 192.168.217.135
[11:27:55] [R] 220 (vsFTPd 3.0.3)
发送用户名、密码
[11:27:55] [R] USER ubuntu
[11:27:55] [R] 331 Please specify the password.
[11:27:55] [R] PASS (hidden)
[11:27:55] [R] 230 Login successful.
pwd显示工作路径
[11:27:55] [R] PWD
[11:27:55] [R] 257 "/home/ubuntu" is the current directory
ls显示当前目录的详细信息
[11:27:55] [R] PASV
[11:27:55] [R] 227 Entering Passive Mode (192,168,217,135,202,198). 202*256+198=51910
[11:27:55] [R] 正在打开数据连接 IP: 192.168.217.135 端口: 51910
[11:27:55] [R] LIST -al
[11:27:55] [R] 150 Here comes the directory listing.
[11:27:55] [R] 226 Directory send OK.
cd进入目录
[11:29:01] [R] CWD Data
[11:29:01] [R] 250 Directory successfully changed.
[11:29:01] [R] PWD
[11:29:01] [R] 257 "/home/ubuntu/Data" is the current directory
[11:29:01] [R] PASV
[11:29:01] [R] 227 Entering Passive Mode (192,168,217,135,25,218).
[11:29:01] [R] 正在打开数据连接 IP: 192.168.217.135 端口: 6618
[11:29:01] [R] LIST -al
[11:29:01] [R] 150 Here comes the directory listing.
[11:29:01] [R] 226 Directory send OK.
[11:29:01] [R] 列表完成: 847 字节 耗时 0.02 秒 (0.8 KB/s)
mkdir 创建目录
[11:29:14] [R] MKD dir
[11:29:14] [R] 257 "/home/ubuntu/Data/dir" created
rmdir 删除空目录
[11:29:24] [R] RMD dir
[11:29:24] [R] 250 Remove directory operation successful.
get 下载文件 a.out
[11:29:52] [R] TYPE I
[11:29:52] [R] 200 Switching to Binary mode.
[11:29:52] [R] SIZE a.out
[11:29:52] [R] 213 12700
[11:29:52] [R] MDTM a.out
[11:29:52] [R] 213 20220822114225
[11:29:52] [R] PASV
[11:29:52] [R] 227 Entering Passive Mode (192,168,217,135,171,225).
[11:29:52] [R] 正在打开数据连接 IP: 192.168.217.135 端口: 44001
[11:29:52] [R] RETR a.out
[11:29:52] [R] 150 Opening BINARY mode data connection for a.out (12700 bytes).
[11:29:52] [R] 226 Transfer complete.
put上传文件lf.c
[11:30:09] [R] SIZE lf.c
[11:30:09] [R] 550 Could not get file size.
[11:30:09] [R] PASV
[11:30:09] [R] 227 Entering Passive Mode (192,168,217,135,76,34).
[11:30:09] [R] 正在打开数据连接 IP: 192.168.217.135 端口: 19490
[11:30:09] [R] STOR lf.c
[11:30:09] [R] 150 Ok to send data.
[11:30:09] [R] 226 Transfer complete.
[11:30:09] 上载: lf.c 182 字节 耗时 0.02 秒 (0.2 KB/s)
#ifndef FTPC_H
#define FTPC_H
//显示当前目录
void show_pwd(int sock,char* buf);
//创建空目录
void mk_dir(int sock,char* buf);
//删除空目录
void rm_dir(int sock,char* buf);
//进入目录
void cd_dir(int sock,char* buf);
//显示目录详细信息
void ls_dir(int sock,char* buf);
//上传
void up_file(int sock,char* buf);
//下载
void down_file(int sock,char* buf);
//退出
void quit_ftp(int sock);
#endif//FTPC_H
#include "ftpC.h"
#include "tools.h"
//显示当前目录
void show_pwd(int sock,char* buf)
{
sprintf(buf,"PWD\n");
send(sock,buf,strlen(buf),0);
if(!num_judge(sock,257))
printf("工作路径打开失败\n");
return;
}
//创建空目录
void mk_dir(int sock,char* buf)
{
char dir[256]={};
sscanf(buf,"mkdir %s",dir);
sprintf(buf,"MKD %s\n",dir);
send(sock,buf,strlen(buf),0);
if(!num_judge(sock,257))
printf("目录创建失败\n");
return;
}
//删除空目录
void rm_dir(int sock,char* buf)
{
char dir[256]={};
sscanf(buf,"rmdir %s",dir);
sprintf(buf,"RMD %s\n",dir);
send(sock,buf,strlen(buf),0);
if(!num_judge(sock,250))
printf("目录删除失败\n");
return;
}
//进入目录
void cd_dir(int sock,char* buf)
{
char dir[256]={};
sscanf(buf,"cd %s",dir);
sprintf(buf,"CWD %s\n",dir);
send(sock,buf,strlen(buf),0);
if(!num_judge(sock,250))
{
printf("目录进入失败\n");
return;
}
show_pwd(sock,buf);
ls_dir(sock,buf);
}
//显示目录详细信息
void ls_dir(int sock,char* buf)
{
int pasv_sock = open_data(sock);
if(0 > pasv_sock)
return;
sprintf(buf,"LIST -al\n");
send(sock,buf,strlen(buf),0);
if(!num_judge(sock,150))
return;
while(read(pasv_sock,buf,4096))
{
printf("%s",buf);
stdin->_IO_read_ptr = stdin->_IO_read_end;
}
if(!num_judge(sock,226));
return;
close(pasv_sock);
}
//上传
void up_file(int sock,char* buf)
{
int pasv_sock = open_data(sock);
char file[256]={};
sscanf(buf,"put %s",file);
sprintf(buf,"STOR %s\n",file);
send(sock,buf,strlen(buf),0);
int fd = open(file,O_RDONLY);
if(0 > fd)
{
close(pasv_sock);
printf("文件不存在,请检查!\n");
return;
}
int ret = 0;
while((ret = read(fd,buf,4096)))
{
send(pasv_sock,buf,ret,0);
}
close(fd);
close(pasv_sock);
bzero(buf,4096);
if(!num_judge(sock,150))
return;
bzero(buf,4096);
if(!num_judge(sock,226))
return;
printf("文件上传成功!\n");
}
//下载
void down_file(int sock,char* buf)
{
}
//退出
void quit_ftp(int sock)
{
close(sock);
}
#ifndef TOOLS_H
#define TOOLS_H
#include <stdbool.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <getch.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
typedef struct sockaddr* SP;
struct sockaddr_in svr_addr;
char Argv[20];
//数字判断
bool num_judge(int sock,int num);
//密码隐藏
void secretword(char keye[]);
//登陆
int login_ftp(const char* argv);
//打开数据通道
int open_data(int sock);
#endif//TOOLS_H
#include "tools.h"
//数字判断
bool num_judge(int sock,int num)
{
char buf[256]={};
int ret = 0;
recv(sock,buf,sizeof(buf),0);
printf("%s",buf);
sscanf(buf,"%d",&ret);
if(num != ret)
return false;
return true;
}
//密码隐藏
void secretword(char keye[])
{
stdin->_IO_read_ptr = stdin->_IO_read_end;
unsigned char c;
int i=0;//记录输入密码的个数
while((c=getch())!='\n')//按下回车退出循环,否则获取键值
{
if(i<20 && isprint(c)) //判断密码是否小于20位并检查所传的字符是否可以打印
{
keye[i]=c;//密码一个一个存入数组
i++;
putchar('*');//打印一个*
}
else if(i>0 && c==127) //判断密码是否大于0位并按下删除键
{
i--;//密码个数减1
putchar('\b'); //向前移动一位
putchar(' '); //打印空格
putchar('\b'); //再向前移动一位
}
}
printf("\n");
keye[i]='\0'; //最后输入'\0'
}
//登陆
int login_ftp(const char* argv)
{
int cmd_sock = socket(AF_INET,SOCK_STREAM,0);
if(0 > cmd_sock)
return -1;
svr_addr.sin_family = AF_INET;
svr_addr.sin_port = htons(21);
svr_addr.sin_addr.s_addr = inet_addr(argv);
socklen_t addrlen = sizeof(svr_addr);
if(connect(cmd_sock,(SP)&svr_addr,addrlen))
return -1;
char buf[255] = {};
if(!num_judge(cmd_sock,220))
return -1;
char name[20] = {};
printf("请输入用户名:");
scanf("%s",name);
sprintf(buf,"USER %s\n",name);
send(cmd_sock,buf,strlen(buf),0);
if(!num_judge(cmd_sock,331))
return -1;
char pass[20] = {};
printf("请输入密码:");
secretword(pass);
sprintf(buf,"PASS %s\n",pass);
send(cmd_sock,buf,strlen(buf),0);
if(!num_judge(cmd_sock,230))
return -1;
return cmd_sock;
}
//打开数据通道
int open_data(int sock)
{
unsigned char ip1,ip2,ip3,ip4,port1,port2;
char buf[256]={};
int ret = 0;
sprintf(buf,"PASV\n");
send(sock,buf,strlen(buf),0);
recv(sock,buf,sizeof(buf),0);
sscanf(buf,"%d",&ret);
if(227 != ret)
return -1;
sscanf(buf,"227 Entering Passive Mode (%hhu,%hhu,%hhu,%hhu,%hhu,%hhu)",&ip1,&ip2,&ip3,&ip4,&port1,&port2);
char ip[16] = {};
sprintf(ip,"%hhu.%hhu.%hhu.%hhu",ip1,ip2,ip3,ip4);
unsigned short port = port1*256+port2;
printf("%s\n%hu\n",buf,port);
int pasv_sock = socket(AF_INET,SOCK_STREAM,0);
if(0 > pasv_sock)
return -1;
struct sockaddr_in pasv_addr = {};
pasv_addr.sin_family = AF_INET;
pasv_addr.sin_port = htons(port);
pasv_addr.sin_addr.s_addr = inet_addr(ip);
socklen_t addrlen = sizeof(pasv_addr);
if(connect(pasv_sock,(SP)&pasv_addr,addrlen))
{
printf("连接数据通道失败\n");
return -1;
}
return pasv_sock;
}
#include "ftpC.h"
#include "tools.h"
int main(int argc,const char* argv[])
{
strcpy(Argv,argv[1]);
int sock = login_ftp(Argv);
if(0 > sock)
{
printf("登陆失败\n");
return 0;
}
printf("登陆成功\n");
char buf[4096] = {};
size_t buf_size = sizeof(buf);
while((scanf("%[^\n]%*c",buf) || 1) && strcmp(buf,"quit") && strcmp(buf,"bye"))
{
if(!strncmp(buf,"pwd",3))
show_pwd(sock,buf);
else if(!strncmp(buf,"mkdir ",6))
mk_dir(sock,buf);
else if(!strncmp(buf,"rmdir ",6))
rm_dir(sock,buf);
else if(!strncmp(buf,"cd ",3))
cd_dir(sock,buf);
else if(!strncmp(buf,"ls ",3))
ls_dir(sock,buf);
else if(!strncmp(buf,"put ",4))
up_file(sock,buf);
else if(!strncmp(buf,"get ",4))
down_file(sock,buf);
else
{
printf("非法命令\n");
stdin->_IO_read_ptr = stdin->_IO_read_end;
}
bzero(buf,buf_size);
}
quit_ftp(sock);
}