项目——校园贴吧平台

项目描述:

        使用场景:用于校园,方便学生的日常生活,促进学生交流。

        问题描述:设计一个互动平台程序,为学生提供便利,可以在平台上发布和咨询问题,丰富校园文化。

基本要求

  1. 实现客户端向服务器发消息。
  2. 实现客户端从服务器读消息。
  3. 实现并发服务器,支持多个客户端同时发布或者浏览文章。
  4. 服务器通过数据库保存发布文章记录(文章标题名称、发布人等)。
  5. 只支持浏览数据库记录中保存的文章(用户每发布一篇文章,便将文章标题保存在数据库中。浏览文章时,检查数据库中是否存在该文章标题,如果存在才能进入浏览,不存在返回不存在。)

项目模块划分

客户端

菜单界面(后续用Qt界面替换)
  • 文章发布:P#文章标题
  • 文章浏览:G#文章标题
  • 刷新页面:F#文章标题
  • 退出:Q
  • 删除标题:D#文件名

TCP客户端

  • 客户端进行注册用户才能进行操作。
  • 客户端注册成功连接到服务器,保持与服务器之间的连接。
  • 在客户端界面上输入退出序号4后,断开与服务器的连接并退出。

文章发布

  • 拼装协议头,发送给服务器,协议头格式:P#文章保存路径与每一个文章标题名,如:(P#../file/filename)
  • 接受服务器消息,进行解析,收到ERROER错误标志则代表该文章已存在数据库中结束发布操作,否则收到SUCCESS成功标志代表可以上传执行下一步。
  • 读取待发布的文章路径与文章标题名,将文章的内容发送给服务器,每次发送1024字节,直到读取完毕,此时文章发布完成。

文章浏览

  • 拼装协议头,发送给服务器,协议头格式:G#文件路径与文件名。
  • 接受服务器消息,进行解析,收到ERROER代表数据库中没有该文章名结束浏览,收到SUCCESS代表可以操作执行下一步。
  • 继续接收服务器数据,将接收到的数据写到待下载的文件里,并打印到终端。

 

服务器

文件上传

  • 解析协议头消息,获得命令、文章保存路径、文章标题名。
  • 进行判断,查看数据库是否存在该文章命题名,不存在发送ERROR,存在发送SUCCES,并将文章标题名和发布人保存到数据库中,并保存文件名到链表。
  • 接收客户端发送的数据,将接收到的数据写到待发布的文章路径里。

文件下载

  • 解析协议头消息,进入对应选项并传递路径与文章标题名。
  • 从数据库里查询指定文章标题名,如果标题不存在,给客户端发送ERROR,反之存在发送SUCCESS,执行下一步操作。
  • 读取待下载的文章名,将文章内容发送给客户端,每次发送1024字节。

支持并发文章发布或者文章浏览

  • 服务器接受客户端的连接,为每个客户端分配单独的线程,用于文章发布和浏览。
  • 对端关闭套接字时,为该客户端分配的线程退出。

 

 扩展功能

  • 每个用户可以修改文章内容。
  • 实现保存功能。
  • 更改用户名对应的文章发布人名也发生变动。

 

项目思路:

设计思路:

  1. 总体结构:采用TCP编程中的并发服务器结构,并结合数据库与链表进行保存。
  2. 发布:输入已经编辑好的文章标题,依次输入。
  3. 浏览:输入存在的标题名,依次浏览。

 

客户端程序

主程序 

#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <pthread.h>
//错误标志
#define DOWNLOAD_FILE_ERROR "download_file_error"
//成功标记
#define UPLOAD_FILE_SUCCESS "upload_file_success"
char name[30], key[30], pock[30];

//链表保存文件名和下标
typedef struct name
{
	char name[1024];
	int nume;
}data_t;
//链表结点
typedef struct Linknode
{
	data_t data;
	struct Linknode *pNext;
}Linknode;
//链表首地址
typedef struct Link
{
	Linknode *pHead;
	int count;
}Link;
//保存文件名的结构体
typedef struct save
{
	char pock[128];
}Save;
//开辟空间
Link *creat_link()
{
	Link *pLink = (Link*)malloc(sizeof(Link));
	if(NULL == pLink)
	{
		return NULL;
	}
	memset(pLink, 0, sizeof(Link));
	return pLink;
}

//创建结点
Linknode *creat_node(data_t tData)
{
	Linknode *pNode = (Linknode*)malloc(sizeof(Linknode));
	if(NULL == pNode)
	{
		return NULL;
	}
	memset(pNode, 0, sizeof(Linknode));
	pNode->data = tData;
	return pNode;
}

//销毁结点
void dastory_link(Link **pLink)
{
	Linknode *pTmp = (*pLink)->pHead;
	if(NULL == pLink || NULL == *pLink)
	{
		return;
	}
	while(pTmp != NULL)
	{
		(*pLink)->pHead = pTmp->pNext;
		free(pTmp);
		pTmp = (*pLink)->pHead;
	}
	(*pLink)->count = 0;
}
//初始化
int create_client(struct sockaddr_in my_addr)
{
	int sock_fd;
	//创建流式套接字
	if((sock_fd = socket(AF_INET, SOCK_STREAM,0)) == -1)
	{
		perror("sock_fd error");
		return -1;
	}

	//等待服务器端连接
	if((connect(sock_fd, (struct sockaddr*)&my_addr, sizeof(my_addr))) == -1)
	{
		perror("connect_fd error");
		close(sock_fd);
		return -1;
	}
	return sock_fd;
}

//遍历链表
char *link_find(Link *pLink, int index)
{
	Linknode *pTmp = pLink->pHead;
	while(pTmp != NULL)
	{
		if(index == pTmp->data.nume)
		{
			return pTmp->data.name;
		}
		pTmp = pTmp->pNext;
	}
	return DOWNLOAD_FILE_ERROR;
}

//开关
int on_off()
{
	char a;
	getchar();
	a = getchar();
	if(a == '\n')
	{
		return 1;
	}
	return -1;
}


int main(char argc, char *argv[])
{
	int my_port, my_id, sock_fd, connect_fd, ret, bank;
	char buf[1024];
	struct sockaddr_in my_addr;
	memset(&my_addr, 0, sizeof(my_addr));
//开辟链表空间
	Link *pLink = creat_link();

//入参检查
	//端口检查
	if(argc != 3)
	{
		printf("请输入正确信息\n");
		return -1;
	}
	if(atoi(argv[2]) <= 5000)
	{
		printf("端空小!\n");
		return -1;
	}
	if(argv[1])
	{
		my_id = inet_addr(argv[1]);//将字符串转化为整形
	}
	else
	{
		my_id = inet_addr("192.168.2.51");//将IP地址改为大端
	}

//分配IP与端口号
	my_addr.sin_family = AF_INET;
	my_addr.sin_port = htons(atoi(argv[2]));
	my_addr.sin_addr.s_addr = my_id;

//注册账户
	if(enroll_user(my_addr) < 0)
	{
	printf("                             \n");
		printf("       >>>注册失败\n");
		return -1;
	}
	printf("                             \n");
	printf("                   >>>注册成功<<<\n");


//操作
	while(1)
	{
		putchar(10);
		printf("        |--------------------------------|\n");
		printf("        |                                |\n");
		printf("        | 【1】刷新页面   【2】进入浏览  |\n");
		printf("        |                                |\n");
		printf("        | 【3】我要发布   【4】退出      |\n");
		printf("        |                                |\n");
		printf("        |          【5】删除标题         |\n");
		printf("        |                                |\n");
		printf("        |--------------------------------|\n");
		putchar(10);

		printf("        请选择>>>>>:");
		scanf("%d", &bank);
		switch(bank)
		{
			case 1:find_file(my_addr);break;
			case 2:
				   get_file(my_addr, pLink);
				   look_word(my_addr, pLink);
				   break;
			case 3:put_file(my_addr);break;
			case 4:quit_file(my_addr);return 0;
			case 5:delete_title(my_addr, pLink);break;
		}
	}
	return 0;
}

  进入浏览程序

//进入浏览
int get_file(struct sockaddr_in my_addr, Link *pLink)
{
	data_t tData;
	char buf[1024] = "L", filename[30];
	int sock_fd, index = 0, ret = 0, i = 0;
	Linknode *pNode;           //创建结点保存文件名和对应下标
	//初始化 获得接受套接字
	if((sock_fd = create_client(my_addr)) == -1)
	{
		printf("create_client error\n");
		return -1;
	}

	//发送给服务器 服务器执行look_word函数
	send(sock_fd, buf, sizeof(buf), 0);
	//接受服务器查询出来的文件名
	putchar(10);
	while((recv(sock_fd, buf, sizeof(buf), 0)) > 0)
	{
		if(0 == (strcmp(buf, UPLOAD_FILE_SUCCESS))) //判断服务器是否发送完毕
		{
			break;
		}
		if(0 == (strcmp(buf, DOWNLOAD_FILE_ERROR)))  //判断服务器是否出错
		{
			printf("find error\n");
			return -1;
		}
		printf("            |______________________\n");
		printf("            |    标题%d:%s\n", i++, buf);  //打印文件名 为读者提供方便

//头部插入 每接受到一个文件名都通过链表去保存 文件名与下标
		strcpy(tData.name, buf);
		//创建新结点去保存
		pNode = creat_node(tData);
		if(NULL == pNode)
		{
			return -1;
		}
		pNode->pNext = pLink->pHead;
		pLink->pHead = pNode;
		pNode->data.nume = pLink->count;
		pLink->count++;
		usleep(50);
	}
	close(sock_fd);
}

 

文章阅读程序

//浏览阅读
int look_word(struct sockaddr_in my_addr, Link *pLink)
{
	int sock_fd, index = 0, size;
	char filename[30], buf[8000];
	struct stat pock;

	//初始化
	if((sock_fd = create_client(my_addr)) == -1)
	{
		printf("create_client error\n");
		return -1;
	}
	//要上传文件的名字
	putchar(10);
	printf("   请点击您要进入的标题>>>:");
	scanf("%d",&index);

	//链表遍历查找
	strcpy(filename, link_find(pLink, index));
	if(0 == strcmp(filename, DOWNLOAD_FILE_ERROR))
	{
		printf("没有找到\n");
		return -1;
	}
	sprintf(buf, "G#../file/%s", filename);
	stat(filename, &pock);

	//发送
	send(sock_fd, buf, sizeof(buf), 0);

	//接受 判断消息是否为DOWNLOAD_FILE_ERROR 或出错
	if((size = recv(sock_fd, buf, sizeof(buf), 0)) < 0)
	{
		perror("recv error");
		return -1;
	}
	if(0 == strcmp(buf, DOWNLOAD_FILE_ERROR))
	{
		printf("文件不存在\n");
		return -1;
	}
	
	//文件存在并且接收到size 接受文件内容 打开帖子
	putchar(10);
	printf("             >>>该篇文章内容为:<<<\n");
	putchar(10);
	while((recv(sock_fd, buf, 8000, 0)) > 0)
	{
		printf("%s",buf);	
		memset(buf, 0, sizeof(buf));
		usleep(2000);
	}
	if(on_off())
	{
		close(sock_fd);
		//销毁结点
		dastory_link(&pLink);
		return -1;
	}
	printf("开关失效\n");
}

 

查找显示程序

int find_file(struct sockaddr_in my_addr)
{
	char buf[1024] = "F";
	int sock_fd, ret, i = 0;
	Save save;
	memset(&save, 0, sizeof(save));
	
	//初始化
	if((sock_fd = create_client(my_addr)) == -1)
	{
		printf("create_client error\n");
		return -1;
	}
	
	//发送
	send(sock_fd, buf, sizeof(buf), 0);

	//接受
	while((recv(sock_fd, &save, sizeof(save), 0)) > 0)
	{
		if(0== (strcmp(save.pock, DOWNLOAD_FILE_ERROR)))
		{
			printf("find error");
			return -1;
		}
		putchar(10);
		if(0 == i)
		{
			printf("      >>>>>>>>文章标题:%s<<<<<<<",save.pock);
		}
		if(i > 0 && i < 3)
		{
			printf("      >>>%s  ",save.pock);
		}
		putchar(10);
		memset(&save, 0, sizeof(save));
		usleep(50);
		if(++i >= 3)
		{
			printf("\n");
			i = 0;
		}
	}
	if(on_off())
	{
		close(sock_fd);
		return -1;
	}
	printf("开关失效\n");
}

 

 发布文章程序

//把../put_file/filename里面保存的文件上传到../file/里面
int put_file(struct sockaddr_in my_addr)
{
	char filename[30], pock[128], buf[1024], i;
	int sock_fd, fd, size = 0;
	//初始化
	if((sock_fd = create_client(my_addr)) == -1)
	{
		printf("create_client error\n");
		return -1;
	}

	//需要发布的帖子
	printf("需要发布的帖子:");
	scanf("%s", filename);
	sprintf(buf, "P#%s",filename);

	//动画
	printf("     >>>>确定发布:  【y】 【n】\n");
	putchar(10);
	printf("    请输入>>>:");
	getchar();
	i = getchar();
	if(i == 'n')
	{
		putchar(10);
		printf("     >>>>已取消<<<<\n");
		return -1;
	}

	//发送拼装好的协议
	send(sock_fd, buf, sizeof(buf), 0);

	//接受消息并 判断 
	//成功 UPLOAD_FINE_SUCCESS   失败 DOWNLOAD_FILE_ERROR
	if((recv(sock_fd, buf, sizeof(buf), 0)) < 0)//判断是否出错
	{
		perror("recv error");
		return -1;
	}
	if(0 == strcmp(buf, DOWNLOAD_FILE_ERROR))//判断接受的内容是否为DOWN...
	{
		printf("名字已经存在请换名 或者 路径中没有该文件 请编译成功\n");  //文件存在对应路径中
		return -1;
	}

	//打开要上传帖子的文件
	sprintf(pock, "../put_file/%s", filename);
	if((fd = open(pock, O_RDWR, 0666)) == -1)
	{
		perror("open error");
		return -1;
	}
	//将读到的内容发送到服务器
	while((size = read(fd, buf, sizeof(buf))) > 0)
	{
		send(sock_fd, buf, size, 0);
		memset(buf, 0, sizeof(buf));
		usleep(50);
	}
	putchar(10);
	printf("     >>>>发布成功<<<<\n");
	close(fd);
	close(sock_fd);
}

 

 退出程序

//退出
void quit_file(struct sockaddr_in my_addr)
{
	char buf[1024] = "Q";
	int sock_fd;
	//初始化
	if((sock_fd = create_client(my_addr)) == -1)
	{
		printf("create_client error\n");
		return;
	}
	//发送
	send(sock_fd, buf, sizeof(buf), 0);
	return;
	
}

注册程序

//注册
int enroll_user(struct sockaddr_in my_addr)
{
	char buf[1024];
	int sock_fd;
	//用户名
	printf("          >>>>注册新用户<<<<\n");
	printf("                             \n");
	printf("  请输入用户名>>>:");
	scanf("%s", name);
	printf("                             \n");
	printf("    请输入密码>>>:");
	scanf("%s", key);
	//初始化
	if((sock_fd = create_client(my_addr)) == -1)
	{
		printf("create_client error\n");
		return -1;
	}
	//加工
	sprintf(buf, "E#%s#%s", name, key);

	//发送
	send(sock_fd, buf, sizeof(buf), 0);
	return 1;
}

 

删除文章程序

//删除标题
int delete_title(struct sockaddr_in my_addr, Link *pLink)
{

	char buf[1024], filename[1024] = {0};
	int sock_fd;
	//初始化
	if((sock_fd = create_client(my_addr)) == -1)
	{
		printf("create_client error\n");
		return -1;
	}
	
	printf("想要删除的标题名>>>:");
	scanf("%s", filename);
	//加工
	sprintf(buf, "D#%s", filename);
	//发送
	send(sock_fd, buf, sizeof(buf), 0);
	
	if((recv(sock_fd, buf, sizeof(buf), 0)) < 0)//判断是否出错
	{
		perror("recv error");
		return -1;
	}
	if(0 == strcmp(buf, DOWNLOAD_FILE_ERROR))//判断接受的内容是否为DOWN...
	{
		printf("删除失败\n");  //文件存在对应路径中
		return -1;
	}
	
	printf("删除成功\n");
	close(sock_fd);

}

服务器端 

主程序

 

#include <stdio.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <pthread.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <dirent.h>
#include <sqlite3.h>
#include <time.h>

#define N 1024

//错误标志
#define DOWNLOAD_FILE_ERROR "download_file_error"
//成功标志
#define UPLOAD_FILE_SUCCESS "upload_file_success"
//数据库操作🔓
pthread_mutex_t g_mutex;
//数据库的句柄
sqlite3 *db = NULL;
//注册用户名
char key[30] = {0}, name[128] = {0};

//保存文件名结构体
typedef struct save
{
	char pock[128];
}Save;

//创建数据库表
int SQL_create(char *sql)
{
	char *errmsg = NULL;
	//创建数据库
	if((sqlite3_exec(db, sql, NULL, NULL, &errmsg)) != SQLITE_OK)
	{
		printf("SQL_create error:%s\n", errmsg);
		sqlite3_free(errmsg);
		return -1;
	}
	printf("SQL_create success\n");
	return 1;
}

//打开数据库 不存在则创建
void SQL_open(const char *SQL_name)
{
	printf("%s\n", SQL_name);
	if((sqlite3_open(SQL_name, &db)) != SQLITE_OK)
	{
		printf("sqlite3_open error\n");
		return;
	}
	printf("sqlite3_open success\n");
}


//空格建退出
void quit_file()
{
	printf("客户端退出\n");
	return;
}



int main(char argc, char *argv[])
{
	/*
	   struct stat pock;
	   stat(SIZE,&pock);
	   printf("文件大小:%ld\n",pock.st_size);
	   */
	int my_port, sock_fd, connect_fd;
	struct sockaddr_in my_addr;
	memset(&my_addr, 0, sizeof(my_addr));
	char buf[1024];
	pthread_t tid;

	//入参检查
	//端口检查
	if(argv[1])      //判断端口号
	{
		my_port = atoi(argv[1]);//将字符串转化为整形
	}
	else
	{
		my_port = 5888;
	}

	//创建流式套接字
	if((sock_fd = socket(AF_INET, SOCK_STREAM,0)) == -1)
	{
		perror("sock_fd error");
		return -1;
	}
	printf("sock_fd success\n");

	//优化
	int on = 1;
	setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

	//绑定IP 端口号
	my_addr.sin_family = AF_INET;
	my_addr.sin_port = htons(my_port);
	printf("my_port:%d\n", my_port);
	my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	if((bind(sock_fd, (struct sockaddr*)&my_addr, sizeof(my_addr))) == -1)
	{
		perror("bind error");
		close(sock_fd);
		return -1;
	}
	printf("bind success\n");

	//设置监听模式
	if((listen(sock_fd, 10)) == -1)
	{
		perror("listen error");
		close(sock_fd);
		return -1;
	}
	printf("Listening......\n");

	//打开并创建数据库
	SQL_open("campus.db");

	//创建数据库表
	char sql[] = "create table if not exists campus(file_name text primary key not null, creater text not null, time text);";
	SQL_create(sql);

	//选择 操作
	while(1)
	{
		//等待客户端的连接
		if((connect_fd = accept(sock_fd, NULL, NULL)) == -1)
		{
			perror("accept error");
			close(sock_fd);
			continue;
		}
		printf("创建的连接描述符:%d\n",connect_fd);

		//创建线程
		pthread_create(&tid, NULL, choose_fun, (void*)&connect_fd);
		pthread_detach(tid);

	}
	close(sock_fd);
	return 0;
}

选择程序 

void *choose_fun(void *arg)
{
	int connect_fd = *(int *)arg, ret;
	char buf[1024], key[30], name[128];

	printf("接受消息\n");
	//接受客户端消息  判断选择那种模式 F查找 G下载 P上传
	if((ret = recv(connect_fd, buf, sizeof(buf), 0)) == -1)
	{
		perror("rece error");
		return NULL;
	}
	//判断对端是否退出
	if(0 == ret)
	{
		printf("客户端退出!\n");
		return NULL;
	}
	printf("接受客户端buf[0]内容: %c\n", buf[0]);
	//1.套接字 2.文件名加路径
	switch(buf[0])
	{
		case 'F':
			find_file(connect_fd);
			break;
		case 'P':
			printf("%s\n",buf);
			put_file(connect_fd, buf+2);
			break;
		case 'G':
			printf("%s\n",buf);
			get_file(connect_fd, buf+2);
			break;
		case 'L':
			printf("%s\n",buf);
			look_word(connect_fd);
			break;
		case 'Q':
			quit_file();
			break;
		case 'E':
			enroll_file(connect_fd,buf+2);
			break;
		case 'D':
			delete_title(connect_fd, buf+2);
			break;
	}
}

下载文件程序 

//下载
void get_file(int connect_fd, char filename[30])
{
	char buf[8000];
	int fd, mode = 0;
	struct stat pock;
	stat(filename, &pock);
	printf("文件大小:%ld\n",pock.st_size);

	//检查文件是否存在数据库中 不存在就无法下载
	//文件路径../file/    
	if((SQL_file_exist(filename)+8) < 0)//文件不存在 发DOWNLOAD_FILE_ERROR
	{
		printf("不存在\n");
		strcpy(buf,  DOWNLOAD_FILE_ERROR);
	}
	else                            //文件存在 发文件大小
	{
		//检查文件是否存在对应路径中的文件夹
		if((access(filename, mode)) == -1)
		{
			printf("文件不在对应的路径中\n");
			strcpy(buf, DOWNLOAD_FILE_ERROR);
		}
		else
		{
			printf("在数据库中文件存在\n");
			sprintf(buf, "%ld", pock.st_size);
		}
	}
	send(connect_fd, buf, sizeof(buf), 0);//将获得的buf内容发给client
		
	if(0 == strcmp(buf, DOWNLOAD_FILE_ERROR))
	{
		printf("文件%s出错\n",buf);
		return;
	}

	//打开文件
	if((fd = open(filename, O_RDWR)) == -1)
	{
		printf("open error\n");
		return;
	}
	printf("打开文件成功\n");
	//读取内容
	printf("size文件大小:%ld\n", pock.st_size);
	while((read(fd, buf, pock.st_size)) > 0)
	{
		send(connect_fd, buf, pock.st_size, 0);
		memset(buf, 0, sizeof(buf));
		usleep(2000);
	}
	close(fd);
	close(connect_fd);
}

 上传文件程序

//上传
void put_file(int connect_fd, char filename[30])
{
	char buf[1024], sql[128], pock[128];
	int fd, mode = 0;
	struct stat Size;

	//检查文件是否存在数据库中
	sprintf(pock, "../put_file/%s", filename);
	if((SQL_file_exist(filename)) < 0)//数据库中没有一样的文件名 就通过
	{
		//检查文件是否存在对应路径中的文件夹
		if((access(pock, mode)) == -1) //返回-1表示文件不存在
		{
			printf("路径中没有该文件 请编译通过\n");
			strcpy(buf, DOWNLOAD_FILE_ERROR);
		}
		else                               
		{
			printf("路径中存在 可以上传\n");
			strcpy(buf,  UPLOAD_FILE_SUCCESS);
		}
	}
	else                            //文件名存在数据库
	{
			printf("在数据库中文件存在 请更换文件名\n");
			strcpy(buf, DOWNLOAD_FILE_ERROR);
	}

	send(connect_fd, buf, sizeof(buf), 0);//将获得的buf内容发给client

	//再次判断
	if(0 == strcmp(buf, DOWNLOAD_FILE_ERROR))
	{
		printf("文件%s出错\n",buf);
		return;
	}
	
	stat(pock,&Size);
	int i = Size.st_size;
	printf("文件大小:%d\n", i);


	//文件名保存到数据库
	char len[20] = {0};
	time_t timep;
	time(&timep);
	struct tm *p;
	p = gmtime(&timep);
	snprintf(len, 20, "%d-%d-%d %d:%d:%d", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday, 8 + p->tm_hour, p->tm_min, p->tm_sec);
	printf("时间%s\n:", len);
	

	sprintf(sql, "insert into campus values('%s', '发布人:%s', '发布时间:%s');", filename, name, len);
	if((SQL_create(sql)) == -1)
	{
		printf("文件上传失败\n");
		return;
	}

	//将文件保存到文件夹中
	sprintf(pock, "../file/%s", filename);
	if((fd = open(pock, O_CREAT | O_RDWR | O_TRUNC, 0666)) == -1)
	{
		perror("open error");
		return;
	}

	//把接收到文件的内容写入到打开的路径中
	//while((recv(connect_fd, buf, sizeof(buf), 0)) > 0)
	if(i >= N)
	{
		i = N;
	}
	while((recv(connect_fd, buf, i, 0)) > 0)
	{
		printf("buf里面的字符个数%ld\n", strlen(buf));
		write(fd, buf, strlen(buf));
		memset(buf, 0, sizeof(buf));
		usleep(50);
	}
	printf("发布成功\n");
	close(fd);
	close(connect_fd);
}

注册程序

//注册
int enroll_file(int connect_fd, char buf[1024])
{
	char *pock = buf;
	int i = 0;
	while(1)
	{
		if('#' != buf[i])
		{
			name[i] = buf[i];
			++pock;
			++i;
			continue;
		}
		strcpy(key, ++pock);
		break;
	}
	printf("name=%s\n", name);
	printf("key=%s\n", key);

	//创建数据库表
	char sql[1024] = {0};
	sprintf(sql, "create table if not exists %s(user text primary key not null, key text not null);", name);
	printf("sql=%s\n", sql);
	SQL_create(sql);
	printf("创建成功");
	
}

删除文件程序

//删除标题
int delete_title(int connect_fd, char filename[1024])
{
	char sql[128] = {0}, buf[1024] = {0};
	printf("name=%s\n", filename);
	sprintf(sql, "delete from campus where file_name='%s';", filename);
	
	if(SQL_create(sql)< 0)
	{
		printf("删除失败\n");
		strcpy(buf, DOWNLOAD_FILE_ERROR);
	}
	else
	{
		printf("删除成功\n");
		strcpy(buf,  UPLOAD_FILE_SUCCESS);
	}
	send(connect_fd, buf, sizeof(buf), 0);//将获得的buf内容发给client
	close(connect_fd);
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值