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));//错误信息的返回 函数errmsgreturn ;}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));//错误信息的返回 函数errmsgreturn ;}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));//错误信息的返回 函数errmsgreturn ;}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中的"-"数量相匹配,两者相乘等于100const int Step = 5;// 总共需要多少进度标志,即LastStr中"-"的数量const int iconMaxNum = 20;// 每隔100ms打印一次,这里同时每隔200ms会让进度加1printf("正在进入服务器:");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);//服务端的sidif(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); //网络字节序,转化为主机字节序的ipttt=ntohl(client_addr.sin_port);//网络字节序的port 转化为主机字节序的portstrcpy(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_fileqq : user.o main.o gcc -g -o qq user.o main.o
user.o :user.cgcc -g -c user.c -o user.o
main.o: main.cgcc -g -c main.c -o main.ofuq:fuq.ogcc -g -pthread  -o fuq fuq.o -l sqlite3
fuq.o:fuq.cgcc -g -c  fuq.c -pthread  -o  fuq.o -l sqlite5khd:khd.ogcc -g -pthread  -o khd khd.o -l sqlite3
khd.o:khd.cgcc -g -c  khd.c -pthread  -o  khd.o -l sqlite3UTP:UTP.ogcc -g -pthread  -o UTP UTP.o -l sqlite3
UTP.o:UTP.cgcc -g -c  UTP.c -pthread  -o  UTP.o -l sqlite3UDP_file:UDP_file.ogcc -g -pthread  -o UDP_file UDP_file.o -l sqlite3
UDP_file.o:UDP_file.cgcc -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];//ipchar port[1000];//portsystem("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];//portprintf("请输入服务器的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];//portchar name[1000];//namechar ip1[1000]; //ip char port1[1000];//portchar name1[1000];//nameprintf("为了确保网络信息的安全,私聊信息要输入的详细一点!,请您见谅!\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];//portchar ip1[1000]; //ip char port1[1000];//portprintf("为了确保网络信息的安全,私聊信息要输入的详细一点!,请您见谅!\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));//错误信息的返回 函数errmsgreturn -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));//错误信息的返回 函数errmsgreturn ;}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);//ipstrcat(port1,b);//portstrcat(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));//错误信息的返回 函数errmsgreturn ;}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 信号捕捉之后退出!

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

  1. Linux系统Vi/Vim编辑器的简单介绍、安装/卸载、常用命令

    Linux系统Vi/Vim编辑器的简单介绍.安装/卸载.常用命令 1.介绍 vi(Visual Interface)编辑器是Linux和Unix上最基本的文本编辑器,工作在字符模式下.由于不需要图形界 ...

  2. linux下vim编辑器插件,为你介绍Linux系统中vim编辑器的实用插件!

    今天小编要跟大家分享的文章是关于Linux系统中vim编辑器的实用插件.Vim 是 Linux 下的常用文本编辑器,但也经常被称为是一个上古神器,因为它对于初学者而言相当不友好,也不好入门. Linu ...

  3. Linux学习之Vim编辑器

    Linux学习之Vim编辑器 输入模式-Esc键–>命令模式 末行模式-Esc键–>命令模式 命令模式-a,i,o等键–>输入模式模式 命令模式- :键 -->末行模式 命令模 ...

  4. linux vim修改字符串,Linux系统vi(vim)编辑器命令说明

    Linux系统vi(vim)编辑器命令说明 刘大喵 • 2019 年 02 月 06 日 vi(vim)是上Linux非常常用的代码编辑器,很多Linux发行版都默认安装了vi(vim).vi(vim ...

  5. Linux嵌入式开发——vim编辑器

    文章目录 Linux嵌入式开发--vim编辑器 准备操作 使用 打开 工作模式 一般模式 编辑模式 命令行模式 保存退出 其他操作方式 Linux嵌入式开发--vim编辑器 准备操作 首先我们需要安装 ...

  6. Linux中设置tab4个空格,Linux怎么在VIM编辑器中修改Tab为4个空格

    摘要 腾兴网为您分享:Linux怎么在VIM编辑器中修改Tab为4个空格,云景任务,壹学车,围棋宝典,腾讯qq等软件知识,以及临沂市教育收费,美矣收银系统,我的世界rpgitem,来电归属地显示,盘古 ...

  7. Linux知识之vim编辑器

    文章目录 一.vi与vim文本编辑器 1.什么是文本编辑器 2.vi/vim编辑器简介及区别 2.1 简介 2.2 vi与vim的区别 二.vim编辑器 2.1 vim编辑器使用指南 2.2 进入文件 ...

  8. Linux工具之Vim编辑器

    Vim工具 关于Vim Vim是Linux系统下一款功能强大的编辑器,在Vi的基础上改进和增加了许多特性. Vim的三种模式 编辑模式. 输入模式. 末行模式. 三种模式之间的关系如下图: 三种模式之 ...

  9. linux进入了vim强制退出,linux中的vim编辑器怎么强制退出

    linux中的vim编辑器怎么强制退出 发布时间:2020-07-02 15:31:10 来源:亿速云 阅读:176 作者:元一 linux中的vim编辑器怎么强制退出?很多新手对此不是很清楚,为了帮 ...

  10. Linux环境下——C语言聊天室项目

    由于使用了多线程操作,客户端进入程序后请先随便注册一次用户后再进行使用. 本程序默认第一个用户即ID为1的用户为超级管理员. 由于线程阻塞,最后的踢人操作有阻塞,需要在被踢出在线链表后手动下线. 看了 ...

最新文章

  1. 如何修改Linux主机名
  2. 使用flexible适配移动端h5页面
  3. fileset java_Java FileSet.iterator方法代码示例
  4. 直播预告 | AAAI 2022论文解读:基于对比学习的预训练语言模型剪枝压缩
  5. ngixn+tomcat负载均衡 动静分离配置 (nginx反向代理)
  6. python-opencv图像处理之用于跟踪的Shi-Tomasi拐角探测器
  7. 环境变量的配置windows10系统
  8. 甘肃省计算机能力vf考试题库,计算机等级考试二级VF模拟试题十及答案解析
  9. 笔记本平板电脑推荐_平板电脑推荐表(2020.618)
  10. BZOJ4029: [HEOI2015]定价
  11. Redhat 5.4 安装vsftp
  12. BZOJ3309 DZY Loves Math 【莫比乌斯反演】
  13. Android趣味课程:超简单猜数游戏
  14. jdk+jmeter下载安装教程
  15. 复工复产到欧洲,深兰科技环卫产品亮相国际舞台
  16. 对Excel进行瘦身的两个方法
  17. 小草手把手教你 LabVIEW 串口仪器控制——VISA 串口配置
  18. 力扣K神图解算法数据结构解析04
  19. weblogic11g 后台无需密码启动设置
  20. Ubuntu死机卡死问题

热门文章

  1. win10专业版与家庭版有什么不一样
  2. 扫雷可以用计算机,接龙扫雷Windows经典游戏原来还有这些用处啊
  3. 3DMine V202006体验版本下载
  4. 软件测试中期答辩,中期答辩材料创新张颖
  5. Windows10 查看电脑关机时间(提交忘记打卡申请必备)
  6. 5S定置管理协调现场的三大元素
  7. 手把手教你如何复现MS17-010永恒之蓝漏洞
  8. abb机器人编程指令写字_ABB 机器人编程指令.pdf
  9. php私人云,PHP源码Cloudreve乐云网盘私人云盘源码 资源下载不限速功能
  10. prewitt算子实现