Linux C语言 vim编辑器 使用 sqlite3数据库 makefile 的网络编程 qq 聊天室项目

1.功能有哪些:

1.用户登录功能

2.创建多用户连接的服务端

3.创建服务端

4.私聊功能

5.文件传送功能


2.思维导图:

1.

2.

 

 3.

 4.

 5.


3.程序运行的必要条件:

1. Linux  安装好  sqlite3   数据库

2. 有 vim 编辑器


4.文件清单:

1.cursor_color.h     (光标移动的头文件)

2.fuq.c                    (TCP 群聊服务器  )

3.khd.c                   (TCP 群聊客户端)

4.main.c                  (主函数,程序接口)

5.makefile               (程序编译文件  生成可执行的文件)

6.UDP_file.c            (私聊发送文件)

7.user.h                  (用户登录界面的头文件)

8.user.c                 

9.UTP                     (用户私聊功能的文件)


5.

代码:

1.cursor_collor 文件

/************************************************************************************************************************************************************************************************************************
 *文件名:
 *作  者:She001
 *时  间:
 *版  本:
 *作  用:
****************************************************************************************************************************************************************************************************************************/
#ifndef __CURSOR_COLOR_H__
#define __CURSOR_COLOR_H__
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include <stdio.h>

//清屏
#define CLEAR() printf("\033[2J")
 
// 上移光标
#define MOVEUP(x) printf("\033[%dA", (x))
 
// 下移光标
#define MOVEDOWN(x) printf("\033[%dB", (x))
 
// 左移光标
#define MOVELEFT(y) printf("\033[%dD", (y))
 
// 右移光标
#define MOVERIGHT(y) printf("\033[%dC",(y))
 
// 定位光标
#define MOVETO(x,y) printf("\033[%d;%dH", (x), (y))
 
// 光标复位
#define RESET_CURSOR() printf("\033[H")
// 隐藏光标
#define HIDE_CURSOR() printf("\033[?25l")
 
// 显示光标
#define SHOW_CURSOR() printf("\033[?25h")
 
//清除从光标到行尾的内容
#define CLEAR_LINE() printf("\033[K")
//反显
#define HIGHT_LIGHT() printf("\033[7m")
#define UN_HIGHT_LIGHT() printf("\033[27m")
 
//设置颜色
#define SET_FRONT_COLOR(color) printf("\033[%dm",(color))
#define SET_BACKGROUND_COLOR(color) printf("\033[%dm",(color))
//前景色
#define FRONT_BLACK 30
#define FRONT_RED 31
#define FRONT_GREEN 32
#define FRONT_YELLOW 33
#define FRONT_BLUE 34
#define FRONT_PURPLE 35
#define FRONT_DEEP_GREEN 36
#define FRONT_WHITE 37
 
//背景色
#define BACKGROUND_BLACK 40
#define BACKGROUND_RED 41
#define BACKGROUND_GREEN 42
#define BACKGROUND_YELLOW 43
#define BACKGROUND_BLUE 44
#define BACKGROUND_PURPLE 45
#define BACKGROUND_DEEP_GREEN 46
#define BACKGROUND_WHITE 47

#endif

2.fuq.c                    (TCP 群聊服务器  )

代码:

/************************************************************************************************************************************************************************************************************************
 *文件名:
 *作  者:She001
 *时  间:
 *版  本:
 *作  用:多人聊天的服务器 
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<sqlite3.h>



//1.创建锁 申请互斥锁
pthread_mutex_t mutex =PTHREAD_MUTEX_INITIALIZER;


struct information
{
	int num;//第几条信息
	char infor[1024];//信息的内容
}PP[10000];
int information_num=0;//信息的个数
char fppp[1000]="";



struct fuq
{
	int cid; //把所有的accept 返回的套接字存储,用来发送信息,
	char c_name[1024];//cid 的名字
	char c_ip[1024];//cid 的ip;
	int c_port;//cid的port 
}cid_arry[10000];
int cid_number=0; //客户端的个数
char qingchu[128]="clear-input";
char jieshu[128]="exit-out";
char kong[10]="";


void send_out_quit();
void sigfun(int signo)
{
	if(signo ==SIGTSTP)
	{
		printf("强制退出!\n");
		send_out_quit();
		getchar();
		getchar();
		exit(0);
	}
}

char* time1()
{
	//FILE* fp =fopen("1.txt","a+");
	time_t tm1 =time(NULL); //输出函
	struct tm* timp =gmtime(&tm1);
	sprintf(fppp,"year: %d  month: %d  day:%d hour: %d   min:%d  sec:%d  ",timp->tm_year+1900,timp->tm_mon+1,timp->tm_mday,(timp->tm_hour+8)%24,timp->tm_min,timp->tm_sec);
	return fppp;
	
}


void sqlite3_create_table()//确保创建一个表
{
	sqlite3 *studb =NULL;
	//下面这个函数 返回0 是执行成功
	int res =sqlite3_open("stu.db",&studb);// 打开数据库的函数   sqlite3 里面的 agrv[1] (参数传入)
	if(!res)
	{
	//	printf("sqlite3_Open  ok\n");//打开成功
	}
	else 
	{
		//printf("sqlite_open error\n");//打开失败
	//	printf("errmsg:%s \n",sqlite3_errmsg(studb));//错误信息的返回 函数errmsg
		return ;
	}

	char * errstr =NULL;
	//char * create_table ="create table stu_xinxi(s_name,s_ip,s_time,s_caozuo);";
	char  create_table[1024]="";
	
	strcat(create_table,"create table ");
	strcat(create_table,"stu_xinxi");
	strcat(create_table,"(s_name,s_ip,s_time,s_caozuo);");
	//printf("%s\n",create_table);
	if(!sqlite3_exec(studb,create_table,NULL,NULL,&errstr))//创建一个表来存储信息
	{
		//printf("create ta  ble  is suceessfuly \n");
	}
	else
	{
		//printf("create_table is failed \n");
	///	printf("error: %s\n",errstr);
	}
	sqlite3_close(studb);



}

void sqlite3_input_shangxian(char *a ,char *b)//把用户的登陆或者下线信息 写入数据库  a 名字  b ip   
{
	sqlite3 *studb =NULL;
	//下面这个函数 返回0 是执行成功
	int res =sqlite3_open("stu.db",&studb);// 打开数据库的函数   sqlite3 里面的 agrv[1] (参数传入)
	if(!res)
	{
		//printf("sqlite3_Open  ok\n");//打开成功
	}
	else 
	{
		printf("sqlite_open error\n");//打开失败
		printf("errmsg:%s \n",sqlite3_errmsg(studb));//错误信息的返回 函数errmsg
		return ;
	}

	char * errstr =NULL;
	//先写好操作sqlite3的库的命令
	char* time=time1();
	//const char * stup ="insert into stu_xinxi(s_name,s_ip,s_time,s_caozuo)values(\'帅哥\',\'192.168.1.162 \',\'13:12:12\',\'下线\');";
	char stup[1024]="";
	strcat(stup,"insert into stu_xinxi(s_name,s_ip,s_time,s_caozuo)values(\'");
	strcat(stup,a);
	strcat(stup,"\',\'");
	strcat(stup,b);
	strcat(stup,"\',\'");
	strcat(stup,time);
	strcat(stup,"\',\'");
	strcat(stup,"上线\');");


	
	//下面这个函数返回0 是执行成功
	if(!sqlite3_exec(studb,stup,NULL,NULL,&errstr)) //执行命令stup  errstr 是出现错误的时候返回的错误信息
	{
		//printf("opeation  is suceessfuly \n");
	}
	else
	{
		printf("opeation is failed \n");
		printf("error: %s\n",errstr);
	}
	sqlite3_close(studb);

}


void sqlite3_input_xiaxian(char *a ,char *b)//把用户的登陆或者下线信息 写入数据库  a 名字  b ip   
{
	sqlite3 *studb =NULL;
	//下面这个函数 返回0 是执行成功
	int res =sqlite3_open("stu.db",&studb);// 打开数据库的函数   sqlite3 里面的 agrv[1] (参数传入)
	if(!res)
	{
		//printf("sqlite3_Open  ok\n");//打开成功
	}
	else 
	{
		printf("sqlite_open error\n");//打开失败
		printf("errmsg:%s \n",sqlite3_errmsg(studb));//错误信息的返回 函数errmsg
		return ;
	}

	char * errstr =NULL;
	//先写好操作sqlite3的库的命令
	char* time=time1();
	//const char * stup ="insert into stu_xinxi(s_name,s_ip,s_time,s_caozuo)values(\'帅哥\',\'192.168.1.162 \',\'13:12:12\',\'下线\');";
	char stup[1024]="";
	strcat(stup,"insert into stu_xinxi(s_name,s_ip,s_time,s_caozuo)values(\'");
	strcat(stup,a);
	strcat(stup,"\',\'");
	strcat(stup,b);
	strcat(stup,"\',\'");
	strcat(stup,time);
	strcat(stup,"\',\'");
	strcat(stup,"下线\');");


	
	//下面这个函数返回0 是执行成功
	if(!sqlite3_exec(studb,stup,NULL,NULL,&errstr)) //执行命令stup  errstr 是出现错误的时候返回的错误信息
	{
		//printf("opeation  is suceessfuly \n");
	}
	else
	{
		printf("opeation is failed \n");
		printf("error: %s\n",errstr);
	}
	sqlite3_close(studb);

}

void progress_bar() //进度条
{
// ****************************** 配置 ***************************
    // 最后100%时的输出形式
    const char *LastStr = "[--------------------] 100%";

    // 进度条标志,可以改用"*"或其它符号
    const char Progressicon = '-';

    // 进度每加5,进度条就会加一格,注意Step值要和LastStr中的"-"数量相匹配,两者相乘等于100
    const int Step = 5;

    // 总共需要多少进度标志,即LastStr中"-"的数量
    const int iconMaxNum = 20;

    // 每隔100ms打印一次,这里同时每隔200ms会让进度加1
	printf("正在进入服务器:");
    const int Printinterval = 20000;
    // ****************************************************************

    for (int i = 0; i <= 100; ++i)
    {
        // -------------- 打印进度条 --------------
        printf("[");
        int currentindex = i / Step;
        for (int j = 0; j < iconMaxNum; ++j)
        {
            if (j < currentindex)
            {
                printf("%c", Progressicon); // 打印进度条标志
            }
            else
            {
                printf(" "); // 未达进度则打印空格
            }
        }

        printf("] ");
        // ----------------------------------------

        // -------- 打印数字进度 ----------
        printf("%3d%%", i);
        fflush(stdout);
        // -------------------------------

        usleep(Printinterval);

        for (int j = 0; j < strlen(LastStr); ++j)
        {
            printf("\b"); // 回删字符,让数字和进度条原地变化  "\b"控制光标前移一个字符
        }
        fflush(stdout);
    }
    printf("\n");
}
void  tt_input(int c)   //把数据输入到文件 ,删除文件的时候用
{
	int i,k;
	FILE* fp=fopen("fwq.txt","a+");
	if(fp==NULL)
	{
		perror("fwq error ");
	}
	fprintf(fp,"%d\t%s\n",PP[c].num,PP[c].infor);
	fclose(fp);
}

void tt_output()//信息的提取
{
	int i=0;
	FILE*fp=fopen("fwq.txt","r+");
	information_num=0;
	while(fscanf(fp,"%d %s\n",&PP[i].num,PP[i].infor)!=EOF)
	{
		i++;
	}
	information_num=i;
}

void send_out_quit()//把退出信息的所有的信息发送给用户
{
	char buff[1024]="";
	int i,j,k;
	for(i=0;i<cid_number;i++)
	{
			memset(buff,0,sizeof(buff));//退出的信息
			strcat(buff,"quit");
			send(cid_arry[i].cid,buff,strlen(buff),0);//发送信息
			usleep(10000);
	}
}

void send_out()//把文本的所有的信息发送给用户
{
	char buff[1024]="";
	int i,j,k;
	for(i=0;i<cid_number;i++)
	{
		memset(buff,0,sizeof(buff));
		send(cid_arry[i].cid,qingchu,strlen(qingchu),0);//发送清除客户端的命令
		usleep(10000);
		for(k=0;k<information_num;k++)
		{
			memset(buff,0,sizeof(buff));
			strcat(buff,PP[k].infor);
			send(cid_arry[i].cid,buff,strlen(buff),0);//发送信息
			usleep(10000);
		}
		send(cid_arry[i].cid,jieshu,strlen(jieshu),0);//发送结束客户端的命令
		usleep(10000);
	}
}

void information_cunchu(char* a,char *b)//发送的信息存入到文件
{
	char buff[1024]="";
	PP[information_num].num=information_num;
	strcat(buff,a);
	strcat(buff,":");
	strcat(buff,b);
	strcpy(PP[information_num].infor,buff);
	information_num++;
	int c= information_num-1;
	tt_input(c);

}



char *return_name(int cid)//返回 cid  对应人的name
{
	for(int i=0;i<cid_number;i++)
	{
		if(cid==cid_arry[i].cid)
		{
			return cid_arry[i].c_name;
		}
	}
	return NULL;
}

char *return_ip(int cid)//返回 cid  对应人的ip
{
	for(int i=0;i<cid_number;i++)
	{
		if(cid==cid_arry[i].cid)
		{
			return cid_arry[i].c_ip;
		}
	}
	return NULL;
}

int return_port(int cid)//返回 cid  对应的port
{
	for(int i=0;i<cid_number;i++)
	{
		if(cid==cid_arry[i].cid)
		{
			return cid_arry[i].c_port;
		}
	}
}


void *pthread_fun(void* arg)
{
	
	int cid =*((int *)arg);
	char buff[128]="";
	int len =0;
	char sendbuff[128]="";
	
	while(strncmp(buff,"quit",4))
	{
		
		
		bzero(buff,sizeof(buff));
		bzero(sendbuff,sizeof(sendbuff));
		//printf("正在等待!\n");
		int len  = recv(cid,buff,sizeof(buff),0);//接受信息
		//information(return_name(cid),buff);//把接送的信息发送到文件
		


/
		while(pthread_mutex_trylock(&mutex));//上锁
//
		

///		
		if(strncmp(buff,"quit",4)==0||len<=0)//删除已经关闭的终端
		{	
				sqlite3_input_xiaxian(return_name(cid),return_ip(cid));
				int a=return_port(cid);
				char sop[100]="";
				sprintf(sop,"%d",a);
				strcat(sendbuff,return_name(cid));
				strcat(sendbuff," ");
				strcat(sendbuff,return_ip(cid));
				strcat(sendbuff," ");
				strcat(sendbuff,sop);
				strcat(sendbuff," : ");
				strcat(sendbuff,"退出聊天室!\n");
				printf("%s\n",sendbuff);
				information_cunchu(kong,sendbuff);
				
			for(int kk=0;kk<cid_number;kk++)
			{
				if(cid_arry[kk].cid==cid)
				{
					for(int ll=kk;ll<cid_number;ll++)
					{
						cid_arry[ll]=cid_arry[ll+1];
					}
					break;//关闭无限循环 防止报错
				}
			}
			cid_number--;
			send_out();//发送信息
		}
		else
		{
			information_cunchu(return_name(cid),buff);//存放信息
			send_out();//发送信息
		}
///
		


//	
		printf("cid =%d  buff=%s\n ",cid,buff);//打印信息
		pthread_mutex_unlock(&mutex); //解锁
//
	}
	shutdown(cid,SHUT_RDWR);//退出循环之后,关闭文件描述符号
	return NULL;
}



int main(int argc,char *argv[])
{
		//参数判断
		if(argc <3)
		{
			perror("agc error\n");
			printf("argc :%d\n",argc);
			printf("参数错误!\n");
			getchar();
			return -1;
		}

		//1.创建套接字
		int sid =socket(AF_INET,SOCK_STREAM,0);//服务端的sid
		if(sid<0)
		{
			perror("socket error\n");
			printf("套接字申请失败!\n");
			getchar();
			return -2;
		}
		printf("socket ok\n");
		//printf("sid=%d\n",sid);
		

		//2.绑定 bind  函数经常失败
		struct sockaddr_in server_addr={0};
		server_addr.sin_family=AF_INET;
		server_addr.sin_port=htons(atoi(argv[2])); //端口号的转换  字符串-主机整数--网络整数
		server_addr.sin_addr.s_addr=inet_addr(argv[1]);//主机字符串 --网络字节序
		int reslg=bind(sid,(struct sockaddr*)&server_addr,sizeof(server_addr));
		if(reslg==-1)
		{
			perror("bind error\n");
			printf("绑定失败!\n");
			getchar();
			return -2;
		}
		printf("bind  success   ok\n");
		

		//3.监听 listen 
		if(listen(sid,10)<0)
		{
			perror("listen error\n");
			printf("监听失败!\n");
			getchar();
			return -3;
		}
		printf("listen ok\n");



		//4.accept()
		//建立连接
		struct sockaddr_in client_addr ={0};//accept 的准备工作 
		int size =sizeof(client_addr);      //accept 的第三个参数 
		
		/初始化锁

		//2.初始化锁
		if(pthread_mutex_init(&mutex,NULL)<0)
		{
			perror("pthrrad_mutex_init  error\n");
			return -1;
		}
		else
		{
			printf("pthread_mutex_init ok !\n");
		}

/

		signal(SIGTSTP,sigfun);//信号捕捉

		sqlite3_create_table();
/
progress_bar();
printf("欢迎来到QQ 聊天室的服务器 !\n");


/
	//5.循环登陆功能	
		char buff[1024];
		int len=0;
		char sendbuff[1024]="";
		int cid;//客户端套接字
		pthread_t tid=0;
		char kkk[1000]="";
		char t1[1000]="";
		char ntop[1024]="";
		int ttt;
		while(1)
		{
			bzero(buff,sizeof(buff));
			cid=accept(sid,(struct sockaddr*)&client_addr,&size);
			recv(cid,buff,sizeof(buff),0);
			if(strncmp(buff,"quit",4)==0)
			{
				continue;
			}
			printf("user  is cid =%d \n",cid);
			if(cid!=-1)
			{
				const char* ipstr = inet_ntop(AF_INET,&client_addr.sin_addr.s_addr,ntop,sizeof(ntop));
				strcpy(kkk,ntop); //网络字节序,转化为主机字节序的ip
				ttt=ntohl(client_addr.sin_port);//网络字节序的port 转化为主机字节序的port
				strcpy(cid_arry[cid_number].c_ip,kkk);
				cid_arry[cid_number].c_port=ttt;
				cid_arry[cid_number].cid=cid;
				strcpy(cid_arry[cid_number].c_name,buff);
				cid_number++;

			}
			sqlite3_input_shangxian(buff ,kkk);
			printf("cid = %d 连接成功!\n",cid);
			//pid_t pid = fork();只能用线程做
			if(cid!=-1)
			{
				//客户连接成功!
				char jj[1000]="";
				strcat(jj,buff);
				strcat(jj,"  ");
				strcat(jj,kkk);
				sprintf(t1,"%d",ttt);
				strcat(jj," ");
				strcat(jj,t1);
				strcat(jj,"欢迎用户进入聊天室!\n");
				printf("%s\n",jj);
				
				//登陆信息存入文件
				information_cunchu(kong,jj);
				send_out();//发送信息


				pthread_create(&tid,NULL,pthread_fun,&cid);//建立线程
			}
		}
		

       return 0;

}

3.khd.c                   (TCP 群聊客户端)

代码:

/************************************************************************************************************************************************************************************************************************
 *文件名:
 *作  者:She001
 *时  间:
 *版  本:
 *作  用:客户端
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include"cursor_color.h"
int color =31;
void printf_mig()
{
	printf("============================================================\n");
	printf("=                      聊天室                 =\n");	
	printf("============================================================\n");
	
}

void printf_end()
{
	char w[100];
	printf("============================================================\n");
	printf("============================================================\n");
	printf("请输入内容:");
	fflush(stdout);
}

void printf_out(char *s)
{
	color++;
	if(color>36)
	{
		color=31;
	}
	//printf("============================================================\n");
	printf("\033[%d;40m%s \033[0m",color,s);
}

void sigfun(int signo)
{
	//子进程在退出的时候,会给父进程发送 SIGCHLD 忽略信号
	if(signo == SIGCHLD)
	{
		exit(0);
	}
 
	
}

int main(int argc,char *argv[])
{
	int sockfd;
	struct sockaddr_in servaddr;
	if(argc<4)
	{
		printf("argc error!\n");
		printf("参数传输错误!\n");
		return -1;
	}
	else
	{
		printf("参数正确,传输成功!\n");
	}




	if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)//创建套接字 socket
	{
		perror("socket error\n");
		printf("创建套接字失败!\n");
		return -2;
	}
	else
	{
		printf("套接字创建成功\n");
	}
	

	//设置 sockaddr_in 结构体的参数
	bzero(&servaddr,sizeof(servaddr));  //结构体初始化
	servaddr.sin_family=AF_INET;        //数据类型设置 ip 通信
	servaddr.sin_port=htons(atoi(argv[2]));//端口号的赋值 字符串 - -- 主机字节序数值 --网络字节序数值  
	servaddr.sin_addr.s_addr=inet_addr(argv[1]);// ip 地址 的转换 十进制点分形式 到 网络字节序的模式
/// 设置描述符号的捕捉
fd_set rset = {0} ; 	//这个是描述符集合,把所有描述符放在这里面。
struct timeval tm = {0} ; //设定超时时间

///

	//连接服务器 
	if((connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr)))==-1) //调用connect 函数向服务器 建立TCP 连接
	{
		perror("connect error\n");
		printf("客户端连接错误\n");
		return -3;
	}
	else
	{
		printf("客户端与服务器连接成功!\n");
		char yy[1000];
		strcpy(yy,argv[3]);
		send(sockfd,yy,strlen(yy),0);
		printf("名字传送成功!\n");
	}


/
	
	//数据的接收 与发送 
	//创建两个进程 一个发送信息(父进程)  一个接受信息(子进程)
	//
	char buff[1024]="";
	char buff1[1024]="";
	int len=0;//接受父进程发送消息的长度
	int len1=0;//接收子进程收到消息的长度
	int color=31;
	pid_t pid =fork();
	if(pid<0)
	{
		perror("fork error\n");
		printf("进程创建失败!\n");
	}
	else if(pid>0)//父进程 发送消息
	{
		signal(SIGCHLD,sigfun);

		while(1)
		{
			//把键盘文件添加到描述符号集合中
			FD_SET(STDIN_FILENO,&rset);
			tm.tv_sec =10;  //设定超时时间,如果3s内没有动静,就立刻返回
			int count =select(STDIN_FILENO + 1,&rset,NULL,NULL,&tm);//看描述符号里面信号有没有动静
			//printf("count =%d\n",count);
			if(FD_ISSET(STDIN_FILENO,&rset))
			{	

				fgets(buff,sizeof(buff),stdin);
				if(strlen(buff)==0)
				{
					strcat(buff,"空");
				}
				len = send(sockfd,buff,strlen(buff)+1,0);//发送信息!
			}
			if(!strncmp(buff,"quit",4))
			{
				kill(pid,SIGKILL);
				printf("退出!\n");
				exit(0);
			}
			//printf("send : %s \n",buff);
			if(len<0)
			{
				perror(" send error\n");
			}
			memset(buff,0,sizeof(buff));
		}
	}
	else if(pid ==0)
	{
		while(1)
		{
			
			memset(buff1,0,sizeof(buff1));
			len1 = recv(sockfd,buff1,sizeof(buff1),0);
			if(len1<0)
			{
				perror("recv error\n");
			}
			else
			{
				//printf("len =%d\n",len1);
				//printf("接受成功!\n");
			}
			printf("recv : %s\n",buff1);
			if(strncmp(buff1,"quit",4)==0)
			{
				printf("quit 已经接受");
				sleep(2);
			    kill(getppid(),SIGKILL);
			    //kill(getppid(),SIGCHLD);
				printf("pid =%d  ppid=%d\n",getpid(),getppid());
			    kill(getpid(),SIGKILL);
			    exit(0);
			}
			if(strncmp("clear-input",buff1,11)==0)
			{

				system("clear");
				//printf("进入成功!\n");
				printf_mig();
				while(1)
				{
					memset(buff1,0,sizeof(buff1));
					len1 = recv(sockfd,buff1,sizeof(buff1),0);
					if(strncmp("exit-out",buff1,8)==0)
					{
						printf_end();
						break;
					}
					else
					{
						printf_out(buff1);
						
					}
				}
			}
		}
	}
	close(sockfd); 

       return 0;

}

4.main.c                  (主函数,程序接口)

代码:

/************************************************************************************************************************************************************************************************************************
 *文件名:
 *作  者:She001
 *时  间:
 *版  本:
 *作  用:
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include"user.h"
int main(int argc,char *argv[])
{
	user_information_initialize();
	sign_in_surface();
       return 0;

}

5.makefile               (程序编译文件  生成可执行的文件)

代码:

all: qq fuq khd UTP UDP_file

qq : user.o main.o 
	gcc -g -o qq user.o main.o
user.o :user.c
	gcc -g -c user.c -o user.o
main.o: main.c
	gcc -g -c main.c -o main.o

fuq:fuq.o
	gcc -g -pthread  -o fuq fuq.o -l sqlite3
fuq.o:fuq.c
	gcc -g -c  fuq.c -pthread  -o  fuq.o -l sqlite5

khd:khd.o
	gcc -g -pthread  -o khd khd.o -l sqlite3
khd.o:khd.c
	gcc -g -c  khd.c -pthread  -o  khd.o -l sqlite3


UTP:UTP.o
	gcc -g -pthread  -o UTP UTP.o -l sqlite3
UTP.o:UTP.c
	gcc -g -c  UTP.c -pthread  -o  UTP.o -l sqlite3


UDP_file:UDP_file.o
	gcc -g -pthread  -o UDP_file UDP_file.o -l sqlite3
UDP_file.o:UDP_file.c
	gcc -g -c  UDP_file.c -pthread  -o  UDP_file.o -l sqlite3


6.UDP_file.c            (私聊发送文件)

代码:

/************************************************************************************************************************************************************************************************************************
 *文件名:
 *作  者:She001
 *时  间:
 *版  本:
 *作  用:UDP 服务端  发送文件
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<sqlite3.h>
//1.UDP 协议 接受端的编程
//1.socket 数据报套接字
//2.bind : 把自己的ip port  绑定好 
//3.recvfrom  读写操作 while(1)  printf() 
//4.close
//
int cid;
struct sockaddr_in caddr={0};
struct sockaddr_in saddr={0};
int panduan=0;



//采用C模式读二进制文件//并且发送
void DataRead_CMode(char * a)//a :文件名字
{
    printf("正在发送文件!\n");
    FILE *fid;
    int len;
    char buff[10240]="";
    fid = fopen(a,"rb+");
    if(fid == NULL)
    {
        printf("读取文件出错");
        return;
    }



	while(fscanf(fid,"%s\n",buff)!=EOF)//读一行
	{
			strcat(buff,"\n");
			len= sendto(cid,buff,strlen(buff),0,(struct sockaddr*)&saddr,sizeof(struct sockaddr));
			usleep(10000);
	    		memset(buff,0,sizeof(buff));
			 if(len>0)
			 {
				printf("buff=%s\n",buff);
			 	printf("发送成功!\n");
			 }
			 else
			 {
			 	perror("发送失败 send error\n");
			 }	
	    	memset(buff,0,sizeof(buff));
	}



	

 		 strcpy(buff,"fa-song-wang-bi");
	   	sendto(cid,buff,strlen(buff),0,(struct sockaddr*)&saddr,sizeof(struct sockaddr));
		printf("发送完毕!\n");
    	fclose(fid);
}


//采用C模式写二进制文件
void DataWrite_CMode()
{
    //写出数据
	int len;
	int len1;
	char buff[1024]="";
    FILE *fid;
	int size=sizeof(caddr);
    fid = fopen("1.txt","wb+");
    if(fid == NULL)
    {
        printf("写出文件出错");
        return;
    }
    while(1)
	{
		memset(buff,0,sizeof(buff));
		len=recvfrom(cid,buff,sizeof(buff),0,(struct sockaddr*)&caddr,&size);
		if(len>0)
		{
			printf("接受成功!\n");
			printf("buff=%s\n",buff);
		}
		else
		{
			printf("接受失败\n");
		}
		if(strncmp(buff,"fa-song-wang-bi",15)==0)
		{
			break;
		}
		len1 =fwrite(buff,strlen(buff),1,fid);
		if(len1>0)
		{
			printf("写入成功!\n");
		}
		else
		{
			printf("写入error\n");
		}
	}
    fclose(fid);
    
}
 



void song_file()
{
	char name[1000];
	char buff[1000];
	printf("请输入要传送文件的名字:");
	scanf("%s",name);
	DataRead_CMode(name);

}

void sigfun(int signo)//信号捕捉函数
{
	if(signo==SIGCHLD)
	{
		panduan=1;
	}

}

int main(int argc,char *argv[])//1 自己的 ip  2 自己的port    3 别人的ip  4 别人的port 
{
	if(argc <5)
	{
		perror("argc error\n");
		return -1;
	}
	cid = socket(AF_INET,SOCK_DGRAM,0);
	if(cid ==-1)
	{
		perror("cid error\n");
		return -2;
	}
	printf("socket ok\n");
	
	caddr.sin_family =AF_INET;
	caddr.sin_port =htons(atoi(argv[2]));
	caddr.sin_addr.s_addr =inet_addr(argv[1]);

	if(bind(cid,(struct sockaddr*)&caddr,sizeof(caddr))<0)
	{
		perror("bind error\n");
		return -2;
	}
	printf("bind success\n");
	//
	fd_set rset = {0} ; 	//这个是描述符集合,把所有描述符放在这里面。
	struct timeval tm = {0} ; //设定超时时间

	///
	char buff[1280]="";
	saddr.sin_family =AF_INET;
	saddr.sin_port =htons(atoi(argv[4]));
	saddr.sin_addr.s_addr =inet_addr(argv[3]);
	int size =sizeof(saddr);
	char ip[128]="";
	int hh=1;
	int len;
	
			if(hh==1)
			{
				hh=0;
				pid_t pid=fork();
				if(pid==0)
				{
					while(1)
					{
						bzero(buff,sizeof(buff));
						recvfrom(cid,buff,sizeof(buff)-1,0,(struct sockaddr*)&caddr,&size);
						if(strncmp(buff,"shoudao-song-wen-file",21)==0)
						{
							printf("对方已经准备接受,我方准备发送数据\n");
							kill(getppid(),SIGCHLD);//收到信号结束,结束父进程的死循环
							//开始发送数据
							song_file();


						}
						if(strncmp(buff,"song-wen-jian",13)==0)
						{
							
							strcpy(buff,"shoudao-song-wen-file");
							sendto(cid,buff,strlen(buff),0,(struct sockaddr*)&saddr,sizeof(struct sockaddr));
							printf("接受文件的信息收到!\n");
							///接受文件的函数
							 DataWrite_CMode();
						}
						printf("%s\n",buff);
						
					}
				}
				if(pid>0)
				{
					signal(SIGCHLD,sigfun);//闹钟信号的捕捉
					while(1)
					{
						//把键盘文件添加到描述符号集合中
						FD_SET(STDIN_FILENO,&rset);
						tm.tv_sec =20;  //设定超时时间,如果3s内没有动静,就立刻返回
						int count =select(STDIN_FILENO + 1,&rset,NULL,NULL,&tm);//看描述符号里面信号有没有动静
						//printf("count =%d\n",count);
						if(FD_ISSET(STDIN_FILENO,&rset))
						{
							
							printf("===================================\n");
							printf("=    1.传送文件           =\n");
							printf("=    2.退出                        =\n");
							printf("====================================\n");
							printf("请输入选择:");
							scanf("%s",buff);
							int a=atoi(buff);
							printf("a=%d\n",a);
							getchar();
							if(a==1)
							{
								panduan=0;
								while(panduan!=1)
								{
									strcpy(buff,"song-wen-jian");
									sendto(cid,buff,strlen(buff),0,(struct sockaddr*)&saddr,sizeof(struct sockaddr));
									printf("正在发送 :buff=%s\n",buff);
									sleep(1);
									memset(buff,0,sizeof(buff));
								}
							}
							else
							{
								kill(pid,SIGKILL);//杀死子进程
								exit(0);//自己退出	
							}
								
						}
						/*
						if(!strncmp(buff,"quit",4))
						{
							kill(pid,SIGKILL);
							printf("退出!\n");
							exit(0);
						}*/
						//printf("send : %s \n",buff);
						memset(buff,0,sizeof(buff));			
					}
				}
	}
						close(cid);

       return 0;

}

7.user.h                  (用户登录界面的头文件)

代码:

//用户信息 的存储  
#ifndef __USER_H__
#define __USER_H__
#include<stdio.h>
#include<string.h>
#include<stdbool.h>
#include<stdlib.h>
#include<time.h>
#include<termio.h>



typedef struct user
{
	char U_name[100];             //用户的姓名
	char U_account_number[100];   //用户的账户信息
	char U_password[100];         //用户的密码
	int U_id;                     //用户的身份

}user;
int getch(void);                              //不显示函数
void error1();                               //提示函数(提醒自己 这个地方没写) 
void sign_in_surface();                       //开始界面的选择方式 
void staff_password();                      //管理员登陆界面
void passenger_password();                      //乘客的登陆界面
void staff_register();                      //管理员的注册界面
void passenger_register();                      //乘客的注册界面
void staff_sign_in();                       //管理员登陆界面
void passenger_sign_in();                       //管理员登陆界面
void user_information_initialize();         //乘用户信息初始化
void user_input_txt();                      //账户密码信息输入到文件中
void qq_select();                           //选择群聊还是单独聊天 用户功能 
void staff_open_server();                  //管理员打开群聊的服务端
int check_ip_exit(char *a,char *b) ;                       //测试ip是否存在











#endif 


8.user.c                 

代码:

/************************************************************************************************************************************************************************************************************************
 *文件名:user.c
 *作  者:She001
 *时  间:
 *版  本:
 *作  用:用户信息的存储
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include"user.h"




int pp[100];            //密码的传递
int user_number;          //用户的数量
char user_zhanghu[100];  //使用用户的帐号
char user_name[100];     //使用者用户的名字 
user user_num[1000];  //开辟数组储存数据

int check_ip_exit(char *a,char *b)//测试ip是否存在
{
	
	int sockfd;
	struct sockaddr_in servaddr;




	if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)//创建套接字 socket
	{
		perror("socket error\n");
		printf("创建套接字失败!\n");
		return -2;
	}
	else
	{
		//printf("套接字创建成功\n");
	}
	

	//设置 sockaddr_in 结构体的参数
	bzero(&servaddr,sizeof(servaddr));  //结构体初始化
	servaddr.sin_family=AF_INET;        //数据类型设置 ip 通信
	servaddr.sin_port=htons(atoi(b));//端口号的赋值 字符串 - -- 主机字节序数值 --网络字节序数值  
	servaddr.sin_addr.s_addr=inet_addr(a);// ip 地址 的转换 十进制点分形式 到 网络字节序的模式


///

	//连接服务器 
	if((connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr)))==-1) //调用connect 函数向服务器 建立TCP 连接
	{
		perror("connect error\n");
		printf("客户端连接错误\n");
		return -3;
	}
	else
	{
		//printf("客户端与服务器连接成功!\n");
		//printf("服务器存在! 可以连接\n");
		char pp[10]="quit";
		send(sockfd,pp,strlen(pp),0);
		return 1;
	}
}



void staff_open_server()  //管理员打开群聊界面
{
	char zong[100]="";
	char ip[1000];//ip
	char port[1000];//port
	system("clear");
	printf("===================================\n");
	printf("=      管理员打开服务端界面       =\n");
	printf("===================================\n");
	printf("请输入服务器的ip:");
	scanf("%s",ip);
	printf("请输入服务器的端口号:");
	scanf("%s",port);
	
	pid_t pid=fork();
	if(pid<0)
	{
		perror("fuq fork error\n");
	}
	else if(pid >0)
	{
		wait(NULL);
	}
	else if(pid ==0)
	{	

	
	printf("任意键回车创建服务端\n");
	getchar();
	strcat(zong,"gnome-terminal -x ");
	strcat(zong,"bash -c ");
	strcat(zong,"\"");
	strcat(zong,"./fuq ");
	strcat(zong,ip);
	strcat(zong," ");
	strcat(zong,port);
	strcat(zong,"\"");
	printf("zong :%s",zong);
	getchar();

	system(zong);//打开服务器
	printf("打开成功!\n");
	getchar();

	}
	
}

void error1()
{
	printf("这里有没有填函数!\n");
}
void qq_select() //选择群聊还是单独聊天
{
	system("clear");
	printf("============================================\n");
	printf("=             聊天室功能选择              =\n");
	printf("============================================\n");
	printf("=           1.群聊                         =\n");
	printf("============================================\n");
	printf("=           2.单独找别人聊天        =\n");
	printf("============================================\n");
	printf("=           3.传送文件给别人        =\n");
	printf("============================================\n");
	printf("=           4.退出                         =\n");
	printf("============================================\n");
	printf("请输入数字选择:");
    char kk[1000];
    scanf("%s",kk);
    int a=strlen(kk);
    if(a==1)
    {
        int b=atoi(kk);
        if(b<0||b>4)
        {
            printf("  输入错误!\n");
            printf("任意键加回车,重新进入当前界面\n");
            getchar();
            getchar();
            qq_select();  //重新输入

            return;               //退出程序,防止有bug
        }
        else
        {
            if(b==1)
            {
				char zong[100];
				char ip[1000]; //ip 
				char port[1000];//port
              	printf("请输入服务器的ip ");
				scanf("%s",ip);
				printf("请输入服务器的端口号:");
				scanf("%s",port);
				
				

				int ttt=check_ip_exit(ip,port);
				if(ttt<0)
				{
					printf("服务器不存在!\n");
					printf("回车返回!\n");
					getchar();
					getchar();
				}
				else
				{
					pid_t pid=fork();
					if(pid <0)
					{
						perror("khd fork error\n");
						return ;
					}
					if(pid==0)
					{
					
					printf("服务器存在,正在进入!\n");
					printf("随意按键进入!\n");
					getchar();
					getchar();
					strcat(zong,"gnome-terminal -x ");
					strcat(zong,"bash -c ");
					strcat(zong,"\"");
					strcat(zong,"./khd ");
					strcat(zong,ip);
					strcat(zong," ");
					strcat(zong,port);
					strcat(zong," ");
					strcat(zong,user_name);
					strcat(zong,"\"");
					//system("gnome-terminal -x "./khd ip port user_name"  ");
					printf("zong :%s",zong);
					system(zong);//进入客户端
					getchar();
					}
				}
				wait(NULL);
				qq_select();//再次选择
				
            }
            else if(b==2)
            {
               
				char zong[100];
				char ip[1000]; //ip 
				char port[1000];//port
				char name[1000];//name
				char ip1[1000]; //ip 
				char port1[1000];//port
				char name1[1000];//name

				printf("为了确保网络信息的安全,私聊信息要输入的详细一点!,请您见谅!\n");

              	printf("请输入自己的ip ");
				scanf("%s",ip);
				printf("请输入自己的端口号:");
				scanf("%s",port);
				printf("请输入自己的姓名:");
				scanf("%s",name);
              	printf("请输入对方的ip ");
				scanf("%s",ip1);
				printf("请输入对方的端口号:");
				scanf("%s",port1);
				printf("请输入对方的姓名:");
				scanf("%s",name1);

					printf("正在建立自己的客户端,正在进入!\n");
					printf("随意按键进入!\n");
					getchar();
					getchar();
					strcat(zong,"gnome-terminal -x ");
					strcat(zong,"bash -c ");
					strcat(zong,"\"");
					strcat(zong,"./UTP ");
					strcat(zong,ip);
					strcat(zong," ");
					strcat(zong,port);
					strcat(zong," ");
					strcat(zong,name);
					strcat(zong," ");
					strcat(zong,ip1);
					strcat(zong," ");
					strcat(zong,port1);
					strcat(zong," ");
					strcat(zong,name1);
					strcat(zong,"\"");
					//system("gnome-terminal -x "./khd ip port user_name"  ");
					printf("zong :%s\n",zong);
					getchar();
					system(zong);
					 qq_select(); //选择群聊还是单独聊天
            }
			else if(b==3)
			{
				
				char zong[100];
				char ip[1000]; //ip 
				char port[1000];//port
				char ip1[1000]; //ip 
				char port1[1000];//port

				printf("为了确保网络信息的安全,私聊信息要输入的详细一点!,请您见谅!\n");

              	printf("请输入自己的ip ");
				scanf("%s",ip);
				printf("请输入自己的端口号:");
				scanf("%s",port);
              	printf("请输入对方的ip ");
				scanf("%s",ip1);
				printf("请输入对方的端口号:");
				scanf("%s",port1);
				
					printf("正在建立自己的客户端,正在进入!\n");
					printf("随意按键进入!\n");
					getchar();
					getchar();
					strcat(zong,"gnome-terminal -x ");
					strcat(zong,"bash -c ");
					strcat(zong,"\"");
					strcat(zong,"./UDP_file ");
					strcat(zong,ip);
					strcat(zong," ");
					strcat(zong,port);
					strcat(zong," ");
					strcat(zong,ip1);
					strcat(zong," ");
					strcat(zong,port1);
					strcat(zong,"\"");
					//system("gnome-terminal -x "./khd ip port user_name"  ");
					printf("zong :%s\n",zong);
					getchar();
					system(zong);
					 qq_select(); //选择群聊还是单独聊天



			}
			else if(b==4)
			{
				exit(-1);
				return;
			}
            else
            {
              qq_select(); 
            }
        }
    }
    else
    {
        printf("  输入错误!\n");
        printf("任意键加回车,重新进入当前界面\n");
        getchar();
        getchar();
       qq_select(); //重新输入
        return;               //退出程序,防止有bug
    }



}



void sign_in_surface()                       //开始界面的选择方式
{
	
	system("clear");
	printf("=================================================\n");
	printf("*               登陆方式选择界面                *\n");
	printf("=================================================\n");
	printf("*              1.用户登陆                       *\n");
	printf("=================================================\n");
	printf("*              2.管理员登陆                     *\n");
	printf("=================================================\n");
	printf("请输入数字选择:");
	char kk[1000];
    scanf("%s",kk);
    int a=strlen(kk);
    if(a==1)
    {
        int b=atoi(kk);
        if(b<0||b>2)
        {
            printf("  输入错误!\n");
            printf("任意键加回车,重新进入当前界面\n");
            getchar();
            getchar();
            sign_in_surface();  //重新输入
            return;               //退出程序,防止有bug
        }
        else
        {
            if(b==1)
            {
                passenger_sign_in();
            }
            else if(b==2)
            {
                staff_sign_in();
            }
            else
            {
               sign_in_surface();
            }
        }

    }
    else
    {
        printf("  输入错误!\n");
        printf("任意键加回车,重新进入当前界面\n");
        getchar();
        getchar();
        sign_in_surface(); //重新输入
        return;               //退出程序,防止有bug
    }
} 




void staff_password()                     //管理员登陆界面
{
    system("clear");
	char mm[100];  //帐号
	char nn[100];  //密码
	int pppp=0;  //标记
	int i,j;
	printf("=============================================\n");
	printf("=              管理员的登陆界面             =\n");
	printf("=============================================\n");
	printf("请输入帐号(手机号):");
	scanf("%s",mm);
	printf("请输入密码:");
	getchar();
	
	i=0;
	j=0;
	while(i<100)
	{
		nn[i]=getch();//getch()从控制台输入一各字符但是不显示 
		if(nn[i]=='\b' && i>0)  //遇到回车不管 
		{
			continue;
		} 
		if(nn[i]=='\b' && i==0)	//如果在最开始就按退格键,就让i=-1 
		{
			i=0;
			continue;
		}
		if(nn[i]=='\r')     //如果输入的是回车,就退出输入循环 
		{
			break;
		}
		i++;
		putchar('*');
	}
	nn[i]='\0';
	printf("\n");
	//
 
    error1();
    //这个上面需要 密码遮掩
	for(i=0;i<user_number;i++)
	{
		if(strcmp(user_num[i].U_account_number,mm)==0&&user_num[i].U_id==1)
		{
			if(strcmp(user_num[i].U_password,nn)==0)
			{
				pppp=1;
				printf("用户姓名:%s\n",user_num[i].U_name);
				printf("乘客信息确认无误  登陆成功!\n");
				printf("任意键加回车,进入系统!\n");
				
				strcpy(user_name,user_num[i].U_name);
				strcpy(user_zhanghu,user_num[i].U_account_number);
				getchar();
				getchar();
				staff_open_server();//打开服务器
				这里没写()进入界面的函数
			    return; 
			}
		}
	}
	if(pppp==0)
	{
		printf("没有此人信息!\n");
		printf("任意键加回车,返回上一个界面!\n");
		getchar();
		getchar();
		staff_sign_in();
	}
}

void passenger_password()                      //乘客的登陆界面
{
    system("clear");
	char mm[100];  //帐号
	char nn[100];  //密码
	int pppp=0;
	int i,j;
	printf("=============================================\n");
	printf("=              用户的登陆界面               =\n");
	printf("=============================================\n");
	printf("请输入帐号(手机号):");
	scanf("%s",mm);
	printf("请输入密码:");
	getchar();
		
	i=0;
	j=0;
	while(i<100)
	{
		nn[i]=getch();//getch()从控制台输入一各字符但是不显示 
		if(nn[i]=='\b' && i>0)  //遇到回车不管 
		{
			continue;
		} 
		if(nn[i]=='\b' && i==0)	//如果在最开始就按退格键,就让i=-1 
		{
			i=0;
			continue;
		}
		if(nn[i]=='\r')     //如果输入的是回车,就退出输入循环 
		{
			break;
		}
		i++;
		putchar('*');
	}
	nn[i]='\0';
	printf("\n");
	//


    //这个上面需要 密码遮掩
	for(i=0;i<user_number;i++)
	{
		if(strcmp(user_num[i].U_account_number,mm)==0&&user_num[i].U_id==0)
		{
			if(strcmp(user_num[i].U_password,nn)==0)
			{
				pppp=1;
				printf("用户姓名:%s\n",user_num[i].U_name);
				printf("乘客信息确认无误  登陆成功!\n");
				printf("任意键加回车,进入系统!\n");
				
				strcpy(user_name,user_num[i].U_name);
				strcpy(user_zhanghu,user_num[i].U_account_number);
				getchar();
				getchar();
				qq_select();
				///
				//
				//
				//
				//
				//
				//没有填写函数
				return;

			}
			
		}
	}
	if(pppp==0)
	{
		printf("没有此人信息!\n");
		printf("任意键加回车,返回上一个界面!\n");
		getchar();
		getchar();
		passenger_sign_in();
	}

}

void staff_register()                      //管理员的注册界面
{
    system("clear");
	char k1[100];    //姓名  
	char kk[100];   //权限的密码
	char mm[100];  //帐号
	char nn[100];  //密码
    char sex[100];  //性别

	int i,j;
	printf("=============================================\n");
	printf("=              管理员的注册界面             =\n");
	printf("=============================================\n");
	printf("请输入你的名字:");
	scanf("%s",k1);
	printf("请输入帐号(手机号):");
	scanf("%s",mm);
	printf("请输入密码:");
	getchar();
	
	i=0;
	j=0;
	while(i<100)
	{
		nn[i]=getch();//getch()从控制台输入一各字符但是不显示 
		if(nn[i]=='\b' && i>0)  //遇到回车不管 
		{
			continue;
		} 
		if(nn[i]=='\b' && i==0)	//如果在最开始就按退格键,就让i=-1 
		{
			i=0;
			continue;
		}
		if(nn[i]=='\r')     //如果输入的是回车,就退出输入循环 
		{
			break;
		}
		i++;
		putchar('*');
	}
	nn[i]='\0';
	printf("\n");
	//

	for(i=0;i<user_number;i++)
	{
		if(strcmp(user_num[i].U_name,mm)==0)
		{
			printf("账户用户已经存在!\n");
			printf("任意按键加回车,重新输入信息!\n");
			getchar();
			//getchar();
			staff_register();
			perror("xi tong bao cuo\n");
			return;
		}
	}
	printf("请输入gw的权限密码:");
	scanf("%s",kk);
	if(strcmp(kk,"666666")==0)
	{
		printf("权限密码正确,确认成功!\n");
	}
	else
	{
		printf("权限密码错误!\n");
		printf("注册失败!\n");
		printf("按下任意键加回车返回上一个界面!\n");
		getchar();
		getchar();
		sign_in_surface();
		return;
	}

	strcpy(user_num[i].U_account_number,mm);  //帐号
	strcpy(user_num[i].U_password,nn);       //密码
	strcpy(user_num[i].U_name,k1);           //姓名
	user_num[i].U_id=1;
	printf("注册的帐号:%s\n",user_num[i].U_account_number);
	printf("注册的密码:%s\n",user_num[i].U_password);
	user_number++;
	printf("注册成功!\n");
	/用户写入文本
    user_input_txt();
	printf("按下任意键加回车返回上一个界面!\n");
	getchar();
	getchar();
	sign_in_surface();
}

void passenger_register()                      //乘客的注册界面
{
     system("clear");
	char k1[100];    //姓名  
	char kk[100];   //权限的密码
	char mm[100];  //帐号
	char nn[100];  //密码
    char sex[100];  //性别

	int i,j;
	printf("=============================================\n");
	printf("=              用户的注册界面               =\n");
	printf("=============================================\n");
	printf("请输入你的名字:");
	scanf("%s",k1);
	printf("请输入帐号(手机号):");
	scanf("%s",mm);
	printf("请输入密码:");
	getchar();
		
	i=0;
	j=0;
	while(i<100)
	{
		nn[i]=getch();//getch()从控制台输入一各字符但是不显示 
		if(nn[i]=='\b' && i>0)  //遇到回车不管 
		{
			continue;
		} 
		if(nn[i]=='\b' && i==0)	//如果在最开始就按退格键,就让i=-1 
		{
			i=0;
			continue;
		}
		if(nn[i]=='\r')     //如果输入的是回车,就退出输入循环 
		{
			break;
		}
		i++;
		putchar('*');
	}
	nn[i]='\0';
	printf("\n");
	//

	for(i=0;i<user_number;i++)
	{
		if(strcmp(user_num[i].U_name,mm)==0)
		{
			printf("账户用户已经存在!\n");
			printf("任意按键加回车,重新输入信息!\n");
			getchar();
			//getchar();
			passenger_register();
			return;
		}
	}


	strcpy(user_num[i].U_account_number,mm);  //帐号
	strcpy(user_num[i].U_password,nn);       //密码
	strcpy(user_num[i].U_name,k1);           //姓名
	user_num[i].U_id=0;
	printf("注册的帐号:%s\n",user_num[i].U_account_number);
	printf("注册的密码:%s\n",user_num[i].U_password);
	user_number++;
	printf("注册成功!\n");
	/用户写入文本
    user_input_txt();
	printf("按下任意键加回车返回上一个界面!\n");
	getchar();
	getchar();
	sign_in_surface();

}
void staff_sign_in()                       //管理员登陆界面
{
       system("clear");
	printf("==================================================\n");
	printf("*            管理员登陆界面                      *\n");
	printf("==================================================\n");
	printf("*          1.注册新的账户                        *\n");
	printf("==================================================\n");
	printf("*          2.进入登陆模式                        *\n");
	printf("==================================================\n");
	printf("*          3.返回上个界面                        *\n");
	printf("==================================================\n");
	printf("请输入数字选择:");
    char kk[1000];
    scanf("%s",kk);
    int a=strlen(kk);
    if(a==1)
    {
        int b=atoi(kk);
        if(b<0||b>3)
        {
            printf("  输入错误!\n");
            printf("任意键加回车,重新进入当前界面\n");
            getchar();
            getchar();
            staff_sign_in();   //重新输入
            return;               //退出程序,防止有bug
        }
        else
        {
            if(b==1)
            {
                staff_register();
            }
            else if(b==2)
            {
                staff_password();
            }
            else if(b==3)
            {
                sign_in_surface(); 
            }
            else
            {
               staff_sign_in();
            }
        }
    }
    else
    {
        printf("  输入错误!\n");
        printf("任意键加回车,重新进入当前界面\n");
        getchar();
        getchar();
        staff_password();  //重新输入
        return;               //退出程序,防止有bug
    }
}


void passenger_sign_in()                       //乘客登陆界面
{
       system("clear");
	printf("==================================================\n");
	printf("*            乘客登陆界面                        *\n");
	printf("==================================================\n");
	printf("*          1.注册新的账户                        *\n");
	printf("==================================================\n");
	printf("*          2.进入登陆模式                        *\n");
	printf("==================================================\n");
	printf("*          3.返回上个界面                        *\n");
	printf("==================================================\n");
	printf("请输入数字选择:");
    char kk[1000];
    scanf("%s",kk);
    int a=strlen(kk);
    if(a==1)
    {
        int b=atoi(kk);
        if(b<0||b>3)
        {
            printf("  输入错误!\n");
            printf("任意键加回车,重新进入当前界面\n");
            getchar();
            getchar();
            passenger_sign_in();  //重新输入
            return;               //退出程序,防止有bug
        }
        else
        {
            if(b==1)
            {
               passenger_register();
            }
            else if(b==2)
            {
                passenger_password();
            }
            else if(b==3)
            {
                sign_in_surface(); 
            }
            else
            {
               passenger_sign_in();
            }
        }
    }
    else
    {
        printf("  输入错误!\n");
        printf("任意键加回车,重新进入当前界面\n");
        getchar();
        getchar();
        passenger_sign_in(); //重新输入
        return;               //退出程序,防止有bug
    }
}




void user_information_initialize()         //用户信息初始化
{
    int i=0;
	FILE* fp=fopen("user_information.txt","r+");
	if(fp==NULL)
	{
		perror("user_information_file error ");
	}
	while(fscanf(fp,"%s %s %s %d",user_num[i].U_name,user_num[i].U_account_number,user_num[i].U_password,&user_num[i].U_id)!=EOF)
	{
		i++;
	}
	user_number=i;
	fclose(fp);
}


void user_input_txt()                     //账户密码信息输入到文件中
{
    int i,k;
	FILE* fp=fopen("user_information.txt","w+");
	if(fp==NULL)
	{
		perror("user_information_file error ");
	}
	for(i=0;i<user_number;i++)
	{
		fprintf(fp,"%15s%30s%30s%10d\n",user_num[i].U_name,user_num[i].U_account_number,user_num[i].U_password,user_num[i].U_id);
	}
	fclose(fp);

}



int getch(void)
{
     struct termios tm, tm_old;
     int fd = 0, ch;
 
     if (tcgetattr(fd, &tm) < 0) {//保存现在的终端设置
          return -1;
     }
 
     tm_old = tm;
     cfmakeraw(&tm);//更改终端设置为原始模式,该模式下所有的输入数据以字节为单位被处理
     if (tcsetattr(fd, TCSANOW, &tm) < 0) {//设置上更改之后的设置
          return -1;
     }
 
     ch = getchar();
     if (tcsetattr(fd, TCSANOW, &tm_old) < 0) {//更改设置为最初的样子
          return -1;
     }
    
     return ch;
}


/*
int main()
{
	
	 user_information_initialize();         //用户信息初始化
	 sign_in_surface();

 	return 0;
}
*/

9.UTP                     (用户私聊功能的文件)

代码:

/************************************************************************************************************************************************************************************************************************
 *文件名:
 *作  者:She001
 *时  间:
 *版  本:
 *作  用:UDP 服务端  接受端一体 
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<sqlite3.h>
//1.UDP 协议 接受端的编程
//1.socket 数据报套接字
//2.bind : 把自己的ip port  绑定好 
//3.recvfrom  读写操作 while(1)  printf() 
//4.close
//
int color=31;
void printf_mig()
{
	printf("============================================================\n");
	printf("=                      聊天室                 =\n");	
	printf("============================================================\n");
	
}

void printf_end()
{
	char w[100];
	printf("============================================================\n");
	printf("============================================================\n");
	printf("请输入内容:");
	fflush(stdout);
}

void printf_out(char *s)
{
	color++;
	if(color>36)
	{
		color=31;
	}
	//printf("============================================================\n");
	printf("\033[%d;40m%s \033[0m",color,s);
}


int sqlite3_input(char *a,char *b,char *c,char *d,char *e )//把用户接受的 写入数据库  a ip  b port    c : name  d : 信息 e: 别人的port
{
	sqlite3 *studb =NULL;
	//下面这个函数 返回0 是执行成功
	int res =sqlite3_open("stu1.db",&studb);// 打开数据库的函数   sqlite3 里面的 agrv[1] (参数传入)
	if(!res)
	{
		//printf("sqlite3_Open  ok\n");//打开成功
	}
	else 
	{
		//printf("sqlite_open error\n");//打开失败
		//printf("errmsg:%s \n",sqlite3_errmsg(studb));//错误信息的返回 函数errmsg
		return -1;
	}

	char * errstr =NULL;
	//先写好操作sqlite3的库的命令
	//const char * stup ="insert into qq_ip_port_port(q_name, q_information )values(\'帅哥\',\'下线\');";
	char stup[1024]="";
	strcat(stup,"insert into qq_");
	strcat(stup,"stu1");
	strcat(stup,"_");
	strcat(stup,b);
	strcat(stup,"_");
	strcat(stup,e);
	strcat(stup,"(q_name,q_information)values(\'");
	strcat(stup,c);
	strcat(stup,"  :");
	strcat(stup,"\',\'");
	strcat(stup,d);
	strcat(stup,"\');");
	//printf("%s\n",stup);


	
	//下面这个函数返回0 是执行成功
	if(!sqlite3_exec(studb,stup,NULL,NULL,&errstr)) //执行命令stup  errstr 是出现错误的时候返回的错误信息
	{
		//printf("opeation  is suceessfuly \n");
	}
	else
	{
		//printf("opeation is failed \n");
		//printf("error: %s\n",errstr);
		return -2;
	}
	sqlite3_close(studb);
	return 1;
}

void create_table_stu1(char* a,char *b,char *c)//a: ip  b:port  c: 别人的port //创造一个表 
{
	sqlite3 *studb =NULL;
	//下面这个函数 返回0 是执行成功
	int res =sqlite3_open("stu1.db",&studb);// 打开数据库的函数   sqlite3 里面的 agrv[1] (参数传入)
	if(!res)
	{
	//	printf("sqlite3_Open  ok\n");//打开成功
	}
	else 
	{
		//printf("sqlite_open error\n");//打开失败
	//	printf("errmsg:%s \n",sqlite3_errmsg(studb));//错误信息的返回 函数errmsg
		return ;
	}

	char * errstr =NULL;
	//char * create_table ="create table qq_ip_port_port(q_name text , q_information text);";
	char  create_table[1024]="";
	char  ip1[1024]="";
	char  port1[1024]="";
	strcat(ip1,a);//ip
	strcat(port1,b);//port
	
	strcat(create_table,"create table qq_");
	strcat(create_table,"stu1");
	strcat(create_table,"_");
	strcat(create_table,port1);
	strcat(create_table,"_");
	strcat(create_table,c);
	strcat(create_table,"(q_name text,q_information text);");
	//printf("%s\n",create_table);
	if(!sqlite3_exec(studb,create_table,NULL,NULL,&errstr))//创建一个表来存储信息
	{
		//printf("create ta  ble  is suceessfuly \n");
	}
	else
	{
		//printf("create_table is failed \n");
	///	printf("error: %s\n",errstr);
	}
	sqlite3_close(studb);

}


void read_table_stu1(char *a,char* b,char *c )//a :ip  b: port c :别人的port  //从表里面读取数据
{
	sqlite3 *studb =NULL;
	//下面这个函数 返回0 是执行成功
	int res =sqlite3_open("stu1.db",&studb);// 打开数据库的函数   sqlite3 里面的 agrv[1] (参数传入)
	if(!res)
	{
		//printf("sqlite3_Open  ok\n");//打开成功
	}
	else 
	{
		printf("sqlite_open error\n");//打开失败
		printf("errmsg:%s \n",sqlite3_errmsg(studb));//错误信息的返回 函数errmsg
		return ;
	}

	char * errstr =NULL;
	 //char *look = "select * from qq_ip_port_port";//查看所有的列
	char look[1024]="";
    	char ** paz_result;

    	int hang;//用于存放获取到的总个数
   	 int lie;//用于存放一列表的个数
	strcat(look,"select * from qq_");
	strcat(look,"stu1");
	strcat(look,"_");
	strcat(look,b);
	strcat(look,"_");
	strcat(look,c);
	//printf("%s\n",look);

    //将数据库内容传到C变量里
    if(SQLITE_OK != sqlite3_get_table(studb,look,&paz_result,&hang,&lie,&errstr))
    {
        //打印错误信息
        fprintf(stderr,"数据库操作错误\n%s\n",errstr);  //输入到标准报错里面

        //释放掉错误区域内存,防止内存溢出
        sqlite3_free(errstr);

        return;
    }

    

    int i,j,index = 0;
	//system("clear");
	//printf_mig();
    for ( i = 0; i <= hang; i++)//默认会少打印一行,所以 i <= hang
    {
		color++;
		if(color>36)
		{
			color=31;
		}
        for ( j = 0; j < lie; j++)
        {
            printf("\033[%d;40m %s \033[0m",color,paz_result[index]);
            index++;
        }
		fflush(stdout);
		if(i==0)
		{
			system("clear");
			printf_mig();
			system("clear");
			printf_mig();
		}
    }
	printf_end();
	sqlite3_close(studb);

}





int main(int argc,char *argv[])//1 自己的 ip  2 自己的port  3 自己的name    4 别人的ip  5 别人的port  6 别人的name
{
	if(argc <7)
	{
		perror("argc error\n");
		return -1;
	}
	int cid = socket(AF_INET,SOCK_DGRAM,0);
	if(cid ==-1)
	{
		perror("cid error\n");
		return -2;
	}
	printf("socket ok\n");
	struct sockaddr_in caddr={0};
	caddr.sin_family =AF_INET;
	caddr.sin_port =htons(atoi(argv[2]));
	caddr.sin_addr.s_addr =inet_addr(argv[1]);

	if(bind(cid,(struct sockaddr*)&caddr,sizeof(caddr))<0)
	{
		perror("bind error\n");
		return -2;
	}
	printf("bind success\n");
	//
	create_table_stu1(argv[1],argv[2],argv[5]);//建立一个表 ,也可以是查看这个表存在不
	fd_set rset = {0} ; 	//这个是描述符集合,把所有描述符放在这里面。
	struct timeval tm = {0} ; //设定超时时间

	///
	char buff[1280]="";
	struct sockaddr_in saddr={0};
	saddr.sin_family =AF_INET;
	saddr.sin_port =htons(atoi(argv[5]));
	saddr.sin_addr.s_addr =inet_addr(argv[4]);
	int size =sizeof(saddr);
	char ip[128]="";
	int hh=1;
	int len;

	
			if(hh==1)
			{
				hh=0;
				pid_t pid=fork();
				if(pid==0)
				{
					while(1)
					{
						int fanhui=0;
						bzero(buff,sizeof(buff));
						recvfrom(cid,buff,sizeof(buff)-1,0,(struct sockaddr*)&caddr,&size);
						printf("%s\n",buff);
						while(1)
						{
							fanhui=sqlite3_input(argv[1],argv[2],argv[6],buff,argv[5]);//向数据库写入数据
							if(fanhui==1)
							{
								break;
							}
						}
						read_table_stu1(argv[1],argv[2],argv[5]);
						//printf("%d  %s\n",ntohs(saddr.sin_port),inet_ntop(AF_INET,&saddr.sin_addr.s_addr,ip,20));
					}
				}
				if(pid>0)
				{
					while(1)
					{
						int fanhui=0;
						//把键盘文件添加到描述符号集合中
						FD_SET(STDIN_FILENO,&rset);
						tm.tv_sec =10;  //设定超时时间,如果3s内没有动静,就立刻返回
						int count =select(STDIN_FILENO + 1,&rset,NULL,NULL,&tm);//看描述符号里面信号有没有动静
						//printf("count =%d\n",count);
						if(FD_ISSET(STDIN_FILENO,&rset))
						{
							fgets(buff,sizeof(buff),stdin);
							sendto(cid,buff,strlen(buff),0,(struct sockaddr*)&saddr,sizeof(struct sockaddr));	
						//	sqlite3_input(argv[1],argv[2],argv[3],buff);//向数据库写入数据
							while(1)
							{
								fanhui=sqlite3_input(argv[1],argv[2],argv[3],buff,argv[5]);//向数据库写入数据
								if(fanhui==1)
								{
									break;
								}
							}
							read_table_stu1(argv[1],argv[2],argv[5]);	
						}
						if(!strncmp(buff,"quit",4))
						{
							kill(pid,SIGKILL);
							printf("退出!\n");
							exit(0);
						}
						//printf("send : %s \n",buff);
						memset(buff,0,sizeof(buff));			
					}
				}
	}
						close(cid);

       return 0;

}

6.注意事项 。

1.自己的IP  请输入正确!

2.注意,客户端不要异常退出!,请输入quit 退出!

3.服务器。请输入ctrl + z 信号捕捉之后退出! 

  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值