#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <linux/un.h>
#include <sys/select.h>
#include <sys/time.h>
#include <pthread.h>
#include <poll.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include "ftp.h"
/*
功能:打印文件名
参数:
get_filename:文件名数组首地址
n:文件名个数
*/
void printf_filename(char get_filename[1024][1080],int n)
{
for(int i = 0;i<n;i++)
{
printf("%s\n",get_filename[i]);
}
}
/*
报头内容如下:
char buf[];
buf[0] = 0 =>普通数据
buf[0] = 1 =>文件名数据
buf[0] = 2 =>文件内容数据
buf[0] = 3 =>文件夹内容数据
buf[1] = 0 => 如果buf[0] = 2 且buf[1] = 0 =>表示文件
内容未传输完备,否则就是传输完毕 buf[1] = 1
buf[2] = len(short) & 0x00ff
buf[3] = len >> 8
//表示数据的长度
//数据的长度 => unsigned short类型 => 2个字节
//把两个字节,分开放到 char数组的两个元素中
//假设 0x1234 => buf[2] = 0x34,buf[3] = 0x12
// 0x1234 & 0x00ff = buf[2] = 0x34
// 0x1234 >> 8 => 0x12 = buf[3]
*/
/*
sockfd:表示客户端的套接字
buf:表示内容数据
*/
void send_data(int sockfd,unsigned char* buf,char type,char flag,unsigned short len)
{
//1.把报头添加到内容数据的前面,我强行限制buf最长1024
char s_buf[1080] = {0};
strcpy(s_buf+4,buf);
//2.填入报头数据
s_buf[0] = (int)type+'0';
s_buf[1] = (int)flag+'0';
s_buf[2] = len & 0xff;
s_buf[3] = len >> 8;
write(sockfd,s_buf,4+len);
if(len == 0)
{
puts("send success");
}
//假设 type = 0 =>普通数据,strlen遇到0就结束了,怎么玩下去..
}
/*
功能:发送文件
*/
void send_file(int sockfd,char *filename)
{
unsigned short len = strlen(filename);
send_data(sockfd,filename,1,0,len);
sleep(1);
int fd = open(filename,O_RDONLY);//打开文件 发送内容
if(fd == -1)
{
perror("open file error");
return ;
}
while(1)
{
char buf[1024]={0};
int r = read(fd,buf,1024);
if(r == 0)
{
break;
}
send_data(sockfd,buf,2,0,r);//发送内容给服务器
}
send_data(sockfd,"q",2,1,0); //发送完毕信号
close(fd);//关闭文件
}
/*
func:查看当前目录下的文件
argc:文件名
返回值:返回文件个数
*/
int file_ls(char *filename , char get_filename[1024][1080])
{
//1.打开目录流
DIR *dirp = opendir(filename);
if(dirp == NULL)
{
perror("opendir err");
return -1;
}
//2.读取目录流 打印文件名
struct dirent *d0;//定义结构体接收目录流信息
int count = 0,n=0;
while(1)
{
d0 = readdir(dirp);//读取
if(d0 == NULL)//读完结束
{
printf("\n");
break;
}
//排除. ..目录
if(strcmp(d0->d_name,".")&&strcmp(d0->d_name,".."))
{
strcpy(get_filename[n++],d0->d_name);
}
}
closedir(dirp);//关闭目录流
return n;
}
/*
功能:获取服务器目录下所有文件名
参数:套接字
*/
void get_server_ls(int sockfd)
{
int n=0;
char get_filename[1024][1080]={0};
char buf[10]={0};
write(sockfd,"2",1);
while(1)
{
int r = read(sockfd,buf,4);
if(r<=0 || buf[1] == '1') //发送端暴毙 或 发送数据完毕
{
break;
}
unsigned short len = buf[2] | buf[3]; //获得内容长度
r = read(sockfd,get_filename[n++],len); //读取内容
if(r<=0)
{
break;
}
}
printf_filename(get_filename,n);
}
/*
功能:发送获取到的目录下文件名
*/
void send_ls(int sockfd)
{
char get_filename[1024][1080]={0};
int n=file_ls("./",get_filename);
for(int i = 0;i<n;i++)
{
unsigned short len = strlen(get_filename[i]);
send_data(sockfd,get_filename[i],0,0,len);
}
send_data(sockfd,"q",0,1,0);
}
/*
func:发送文件
*/
void server_send_file(int sockfd)
{
while(1)
{
char filename[128]={0};
int r = read(sockfd,filename,128);
if(filename[0] == '@')
{
break;
}
puts(filename);
unsigned short len = strlen(filename);
send_data(sockfd,filename,1,0,len);
int fd=open(filename,O_RDONLY);//打开文件 发送内容
if(fd==-1)
{
perror("open file error");
continue;
}
while(1)
{
char buf[1024] = {0};
int r = read(fd,buf,1024);//从文件中读取数据
if(r == 0)
{
break;
}
send_data(sockfd,buf,2,0,r);//发送内容给服务器
}
usleep(50000);
send_data(sockfd,"q",2,1,0);//发送完毕信号
usleep(50000);
send_data(sockfd,"q",0,1,0);
close(fd);//关闭文件
}
}
/*
func:接收文件
*/
void recv_file(int sockfd)
{
while(1)
{
char buf[10]={0};
int r = read(sockfd,buf,4);//接收报头信息
printf("buf[0] = %c,buf[1] = %c\n",buf[0],buf[1]);
if(r<=0)
{
break;
}
unsigned short len = buf[2] | buf[3]<<8;
if(len == 0)//为0 跳转到下方 不接收数据
{
goto loop;
}
char filedata[1080]={0};
r = read(sockfd,filedata,len);//接收数据内容
if(r<=0)//发送端暴毙
{
break;
}
int fd;
loop:
switch(buf[0])//判断数据类型
{
case '0'://普通数据
{
if(buf[1] == '1')
{
puts("结束");
return ;
}
puts(filedata);
break;
}
case '1'://文件名数据
{
fd = open(filedata , O_WRONLY | O_CREAT,0666);
if(fd == -1)
{
perror("error");//玩不动
while(1)//既然不能同名,那么允许我输入一个可好?
{
char filename[1024] = {0};
puts("please input filename");
scanf("%s",filename);
fd = open(filename,O_WRONLY | O_CREAT,0666);
if(fd > 0)
{
break;
}
}
}
break;
}
case '2'://文件内容数据
{
if(buf[1] == '1')
{
puts("close success");
close(fd);
}
else
{
write(fd,filedata,r);
}
break;
}
}
}
}
评论0