FTP客户端
项目准备:在ubuntu系统上搭建FTP服务器
搭建ftp服务器:
1、sudo apt-get install vsftpd
2、sudo vi /etc/vsftpd.conf 打开配置文件
anonymous_enable=NO 禁止匿名用户登录
local_enable=YES 开户本地用户登录
write_enable=YES 开户上传权限
2、service vsftpd restart 重启ftp服务器
3、使用FlashFXP与FTP服务器通信,查看通信过程,解析协议
注意:
1、发送给服务端的指令以\n结尾。
2、端口号是 21 链接它后只用于传输指令,和接收指令执行结果
3、发送大量数据时,重新建立一个链接,专门用于传输数据
4、其中涉及到断点重传,利用时间戳和文件大小进行判断是否是同一个文件,是否完成,是否覆盖
1、编写makefile 文件
CC=gcc
STD=-std=gnu99
FLAG=-Wall -Werror
OBJS=main.o ftp_client.o tools.o
TARGE=ftp
all:$(OBJS)
$(CC) $(OBJS) -o $(TARGE) && ./$(TARGE) 127.0.0.1
%.o:%.c
$(CC) $(FLAG) $(STD) -c $< -o $@
clean:
rm -rf $(OBJS) $(TARGE)
rm -rf *.h.gch
2、ftp_client.h
#ifndef FTP_CLIENT_H
#define FTP_CLIENT_H
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <limits.h>
#define BUF_SIZE (100)
typedef struct sockaddr* SP;
typedef struct FTPClient
{
char* buf; //缓冲区
int sock_fd;//命令通道
int data_fd;//数据通道
int file_fd;//文件描述符
char file_name[PATH_MAX];//文件名
char client_path[PATH_MAX];//客户端地址
char server_path[PATH_MAX];//服务端地址
char client_mdtm[15];//客户端最后修改时间
char server_mdtm[15];//服务端最后修改时间
size_t server_size;//服务端大小
size_t client_size;//客户端大小
bool is_put;//是否在上传
bool is_get;//是否在下载
}FTPClient;
FTPClient* create_FTPClient(void); //创建ftp文件
void destroy_FTPClient(FTPClient* ftp); //销毁ftp
int connect_FTPClient(FTPClient* ftp,const char* ip,short port); //建立连接
void send_FTPClient(FTPClient* ftp); //发送
int recv_FTPClient(FTPClient* ftp,int check);//接收
int user_FTPClient(FTPClient* ftp,const char* user);//填写账户
int pass_FTPClient(FTPClient* ftp,const char* pass);//填写密码
void cwd_FTPClient(FTPClient* ftp,const char* path);//指令cwd
void pwd_FTPClient(FTPClient* ftp);//指令pwd
void bye_FTPClient(FTPClient* ftp);//指令quit
int pasv_FTPClient(FTPClient* ftp);//指令pasv
void list_FTPClient(FTPClient* ftp);//指令listen
void put_FTPClient(FTPClient* ftp,const char* file);//上传
void get_FTPClient(FTPClient* ftp,const char* file);//下载
#endif//FTP_CLIENT_H
3、tcp_client.c
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "ftp_client.h"
#include "tools.h"
FTPClient* create_FTPClient(void)
{
FTPClient* ftp = malloc(sizeof(FTPClient));
ftp->sock_fd = socket(AF_INET,SOCK_STREAM,0);
if(0 > ftp->sock_fd)
{
free(ftp);
ERROR("socket");
return NULL;
}
ftp->buf = malloc(BUF_SIZE);
return ftp;
}
void destroy_FTPClient(FTPClient* ftp)
{
close(ftp->sock_fd);
close(ftp->data_fd);
free(ftp->buf);
free(ftp);
}
static int connect_server(int sock,const char* ip,short port)
{
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(ip);
if(connect(sock,(SP)&addr,sizeof(addr)))
{
ERROR("connect");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int connect_FTPClient(FTPClient* ftp,const char* ip,short port)
{
if(connect_server(ftp->sock_fd,ip