📄 myftpserver.c
字号:
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<errno.h>
#include<string.h>
#include<pthread.h>
#include<dirent.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#define BACKLOG 5
#define ASSCI 0
#define BIN 1
#define SPEED 512
#define SUC_FLAG "USER Certification Successed!"
#define FAIL_FLAG "USER Certification Failed!"
#define data_len 1024;
#define cmd_len 50;
#define mput_limit 10;
#define mget_limit 10;
//请更新用户/密码表的路径
//********************************************************
#define PASSWORD "/home/young/桌面/ftp/ftpserver/password.c"
//********************************************************
int pswd_fd;
FILE *ps_file;
void lpwd(int dataSocketFd);
void lmkdir(int dataSocketFd,char *dirName);
void lrmdir(int dataSocketFd,char *dirName);
void ldir(int dataSocketFd);
void lcd(int dataSocketFd,char *dirName);
int getUpDir(char *currentDirPath) ;//获得当前目录的上一级目录
struct sockaddr_in make_localaddr(short int ,long int);
int init_server(short int ,long int);
int checkclient(int,int);
int download_server2client(int clientfd,char *filename,int download_type);
int put_client2server(int clientfd,char *filename,int type);
void client_op(int,int);
void server_op(void *arg);
//****
struct clientinfo{ // 登录信息
char name[10];
char passwd[6];
};
struct arg_info {
int arg_mount;
char *arg_array[512];
};
struct positv_client{// 记录当前活动用户名
char name[20];
struct positv_client *next;
};
struct fd_struct { // 套接字
int client_fd;
int data_fd;
};
struct usr_info { // 用户信息
char usrname[20];
char psword[20];
};
// 用户文件中的所有人员信息
struct usr_info ALL_USERS[512] = {
{"abcc","ddd"}
};
// 当前活动人员信息
struct usr_info POSITIVE_USERS[512] = {
};
//****
// 全局变量
char comstr[100];
char testlink[12];
int infosockfd,datasockfd,op_clientfd,all_cltnum,positv_cltnum,_current;
int count_all;
char help[]="\t**************************************\n\t*count current --显示当前活动用户数*\n\t*count all --显示系统访客总数 *\n\t*list--显示当前在线用户列表 *\n\t*quit--退出服务器 *\n\t**************************************\n";;
pthread_mutex_t mutex;
pthread_t client_pthread[BACKLOG]; // 最大线程数
int main(int argc,char *argv[]){ //argv[1]为端口号argv[2]为IP
init_envi();
// 创建客户会话线程
struct arg_info arg_inf={
0,{""}
};
pthread_t server_pd;
arg_inf.arg_mount = argc;
int i = 0;
char main_cmd[128] = {""};
for (; i< argc; i++) {
//memset(arg_inf.arg_array[i],'\0',sizeof(arg_inf.arg_array[i]));
arg_inf.arg_array[i]=argv[i];
}
pthread_create(&server_pd,0,(void *)&main_operation,(void *)&arg_inf);//客户线程创建
pthread_detach(server_pd);//分离的
printf("\t\tmyftp server\n");
printf("%s",help);
printf("myserver>");
fgets(main_cmd,sizeof(main_cmd),stdin);
while (strcmp(main_cmd,"quit\n")) {
if(!strcmp(main_cmd,"count current\n"))
printf("当前活动用户数 :%d\n",_current);
if(!strcmp(main_cmd,"count all\n"))
printf("系统访客总数 :%d\n",count_all);
if (!strcmp(main_cmd,"list\n")) {
printf("当前活动用户 :\n");
int k = 0;
for (;k<_current; k++ ) {
printf("第%d号用户:%s\n",k+1,POSITIVE_USERS[k].usrname);
}
}
else
printf("请输入正确指令!\n");
printf("myserver>");
fgets(main_cmd,sizeof(main_cmd),stdin);
}
}
int main_operation(void *arg) {
sleep(1);
struct arg_info *arg_inf;
arg_inf = (struct arg_info *)arg;
pthread_mutex_init(&mutex,NULL);
int i=0;
if((*arg_inf).arg_mount == 1 || (*arg_inf).arg_mount >3){ // 输入错误
perror("start failed.\n");
return -1;
}else if((*arg_inf).arg_mount == 2){ // 只输入端口
short int *port;
port = (short int *)((*arg_inf).arg_array[1]);
infosockfd = init_server(*port,0);
short int dataport;
dataport = *port + 1;
datasockfd = init_server(dataport,0);
if(infosockfd == -1){
perror("server init failed.\n");
return -1;
} else if(infosockfd != -1){
op_clientfd = checkclient(infosockfd,datasockfd);
return 0;
}
} else if((*arg_inf).arg_mount == 3){
short int *port;
long int ip;
port = (short int *) ((*arg_inf).arg_array[1]);
ip = inet_addr(((*arg_inf).arg_array[2])); //把字符串转换为IP格式
infosockfd = init_server(*port,ip);
short int dataport;
dataport = *port + 1;
datasockfd = init_server(dataport,ip);
if(infosockfd == -1){
perror("server init failed.\n");
return -1;
} else if(infosockfd != -1){
op_clientfd = checkclient(infosockfd,datasockfd);
return 0;
}
}
}
int init_envi(){
int pswd_lenth = 0;
ps_file = fopen(PASSWORD,"rb");
lseek(pswd_fd,0,SEEK_SET);// //置读写指针到文件头
pswd_fd = fileno(ps_file);
pswd_lenth = lseek(pswd_fd,0,SEEK_END);//获取文件长度
lseek(pswd_fd,0,SEEK_SET);
int i=0;int j=0; // j=0 当前读到的是名字,j=1 当前读到的是密码
int _ui,_pi; _ui=0; _pi=0;
char ch[512]="a";
char par[512]="";char _usrname[512]=""; char _psword[512]="";
while (i<pswd_lenth) {
read(pswd_fd,ch,1);
if (!strcmp(ch,",")) { // 读名字结束
_ui = 0;
j = 1;
} else if (!strcmp(ch, ";")) { // 读密码结束
_pi = 0;
j = 0;
strcpy(ALL_USERS[all_cltnum].usrname,_usrname);
strcpy(ALL_USERS[all_cltnum].psword,_psword);
memset(_usrname,'\0',sizeof(_usrname));
memset(_psword,'\0',sizeof(_psword));
all_cltnum++;
} else {
if ( j == 0) {
_usrname[_ui++] = ch[0];
} else {
_psword[_pi++] = ch[0];
}
}
i++;
}//while_end
//memset(ALL_USERS[all_cltnum++].usrname,'\0',sizeof(ALL_USERS[all_cltnum].usrname));
//memset(ALL_USERS[all_cltnum++].psword,'\0',sizeof(ALL_USERS[all_cltnum].psword));
strcpy(ALL_USERS[all_cltnum].usrname,_usrname);
strcpy(ALL_USERS[all_cltnum].psword,_psword);
ALL_USERS[all_cltnum].psword[strlen(ALL_USERS[all_cltnum].psword)-1] = '\0';
all_cltnum++;
}
int init_server(short int port,long int ip){
int _sockfd;
struct sockaddr_in localaddr;
_sockfd = socket(AF_INET,SOCK_STREAM,0);
if(_sockfd == -1 ){
printf("\nsock creat error.\n");
return -1;
}
localaddr = make_localaddr(port,ip);//设置本地地址和端口
if(bind(_sockfd,(struct sockaddr *)&localaddr,sizeof(localaddr)) == -1){//绑定地址及端口
printf("\nbind() error.\n");
return -1;
}
if((listen(_sockfd,BACKLOG)) == -1){//最大等待5个客户
printf("\nlisten() error.\n");
return -1;
}
return _sockfd;
}
void client_op(int clientfd,int datafd){//服务函数
struct fd_struct fd_st={0,0};
fd_st.client_fd = clientfd;
fd_st.data_fd = datafd;
//pthread_mutex_lock(&mutex);
pthread_create(&client_pthread[positv_cltnum],0,(void *)&server_op,(void *)&fd_st);//客户线程创建
//pthread_detach(client_pthread[positv_cltnum]);//分离的
//pthread_mutex_unlock(&mutex);
}
//设置IP和端口
struct sockaddr_in make_localaddr(short int port,long int ip){
struct sockaddr_in localaddr;
memset(localaddr.sin_zero,'\0',sizeof(localaddr.sin_zero));
localaddr.sin_family = AF_INET;
localaddr.sin_port =port;
if(ip == 0){
localaddr.sin_addr.s_addr = INADDR_ANY;//未输入IP,用默认
}
else if(ip != 0){
localaddr.sin_addr.s_addr = ip;//转为网络字节顺序
}
return localaddr;
}
void server_op(void *arg){//服务函数
struct fd_struct *fd_st;
fd_st = (struct fd_struct *)arg;
int cmd_arg_mount=0; // 记录命令参数个数
char dealmessage[200]=""; // 存储处理结果
char *cmd_arg_array[512]={""}; // 存放命令及参数
char currentDirPath[200] = ""; // 存放当前路径
int i = 0;
int _clientfd = 0;
int _datasockfd = 0;
int dataclient_addrlen;
struct sockaddr_in dataclient_addr;
dataclient_addrlen = sizeof(dataclient_addr);
_clientfd = (*fd_st).client_fd;
_datasockfd = (*fd_st).data_fd;
int datafd;
datafd = accept(_datasockfd,(struct sockaddr *)&dataclient_addr,&dataclient_addrlen);
int flag = 1;int flag2=1;
// 用户验证
char client_msg[512]="";
read(_clientfd,client_msg,512);
int iii = 0;
if (!(iii=checkpassword(client_msg))) { // 没有通过验证
write(datafd,FAIL_FLAG,512);
// 错误处理.
close(datafd);
pthread_exit(0);
}
write(datafd,SUC_FLAG,512);
_current++;count_all++;
// 读操作
while(flag){
flag2= 0;
int __current,_all_cltnum ;
__current = _current;
_all_cltnum = all_cltnum;
memset(comstr,'\0',sizeof(comstr));
read(_clientfd,comstr,512);
// 为什么read后_current会被冲掉?
_current = __current;
all_cltnum = _all_cltnum;
if (!strcmp(comstr,"quit")){
flag=0;
_current--;
}
// 解析命令
cmd_arg_mount=get_argc_argv(comstr,cmd_arg_array);
// 处理命令
if (cmd_arg_mount) {
if (!strcmp(cmd_arg_array[0],"lmkdir")) {
int i;flag2 =1;
//printf("get command lmkdir!\n");
if(cmd_arg_mount > 2){
for(i = 1;i < cmd_arg_mount;i++)
lmkdir(datafd,cmd_arg_array[i]);
}
if(cmd_arg_mount == 2)
lmkdir(datafd,cmd_arg_array[1]);
if(cmd_arg_mount == 1){
write(datafd,"need filename..",15);
}
//printf("lmkdir done!\n");
}
if (!strcmp(cmd_arg_array[0],"lrmdir")) {
int i;flag2 =1;
//printf("get command lrmdir!\n");
if(cmd_arg_mount > 2){
for(i = 1;i < cmd_arg_mount;i++)
lrmdir(datafd,cmd_arg_array[i]);
}
if(cmd_arg_mount == 2)
lrmdir(datafd,cmd_arg_array[1]);
if(cmd_arg_mount == 1)
write(datafd,"need filename..",15);
//printf("lrmdir done!\n");
}
if (!strcmp(cmd_arg_array[0],"lpwd")) {
//printf("get command lpwd!\n");
flag2 =1;
if(cmd_arg_mount > 1)
write(datafd,"type error!",11);
else
lpwd(datafd);
//printf("lpwd done!");
}
if (!strcmp(cmd_arg_array[0],"lcd")) {
///printf("get command lcd!\n");
flag2 =1;
if(cmd_arg_mount == 2)
lcd(datafd,cmd_arg_array[1]);
else
write(datafd,"type error!",11);
//printf("lcd done!\n");
}
if (!strcmp(cmd_arg_array[0],"ls")) {
//printf("get command ls\n");
flag2 =1;
if(cmd_arg_mount == 1)
ldir(datafd);
else
write(datafd,"typeflag =0; error!",11);
///printf("ls done!\n");
}
// put
if(!strcmp(cmd_arg_array[0],"put")){
//printf("get command put\n");
flag2 =1;
if(cmd_arg_mount == 2){
put_client2server(datafd,cmd_arg_array[1],0);
write(datafd,"get over!",9);
}
if(cmd_arg_mount ==3){
if(!strcmp(cmd_arg_array[2],"assci")||!strcmp(cmd_arg_array[2],"ASSCI") ){
put_client2server(datafd,cmd_arg_array[1],0);
write(datafd,"get over!",9);
}
else if(!strcmp(cmd_arg_array[2],"bin")||!strcmp(cmd_arg_array[2],"BIN") ){
put_client2server(datafd,cmd_arg_array[1],1);
write(datafd,"get over!",9);
}
}
else write(datafd,"enter error!",12);
}
// get
if(!strcmp(cmd_arg_array[0],"get")){
//printf("get command put\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -