admin 管理员组

文章数量: 887016

目录

主体功能

程序使用方法

1、运行客户端​编辑

2、运行服务器

3、登录

4、注册

5、程序命令解析

6、传输文件(上传--cp、下载--lcp)

具体代码

服务器

services.c(main 函数)

sqlite.c(数据库相关模块)

demo.c(服务器与客户端交互相关模块)

demo.h

sqlite.h

makefile

客户端

client.c(main函数)

demo.c(与服务器交互相关模块)

pathread.c(线程模块,实现恢复暂停下载)

sqlite.c(登录与注册--客户端)

demo.h

pthread.h

sqlite.h

makefile


主体功能

程序总体分两部分,客户端与服务器。
1、支持上传(cp)、下载(lcp)除根目录文件任意大小的文件
2、支持多客户端连接服务器下载、上传文件
3、支持文件下载、上传的暂停与恢复
4、自动检测输入的格式,超过次数程序自动退出。
5、支持切换远程服务器(lcd)、本地客户端(cd)工作目录,以及查看目录文件(lls、ls)和当前工作目录(lpwd,pwd)。

程序使用方法

1、客户端与服务器都可以直接使用make命令编译后运行
2、客户端运行时需要输入,服务器的ip地址与端口号

1、运行服务器

 服务器运行后,属于待机状态,等待服务器连接后交互信息。

2、运行客户端

运行客户端需要输入,客户端的ip地址与端口号。(程序仅支持同一网段下的客户端与服务器交互)。

3、登录

客户端运行后,可以选择登录与注册。服务器在运行之初会自动创建4个VIP用户。可以使用VIP用户直接登录。
2345678  66666666
7654321  8888888 
654321   888888
54321    88888

4、注册

 登录注册时,输入需要按照格式输入,否则到达次数。程序自动退出。

5、程序命令解析

客户端命令:
    ls:查看当期客户端,当期目录文件
    cd:切换当前客户端目录
    pwd:查看当前绝对路径
    cp :上传文件,格式: cp  【当前文件路径】【待上传文件名】  【目的文件路径】【目的文件名】
                        cp ./file1   ./file1
                
    lcp:下载文件,格式: lcp  【远程文件路径】【远程文件名】  【目的文件路径】【目的文件名】
                        lcp ./file1 ./file1
    ***除开目的文件名不能与所传路径下的文件重名外,所有的路径(除根目录)与文件名都可以根据自己意愿确定。
    ***程序会检测文件是否存在,是否重名,是否为空文件,并反馈信息。
    lls:查看服务器当前目录文件
    lpwd:产看服务器当前工作路径
    lcd:切换服务器工作目录
    quit:客户端退出
    lcp:

服务器命令:
    CTRL+c:退出服务器,并自动删除数据库。所有账户信息清零。

6、传输文件(上传--cp、下载--lcp)

程序具备恢复与暂停功能,在上传或下载过程中。输入‘1’表示暂停下载、上传。输入‘2’表示恢复下载、上传。

具体代码

服务器

services.c(main 函数)

int fid = 0;

#include"sqlite.h"
int main(int argc, char* argv[])
{
	int type = 0;
	int fd1,pid,ret;
	int fid = init_socket();
	if(fid < 0)
	{
		printf("init_socket failed.\n");
		return -1;
	}

	signal(SIGCHLD,handler);//捕捉自进程信号,进行处理 
	signal(SIGINT,handler);//捕捉自进程信号,进行处理 

	sqlite3 *db;
	if(init_vip(&db) == -1)//先创建两个用户
	{
		printf("failed\n");
		close(fd1);
		system("rm ./jkl.db");
		exit(-1);
	}


	while(1)
	{
		fd1 = accept_client(fid);//等待客户端接入
		if(fd1 == -1)
		{
			close(fid);
			return -1;
		}

		pid = fork();
		if(pid  == -1)
		{
			perror("fork:");
		}else if(pid == 0 )//子进程和接入客户端交互
		{

			ret = usr_into_system(fd1,&db);//客户端登陆、注册
			if(-1 == ret )

			{
				close(fd1);
				exit(-1);

			}else if(ret == 13 )
			{
				printf("客户端登陆成功 \n");
			}	

			information_from_client(&type,fd1);//循环检测客户端输入
			exit(0);
		}

	}
	close(fid);
	exit(0);
	return 0;
}

sqlite.c(数据库相关模块)

#include"sqlite.h"

extern int vip;
int init_vip(sqlite3 **db1)//初始化数据库,创建一张表,表中两个vip
{
	char sql[100] = {0};
	
	if(init_seqlite("./jkl.db",db1) == -1) 
		return -1;
	strcpy(sql,"create table student(vip integer, log text, password text);");
	if(init_usr(*db1,sql) == -1)
		return -1;
	strcpy(sql,"insert into student values(1 , '2345678', '66666666');");
	if(init_usr(*db1,sql) == -1)
		return -1;
	strcpy(sql,"insert into student values(1 , '7654321', '8888888');");
	if(init_usr(*db1,sql) == -1)
		return -1;
	strcpy(sql,"insert into student values(1 , '654321', '888888');");
	if(init_usr(*db1,sql) == -1)
		return -1;
	strcpy(sql,"insert into student values(1 , '54321', '88888');");
	if(init_usr(*db1,sql) == -1)
		return -1;
	return 0;
}

int init_seqlite(char*r,sqlite3 ** db)//创建一张表
{
	if(0 != sqlite3_open(r,db) )
	{
		perror("open");
		return -1;
	}
	return 0;
}

int init_usr(sqlite3* db,char* sql)//创建用户
{
	if(0 != sqlite3_exec( db,sql,NULL,NULL,NULL))
	{
		perror("exec");
		return -1;
	}
	return 0;
}

int usr_into_system(int fd, sqlite3 **db)//客户端登陆注册
{
	sqlite3 *db1 = *db;
	int a = 0;
	int ret1,ret2;
	struct msgdata msg;
	bzero(&msg,sizeof(msg));
	strcpy(msg.data,"输入 1(登陆) or 2(注册).");
	send(fd,&msg,sizeof(msg),0);//提醒客户端输入
				    //	printf("services put success: %s\n",msg.data);
	while(1)
	{
		bzero(msg.data,sizeof(msg.data));
		if( 0 == recv(fd,&msg,sizeof(msg),0))//接收客户端的输入
			break;
		//	printf("msg.type  =%d\n",msg.type);
		//vip = msg.j;
	
		int n =0 ;
		char buf1[50] ={0};
		char buf2[50] ={0};
		strcpy(buf1,msg.data);
		strcpy(buf2,strtok_str(buf1,0));
		strcpy(buf1,strtok_str(msg.data,1));

	//	printf("buf1:%s\n",buf1);//密码	
	//	printf("buf2:%s\n",buf2);//帐号	
		if(msg.type == 1)
		{
			msg.type = 0;

			int x=0,y=0;
			ret1 =select_data(db1,1,buf2,&x);
			ret2 =select_data(db1,2,buf1,&y);
			if( (ret1 == 1) && (ret2 == 1))
			{
				if(  ((x != 0) &&(y != 0) )  && (x == (y) - 1)  )
				{
				//	printf("x= %d  y =%d\n",x ,y);	
					msg.type = 1;
					send(fd,&msg,sizeof(msg),0);//告诉客户端登陆成功
					return 13;

				}else{
				msg.type = -1;
                                send(fd,&msg,sizeof(msg),0);
                                continue;
				
				}
			}else{
				msg.type = -1;
				send(fd,&msg,sizeof(msg),0);
				continue;
			}	

			/*

			   if( (select_data(db1,1,buf2) == 1) && (select_data(db1,2,buf1) == 1) )
			   {
			   msg.type = 1;
			   send(fd,&msg,sizeof(msg),0);//告诉客户端登陆成功
			   return 13;

			   }else{
			   msg.type = -1;
			   send(fd,&msg,sizeof(msg),0);
			   continue;
			   }
			   */		
		}else if(msg.type == 2)
		{
	//		printf("j = %d\n",msg.j);
			if(msg.j == 1)
			{
				vip = 1;
			}else if(msg.j == -1)
			{
				vip = 0;
			}

			if(add_usr_to_system(db1,buf2,buf1,&msg) == -1)
			{
				msg.type = -1;
				send(fd,&msg,sizeof(msg),0);
				continue;
			}else{
				msg.type = 1;
				send(fd,&msg,sizeof(msg),0);
				continue;
			}
		}else if(msg.type  ==-1)
		{
			printf("client quit.\n");
			return -1;	
		}
	}
	return 0;
}



int  select_data(sqlite3* db, int m,char* buf,int* x)
{
	int ret =0 ;
	char sql[50] = {0};
	char **result;
	int R, C;

	if(0 != sqlite3_get_table(db, "select *from student;", &result, &R, &C, NULL))
	{
		printf("select is default\n");
		return -1;
	}
	int i, j;

	 m = C +m;
	for(i = 0; i <R;i++ )
	{
//		printf("%s \n",result[m]);
//		printf("%d  buf = %d\n",strlen(result[m]),strlen(buf));
		ret = strcmp(result[m],buf) ;
//		printf("%d\n",ret);
		if((ret == 0) && (strlen(buf) == strlen(result[m])))//找到相同 数据
		{
	//		printf("this m result  %s    %d\n",result[m],strlen(result[m]));
	//		printf("this m buf  %s        %d\n",buf,strlen(buf));
			*x = m;
			return 1;
		}
		m +=3;
	}

	return 0;//没有找到相同数据
} 



int add_usr_to_system(sqlite3*db,char *buf2,char *buf1,struct msgdata* msg)//注册
{
	int x; 
	char sql[100] ={0};
//	printf("buf2 = %s\n",buf2);
	int ret = select_data(db,1,buf2,&x) ;

	if(ret == 1 )
	{
		strcpy(msg->data,"用户或已存在.");
		return -1;
	}else if(ret == -1)
	{
		return -1;
	}


	sprintf(sql,"insert into student values(%d , '%s', '%s');",msg->j,buf2,buf1);
	if(init_usr(db,sql) == -1)
		return -1;
	return 0;
}


demo.c(服务器与客户端交互相关模块)

#include"demo.h"
#include<pthread.h>
//extern int type;
int vip  =1;
int pthread_type = 2;
int type_pth = 2;

void * input(void*);
extern int fid;
int init_socket()//初始化套接字
{
	int fd = socket(AF_INET,SOCK_STREAM,0);
	if(-1 == fd)
	{
		perror("socket:");
		return -1;
	}else{
		printf("socket success.\n");
	}
	int on =1;
	if(setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))< 0)//设

本文标签: 文件传输 项目 系统 TCP