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));//错误信息的返回 函数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 聊天室项目相关推荐
- Linux系统Vi/Vim编辑器的简单介绍、安装/卸载、常用命令
Linux系统Vi/Vim编辑器的简单介绍.安装/卸载.常用命令 1.介绍 vi(Visual Interface)编辑器是Linux和Unix上最基本的文本编辑器,工作在字符模式下.由于不需要图形界 ...
- linux下vim编辑器插件,为你介绍Linux系统中vim编辑器的实用插件!
今天小编要跟大家分享的文章是关于Linux系统中vim编辑器的实用插件.Vim 是 Linux 下的常用文本编辑器,但也经常被称为是一个上古神器,因为它对于初学者而言相当不友好,也不好入门. Linu ...
- Linux学习之Vim编辑器
Linux学习之Vim编辑器 输入模式-Esc键–>命令模式 末行模式-Esc键–>命令模式 命令模式-a,i,o等键–>输入模式模式 命令模式- :键 -->末行模式 命令模 ...
- linux vim修改字符串,Linux系统vi(vim)编辑器命令说明
Linux系统vi(vim)编辑器命令说明 刘大喵 • 2019 年 02 月 06 日 vi(vim)是上Linux非常常用的代码编辑器,很多Linux发行版都默认安装了vi(vim).vi(vim ...
- Linux嵌入式开发——vim编辑器
文章目录 Linux嵌入式开发--vim编辑器 准备操作 使用 打开 工作模式 一般模式 编辑模式 命令行模式 保存退出 其他操作方式 Linux嵌入式开发--vim编辑器 准备操作 首先我们需要安装 ...
- Linux中设置tab4个空格,Linux怎么在VIM编辑器中修改Tab为4个空格
摘要 腾兴网为您分享:Linux怎么在VIM编辑器中修改Tab为4个空格,云景任务,壹学车,围棋宝典,腾讯qq等软件知识,以及临沂市教育收费,美矣收银系统,我的世界rpgitem,来电归属地显示,盘古 ...
- Linux知识之vim编辑器
文章目录 一.vi与vim文本编辑器 1.什么是文本编辑器 2.vi/vim编辑器简介及区别 2.1 简介 2.2 vi与vim的区别 二.vim编辑器 2.1 vim编辑器使用指南 2.2 进入文件 ...
- Linux工具之Vim编辑器
Vim工具 关于Vim Vim是Linux系统下一款功能强大的编辑器,在Vi的基础上改进和增加了许多特性. Vim的三种模式 编辑模式. 输入模式. 末行模式. 三种模式之间的关系如下图: 三种模式之 ...
- linux进入了vim强制退出,linux中的vim编辑器怎么强制退出
linux中的vim编辑器怎么强制退出 发布时间:2020-07-02 15:31:10 来源:亿速云 阅读:176 作者:元一 linux中的vim编辑器怎么强制退出?很多新手对此不是很清楚,为了帮 ...
- Linux环境下——C语言聊天室项目
由于使用了多线程操作,客户端进入程序后请先随便注册一次用户后再进行使用. 本程序默认第一个用户即ID为1的用户为超级管理员. 由于线程阻塞,最后的踢人操作有阻塞,需要在被踢出在线链表后手动下线. 看了 ...
最新文章
- 如何修改Linux主机名
- 使用flexible适配移动端h5页面
- fileset java_Java FileSet.iterator方法代码示例
- 直播预告 | AAAI 2022论文解读:基于对比学习的预训练语言模型剪枝压缩
- ngixn+tomcat负载均衡 动静分离配置 (nginx反向代理)
- python-opencv图像处理之用于跟踪的Shi-Tomasi拐角探测器
- 环境变量的配置windows10系统
- 甘肃省计算机能力vf考试题库,计算机等级考试二级VF模拟试题十及答案解析
- 笔记本平板电脑推荐_平板电脑推荐表(2020.618)
- BZOJ4029: [HEOI2015]定价
- Redhat 5.4 安装vsftp
- BZOJ3309 DZY Loves Math 【莫比乌斯反演】
- Android趣味课程:超简单猜数游戏
- jdk+jmeter下载安装教程
- 复工复产到欧洲,深兰科技环卫产品亮相国际舞台
- 对Excel进行瘦身的两个方法
- 小草手把手教你 LabVIEW 串口仪器控制——VISA 串口配置
- 力扣K神图解算法数据结构解析04
- weblogic11g 后台无需密码启动设置
- Ubuntu死机卡死问题