博客
关于我
文件服务器——src文件夹
阅读量:256 次
发布时间:2019-03-01

本文共 13460 字,大约阅读时间需要 44 分钟。

1.main.c文件

要做的事有:
1.初始化客户登录信息表
2.检查启动参数和捕捉线程退出信号
3.定义和初始化线程池
4.初始化TCP
5.创建epoll和用epoll监听sfd
6.进入功能界面
6.(1)判断退出标志位是否改为1,是就进入退出程序
6.(2)若不退出程序,用while(1)监听epoll
6.(3)若现在没有新的sfd连接服务器,给新连接的sfd先来登录,主线程承接登录验证作用

#include "../include/queue.h"#include "../include/head.h"#include "../include/threadpool.h"#include "../include/mainthread.h"#include "../include/childthread.h"#include "../include/register_login.h"//设置全局变量退出,用来表示主线程的退出标志int exitflag = 0;void sigFunc(int sigNum){       printf("signal%d is coming\n",sigNum);    //主线程收到退出信号,修改退出标志位值,0代表正常运行,1代表退出    exitflag = 1;}int main(int argc,char *argv[]){       //1.初始化客户登录信息表,结构体login_Flag_List存储连接的sfd和连接状态    memset(login_Flag_List,0,sizeof(Login_Flag_t)*CLIENT_NUM);		//2.检查启动参数和捕捉线程退出信号	// ./main ip port threadNum    ARGS_CHECK(argc,4);    //捕捉信号,SIGUSR1为线程退出发出的信号    signal(SIGUSR1,sigFunc);    //接受开启的线程数    int threadNum = atoi(argv[3]);		//3.定义和初始化线程池    ThreadPool_t threadPool;    memset(&threadPool,0,sizeof(threadPool));	//初始化线程池    threadPoolInit(&threadPool,threadNum);	//启动线程池    threadPoolStart(&threadPool);		//4.初始化TCP    int sfd = 0;    tcpInit(argv[1],argv[2],&sfd);		//5.创建epoll和用epoll监听sfd    int epfd = epoll_create(1);    epfdAddfd(sfd,epfd);	//初始化epoll监听的参数    /* epfdAddfd(exitPipe[0],epfd); */    struct epoll_event evs[2];    int newFd = 0;    int readyNum = 0;    //6.进入功能界面    while(1)    {           //6.(1)判断退出标志位是否改为1,是就进入退出程序        if(1 == exitflag)        {               pNote_t pNote = (pNote_t)calloc(threadPool.threadNum,sizeof(Note_t));            pthread_mutex_lock(&threadPool.Queue.mutex);            for(int i =0;i
< readyNum; ++i) { if(sfd == evs[i].data.fd)//若有新的sfd连接请求到服务器 { newFd = accept(sfd,NULL,NULL);//接受sfd epfdAddfd(newFd,epfd);//加入监听集合 for(int j=0;j
clientFd = evs[i].data.fd; queueInsert(&threadPool.Queue,pNote); pthread_cond_signal(&threadPool.Queue.cond); pthread_mutex_unlock(&threadPool.Queue.mutex); } } } } } } return 0;}

2.function.c

作为补充线程池的函数

#include "../include/head.h"#include "../include/threadpool.h"#include "../include/queue.h"#include "../include/mainthread.h"#include "../include/childthread.h"#include "../include/register_login.h"int threadPoolInit(pThreadPool_t pPool,int threadNum){       pPool->threadNum = threadNum;    pPool->pthid = (pthread_t *)calloc(threadNum,sizeof(pthread_t));    queueInit(&pPool->Queue);    return 0;}int threadPoolStart(pThreadPool_t pPool){       for(int i = 0;i< pPool->threadNum;++i)    {           pthread_create(&pPool->pthid[i],NULL,threadFunc,&pPool->Queue);    }    return 0;}void *threadFunc(void *p){       pQue_t pQueue = (pQue_t)p;    pNote_t pCur;    int getsuccess = 1;    while(1)    {           pthread_mutex_lock(&pQueue->mutex);        if(0 == pQueue->size)        {               pthread_cond_wait(&pQueue->cond,&pQueue->mutex);        }        getsuccess = queueGet(pQueue,&pCur);        pthread_mutex_unlock(&pQueue->mutex);        //如果收到的任务中文件描述符为-1,代表进行线程退出流程        if(pCur->clientFd == -1)        {               pthread_exit(0);        }        //如果获得任务成功,执行任务        if(0 == getsuccess)        {               /* Register_Login_Screen(pCur->clientFd); */            transFile(pCur->clientFd);            free(pCur);            pCur = NULL;        }    }}int queueInit(pQue_t pQueue){       pQueue->size = 0;    pQueue->pHead = NULL;    pQueue->pTail = NULL;    pthread_mutex_init(&pQueue->mutex,NULL);    pthread_cond_init(&pQueue->cond,NULL);    return 0;}int queueInsert(pQue_t pQueue,pNote_t pNote){       if(NULL == pQueue->pHead)    {           pQueue->pHead = pNote;        pQueue->pTail = pNote;    }    else    {           pQueue->pTail->next = pNote;        pQueue->pTail = pNote;    }    pQueue->size++;    return 0;}int queueGet(pQue_t pQueue,pNote_t *pGet){       if(0 == pQueue->size)    {           return -1;    }    *pGet = pQueue->pHead;    pQueue->pHead = pQueue->pHead->next;    pQueue->size--;    if(0 == pQueue->size)    {           pQueue->pTail = NULL;    }    return 0;}int tcpInit(char *ip,char *port,int *sockfd){       int sfd = socket(AF_INET,SOCK_STREAM,0);    ERROR_CHECK(sfd,-1,"socket");    struct sockaddr_in saddr;    memset(&saddr,0,sizeof(saddr));    saddr.sin_family = AF_INET;    saddr.sin_addr.s_addr = inet_addr(ip);    saddr.sin_port = htons(atoi(port));    int ret = bind(sfd,(struct sockaddr*)&saddr,sizeof(saddr));    ERROR_CHECK(ret,-1,"bind");    ret = listen(sfd,10);    ERROR_CHECK(ret,-1,"listen");    *sockfd = sfd;    return 0;}int epfdAddfd(int fd,int epfd){       struct epoll_event event;    memset(&event,0,sizeof(event));    event.events = EPOLLIN;    event.data.fd = fd;    int ret = epoll_ctl(epfd,EPOLL_CTL_ADD,fd,&event);    ERROR_CHECK(ret,-1,"epoll_add");    return 0;}int transFile(int clientfd){       Train_t train;    memset(&train,0,sizeof(train));    int fd = open("file",O_RDWR);    //传输文件名    train.len = 4;    strcpy(train.buf,"file");    send(clientfd,&train,4+train.len,0);    //传输文件长度    struct stat fileInfo;    bzero(&fileInfo,sizeof(fileInfo));    fstat(fd,&fileInfo);    train.len = sizeof(fileInfo.st_size);    memcpy(train.buf,&fileInfo.st_size,train.len);    send(clientfd,&train,4+train.len,0);    while(1)    {           int ret = read(fd,train.buf,sizeof(train.buf));        train.len = ret;        int ret1 = send(clientfd,&train,4+train.len,0);        if(0 == ret)        {               break;        }        if(-1 == ret1)        {               printf("client fault\n");            break;        }    }    return 0;}

3.insert.c

插入客户账号,盐值和密文数据,id自增

int mysqlInsert(char *name,char *salt,char* passwd){   	if(NULL==name||NULL==salt||NULL==passwd){   //若输入的字符串为空		printf("大兄弟,你传入mysqlInsert的字符串是空的");		return -1;	}	MYSQL *conn;	char *server = "localhost";	char *user = "root"; 	char *password = "lily_931216asd"; 	char *database = "clientInfo";//要访问的数据库名称	char query[200]={   0};    //char query[200]="insert into ZGMF (name, salt, passwd) values ('timo', 'sadad12121', '12312sfqwe1')";	int queryResult;	sprintf(query,"insert into clientShadow (nickname,salt,passwd) values ('%s','%s','%s')",name,salt,passwd);	conn = mysql_init(NULL);    //连接数据库,看连接是否成功,只有成功才能进行后面的操作	if(!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0))	{   		printf("Error connecting to database: %s\n", mysql_error(conn));	}    else    {   		printf("Connected...\n");	}	queryResult = mysql_query(conn, query);	if(queryResult)	{   		printf("Error making query:%s\n", mysql_error(conn));		mysql_close(conn);		return -1;//表示插入失败	}    else    {   		printf("insert success\n");	}	mysql_close(conn);	return 0;//表示插入成功}

4.getsalt

根据用户名查盐值,把盐值发给sfd的哪一方

#include "../include/head.h"#include "../include/register_login.h"//根据用户名查盐值,把盐值发给sfd的哪一方int getSalt(char* nameStr,int sfd){   	MYSQL *conn;	MYSQL_RES *res;	MYSQL_ROW row;	char *server = "localhost";	char *user = "root";	char *password = "lily_931223asd";	char *database = "clientInfo";//要访问的数据库名称	char query[300] = "select salt from clientShadow where nickname='";	unsigned int queryRet;    clientInfo_t clientInfo;	sprintf(query, "%s%s%s", query, nameStr, "'");	/* strcpy(query,"select * from hero"); */    //在输出前先打印查询语句	puts(query);    //初始化	conn = mysql_init(NULL);    if(!conn)    {           printf("MySQL init failed\n");        return -1;    }    //连接数据库,看连接是否成功,只有成功才能进行后面的操作	if(!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0))	{   		printf("Error connecting to database: %s\n", mysql_error(conn));		return -1;	}    else    {   		printf("MySQL Connected...\n");	}    //把SQL语句传递给MySQL	queryRet = mysql_query(conn, query);	if(queryRet)	{   		printf("Error making query: %s\n", mysql_error(conn));	}    else    {           //用mysql_num_rows可以得到查询的结果集有几行        //要配合mysql_store_result使用        //第一种判断方式        res = mysql_store_result(conn);        printf("mysql_num_rows = %lu\n", (unsigned long)mysql_num_rows(res));        //第二种判断方式,两种方式不能一起使用		/* res = mysql_use_result(conn); */                    row = mysql_fetch_row(res);		if(NULL == row)        {               printf("Don't find any data\n");        }        else		{               do            {   					/* printf("num=%d\n",mysql_num_fields(res));//列数 */                //每次for循环打印一整行的内容				for(queryRet = 0; queryRet < mysql_num_fields(res); ++queryRet)				{   						/* printf("%8s ", row[queryRet]); */                    char buf[14] = {   0};                    sprintf(buf,"%d %s",3,row[queryRet]);                    send(sfd,buf,strlen(buf),0);                        /* sscanf(row[queryRet],"%d%s%s%s",&clientInfo.id,clientInfo.nickName,clientInfo.salt,clientInfo.Passwd); */				}                /* puts(clientInfo.salt); */				printf("\n");            }while(NULL != (row = mysql_fetch_row(res)));		}		mysql_free_result(res);	}	mysql_close(conn);	return 0;}

5.queryByName

输入名字,看用户表是否有这个用户,若有返回0

//输入名字,打印数据库的名字int queryByName(char* nameStr){   	if(NULL==nameStr){   		printf("大兄弟,你传给queryByName的字符串是空的呀!\n");		return -1;	}	MYSQL *conn;	MYSQL_RES *res;	MYSQL_ROW row;	char *server = "localhost";//本机	char *user = "root";//登录账户 	char *password = "lily_931216asd";//登录密码 	char *database = "clientInfo";//要访问的数据库名称	char query[300] = "select * from clientShadow where nickname='";//按名字查找	unsigned int queryRet;    clientInfo_t clientInfo; 	sprintf(query, "%s%s%s", query, nameStr, "'");//拼接成命令字符串	/* strcpy(query,"select * from hero"); */    //在输出前先打印查询语句	puts(query);    //初始化数据库	conn = mysql_init(NULL);    if(!conn)    {           printf("MySQL init failed\n");        return -1;    }    //连接数据库,看连接是否成功,只有成功才能进行后面的操作	if(!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0))	{   //若连接数据库失败		printf("Error connecting to database: %s\n", mysql_error(conn));		return -1;	}    else//若连接数据库成功    {   		printf("MySQL Connected...\n");	}    //把SQL语句传递给MySQL	queryRet = mysql_query(conn, query);	if(queryRet)//若传输失败	{   		printf("Error making query: %s\n", mysql_error(conn));		return -1;	}    else//若传递命令成功    {               //用mysql_num_rows可以得到查询的结果集有几行        //要配合mysql_store_result使用        //第一种判断方式        res = mysql_store_result(conn);//表示查到结果集有几列        printf("mysql_num_rows = %lu\n", (unsigned long)mysql_num_rows(res));        //第二种判断方式,两种方式不能一起使用		/* res = mysql_use_result(conn); */        row = mysql_fetch_row(res);		if(NULL == row)//若没读到数据        {               printf("Don't find any data\n");        }        else//读到数据		{               do            {   					/* printf("num=%d\n",mysql_num_fields(res));//列数 */                //每次for循环打印一整行的内容				for(queryRet = 0; queryRet < mysql_num_fields(res); ++queryRet)				{   						//printf("%8s ", row[queryRet]);						if(row[queryRet]!=NULL){   							printf("find account in database!\n");							break;//找到就退出,否则会打印四行find account						}				}				printf("\n");//换行            }while(NULL != (row = mysql_fetch_row(res)));		}		mysql_free_result(res);	}	mysql_close(conn);//关闭mysql服务	return 0;//表示找到}

6.queryByPasswd

根据密文,看是否在数据库中,在就返回0

//输入名字,打印数据库的名字int queryByPasswd(char* passWd){   	if(NULL==passWd){           printf("大兄弟,你给queryByPasswd的字符串是空的呀!\n");        return -1;    }		MYSQL *conn;	MYSQL_RES *res;	MYSQL_ROW row;	char *server = "localhost";//本机	char *user = "root";//登录账户 	char *password = "lily_931223asd";//登录密码 	char *database = "clientInfo";//要访问的数据库名称	char query[300] = "select * from clientShadow where passwd='";//按密文查找	unsigned int queryRet;	sprintf(query, "%s%s%s", query, passWd, "'");//拼接成命令字符串	/* strcpy(query,"select * from hero"); */    //在输出前先打印查询语句	puts(query);    //初始化数据库	conn = mysql_init(NULL);    if(!conn)    {           printf("MySQL init failed\n");        return -1;    }    //连接数据库,看连接是否成功,只有成功才能进行后面的操作	if(!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0))	{   //若连接数据库失败		printf("Error connecting to database: %s\n", mysql_error(conn));		return -1;	}    else//若连接数据库成功    {   		printf("MySQL Connected...\n");	}    //把SQL语句传递给MySQL	queryRet = mysql_query(conn, query);	if(queryRet)//若传输失败	{   		printf("Error making query: %s\n", mysql_error(conn));        return -1;	}    else//若传递命令成功    {               //用mysql_num_rows可以得到查询的结果集有几行        //要配合mysql_store_result使用        //第一种判断方式        res = mysql_store_result(conn);//表示查到结果集有几列        printf("mysql_num_rows = %lu\n", (unsigned long)mysql_num_rows(res));        //第二种判断方式,两种方式不能一起使用		/* res = mysql_use_result(conn); */        row = mysql_fetch_row(res);		if(NULL == row)//若没读到数据        {               printf("Don't find any data\n");			return -1;//返回-1表示没找到        }        else//读到数据		{               do            {   					/* printf("num=%d\n",mysql_num_fields(res));//列数 */                //每次for循环打印一整行的内容				for(queryRet = 0; queryRet < mysql_num_fields(res); ++queryRet)				{   						//printf("%8s ", row[queryRet]);						if(row[queryRet]!=NULL){   							printf("find account in database!\n");							break;//找到就退出,否则会打印四行find account						}				}				printf("\n");//换行            }while(NULL != (row = mysql_fetch_row(res)));		}		mysql_free_result(res);	}	mysql_close(conn);//关闭mysql服务	return 0;//表示找到}

7.Screem.c

生成盐值和用户登录程序

#include "../include/head.h"#include "../include/register_login.h"//生成盐值int GenerateStr(char *str){       int i,flag;    srand(time(NULL));    for(i = 0;i

转载地址:http://ytno.baihongyu.com/

你可能感兴趣的文章
MyEclipse教程:Web开发——部署并测试项目
查看>>
【更新】CLion v2018.3发布(六):VCS和插件
查看>>
Linux-调试器gdb-make/makefile-git工具
查看>>
C++-必须知道的类的6个默认成员函数(构造-析构-拷贝构造-操作符重载)
查看>>
移动通信教学大纲
查看>>
leetcode关于微信读书的笔记-字符串
查看>>
文件服务器——src文件夹
查看>>
从零构建通讯器--4.4-4.5信号在创建线程的实战作用、write函数写入日志设置成不混乱、文件IO详解
查看>>
从零构建通讯器--5.2三次握手,telnet,wireshark
查看>>
关于信号的截断备忘录
查看>>
从零构建通讯器--5.6 通讯代码精粹之epoll函数实战1(连接池)
查看>>
Ubuntu命令行C++编译链接第三方库及命名空间
查看>>
为什么vs中的地址值是顺序相反的?
查看>>
如何判断两个浮点数是否相等?
查看>>
什么是地址?
查看>>
2019徐州网络赛K XKC's basketball team(结构体排序+二分+RMQ)
查看>>
POJ - 3984 迷宫问题(bfs+路径标记)
查看>>
2017ccpc杭州 E. Master of Subgraph(点分治 + 树dp + bitset)
查看>>
HDU - 4597 Play Game (博弈 + 区间dp)
查看>>
Educational Codeforces Round 99 (Rated for Div. 2)(A-E)
查看>>