1.功能有哪些:
1.用户登录功能
2.创建多用户连接的服务端
3.创建服务端
4.私聊功能
5.文件传送功能
2.思维导图:
1.
2.
3.
4.
5.
3.程序运行的必要条件:
1. Linux 安装好 sqlite3 数据库
2. 有 vim 编辑器
4.文件清单:
1.cursor_color.h (光标移动的头文件)
2.fuq.c (TCP 群聊服务器 )
3.khd.c (TCP 群聊客户端)
4.main.c (主函数,程序接口)
5.makefile (程序编译文件 生成可执行的文件)
6.UDP_file.c (私聊发送文件)
7.user.h (用户登录界面的头文件)
8.user.c
9.UTP (用户私聊功能的文件)
5.
代码:
1.cursor_collor 文件
/************************************************************************************************************************************************************************************************************************
*文件名:
*作 者:She001
*时 间:
*版 本:
*作 用:
****************************************************************************************************************************************************************************************************************************/
#ifndef __CURSOR_COLOR_H__
#define __CURSOR_COLOR_H__
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include <stdio.h>
//清屏
#define CLEAR() printf("\033[2J")
// 上移光标
#define MOVEUP(x) printf("\033[%dA", (x))
// 下移光标
#define MOVEDOWN(x) printf("\033[%dB", (x))
// 左移光标
#define MOVELEFT(y) printf("\033[%dD", (y))
// 右移光标
#define MOVERIGHT(y) printf("\033[%dC",(y))
// 定位光标
#define MOVETO(x,y) printf("\033[%d;%dH", (x), (y))
// 光标复位
#define RESET_CURSOR() printf("\033[H")
// 隐藏光标
#define HIDE_CURSOR() printf("\033[?25l")
// 显示光标
#define SHOW_CURSOR() printf("\033[?25h")
//清除从光标到行尾的内容
#define CLEAR_LINE() printf("\033[K")
//反显
#define HIGHT_LIGHT() printf("\033[7m")
#define UN_HIGHT_LIGHT() printf("\033[27m")
//设置颜色
#define SET_FRONT_COLOR(color) printf("\033[%dm",(color))
#define SET_BACKGROUND_COLOR(color) printf("\033[%dm",(color))
//前景色
#define FRONT_BLACK 30
#define FRONT_RED 31
#define FRONT_GREEN 32
#define FRONT_YELLOW 33
#define FRONT_BLUE 34
#define FRONT_PURPLE 35
#define FRONT_DEEP_GREEN 36
#define FRONT_WHITE 37
//背景色
#define BACKGROUND_BLACK 40
#define BACKGROUND_RED 41
#define BACKGROUND_GREEN 42
#define BACKGROUND_YELLOW 43
#define BACKGROUND_BLUE 44
#define BACKGROUND_PURPLE 45
#define BACKGROUND_DEEP_GREEN 46
#define BACKGROUND_WHITE 47
#endif
2.fuq.c (TCP 群聊服务器 )
代码:
/************************************************************************************************************************************************************************************************************************
*文件名:
*作 者:She001
*时 间:
*版 本:
*作 用:多人聊天的服务器
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<sqlite3.h>
//1.创建锁 申请互斥锁
pthread_mutex_t mutex =PTHREAD_MUTEX_INITIALIZER;
struct information
{
int num;//第几条信息
char infor[1024];//信息的内容
}PP[10000];
int information_num=0;//信息的个数
char fppp[1000]="";
struct fuq
{
int cid; //把所有的accept 返回的套接字存储,用来发送信息,
char c_name[1024];//cid 的名字
char c_ip[1024];//cid 的ip;
int c_port;//cid的port
}cid_arry[10000];
int cid_number=0; //客户端的个数
char qingchu[128]="clear-input";
char jieshu[128]="exit-out";
char kong[10]="";
void send_out_quit();
void sigfun(int signo)
{
if(signo ==SIGTSTP)
{
printf("强制退出!\n");
send_out_quit();
getchar();
getchar();
exit(0);
}
}
char* time1()
{
//FILE* fp =fopen("1.txt","a+");
time_t tm1 =time(NULL); //输出函
struct tm* timp =gmtime(&tm1);
sprintf(fppp,"year: %d month: %d day:%d hour: %d min:%d sec:%d ",timp->tm_year+1900,timp->tm_mon+1,timp->tm_mday,(timp->tm_hour+8)%24,timp->tm_min,timp->tm_sec);
return fppp;
}
void sqlite3_create_table()//确保创建一个表
{
sqlite3 *studb =NULL;
//下面这个函数 返回0 是执行成功
int res =sqlite3_open("stu.db",&studb);// 打开数据库的函数 sqlite3 里面的 agrv[1] (参数传入)
if(!res)
{
// printf("sqlite3_Open ok\n");//打开成功
}
else
{
//printf("sqlite_open error\n");//打开失败
// printf("errmsg:%s \n",sqlite3_errmsg(studb));//错误信息的返回 函数errmsg
return ;
}
char * errstr =NULL;
//char * create_table ="create table stu_xinxi(s_name,s_ip,s_time,s_caozuo);";
char create_table[1024]="";
strcat(create_table,"create table ");
strcat(create_table,"stu_xinxi");
strcat(create_table,"(s_name,s_ip,s_time,s_caozuo);");
//printf("%s\n",create_table);
if(!sqlite3_exec(studb,create_table,NULL,NULL,&errstr))//创建一个表来存储信息
{
//printf("create ta ble is suceessfuly \n");
}
else
{
//printf("create_table is failed \n");
/// printf("error: %s\n",errstr);
}
sqlite3_close(studb);
}
void sqlite3_input_shangxian(char *a ,char *b)//把用户的登陆或者下线信息 写入数据库 a 名字 b ip
{
sqlite3 *studb =NULL;
//下面这个函数 返回0 是执行成功
int res =sqlite3_open("stu.db",&studb);// 打开数据库的函数 sqlite3 里面的 agrv[1] (参数传入)
if(!res)
{
//printf("sqlite3_Open ok\n");//打开成功
}
else
{
printf("sqlite_open error\n");//打开失败
printf("errmsg:%s \n",sqlite3_errmsg(studb));//错误信息的返回 函数errmsg
return ;
}
char * errstr =NULL;
//先写好操作sqlite3的库的命令
char* time=time1();
//const char * stup ="insert into stu_xinxi(s_name,s_ip,s_time,s_caozuo)values(\'帅哥\',\'192.168.1.162 \',\'13:12:12\',\'下线\');";
char stup[1024]="";
strcat(stup,"insert into stu_xinxi(s_name,s_ip,s_time,s_caozuo)values(\'");
strcat(stup,a);
strcat(stup,"\',\'");
strcat(stup,b);
strcat(stup,"\',\'");
strcat(stup,time);
strcat(stup,"\',\'");
strcat(stup,"上线\');");
//下面这个函数返回0 是执行成功
if(!sqlite3_exec(studb,stup,NULL,NULL,&errstr)) //执行命令stup errstr 是出现错误的时候返回的错误信息
{
//printf("opeation is suceessfuly \n");
}
else
{
printf("opeation is failed \n");
printf("error: %s\n",errstr);
}
sqlite3_close(studb);
}
void sqlite3_input_xiaxian(char *a ,char *b)//把用户的登陆或者下线信息 写入数据库 a 名字 b ip
{
sqlite3 *studb =NULL;
//下面这个函数 返回0 是执行成功
int res =sqlite3_open("stu.db",&studb);// 打开数据库的函数 sqlite3 里面的 agrv[1] (参数传入)
if(!res)
{
//printf("sqlite3_Open ok\n");//打开成功
}
else
{
printf("sqlite_open error\n");//打开失败
printf("errmsg:%s \n",sqlite3_errmsg(studb));//错误信息的返回 函数errmsg
return ;
}
char * errstr =NULL;
//先写好操作sqlite3的库的命令
char* time=time1();
//const char * stup ="insert into stu_xinxi(s_name,s_ip,s_time,s_caozuo)values(\'帅哥\',\'192.168.1.162 \',\'13:12:12\',\'下线\');";
char stup[1024]="";
strcat(stup,"insert into stu_xinxi(s_name,s_ip,s_time,s_caozuo)values(\'");
strcat(stup,a);
strcat(stup,"\',\'");
strcat(stup,b);
strcat(stup,"\',\'");
strcat(stup,time);
strcat(stup,"\',\'");
strcat(stup,"下线\');");
//下面这个函数返回0 是执行成功
if(!sqlite3_exec(studb,stup,NULL,NULL,&errstr)) //执行命令stup errstr 是出现错误的时候返回的错误信息
{
//printf("opeation is suceessfuly \n");
}
else
{
printf("opeation is failed \n");
printf("error: %s\n",errstr);
}
sqlite3_close(studb);
}
void progress_bar() //进度条
{
// ****************************** 配置 ***************************
// 最后100%时的输出形式
const char *LastStr = "[--------------------] 100%";
// 进度条标志,可以改用"*"或其它符号
const char Progressicon = '-';
// 进度每加5,进度条就会加一格,注意Step值要和LastStr中的"-"数量相匹配,两者相乘等于100
const int Step = 5;
// 总共需要多少进度标志,即LastStr中"-"的数量
const int iconMaxNum = 20;
// 每隔100ms打印一次,这里同时每隔200ms会让进度加1
printf("正在进入服务器:");
const int Printinterval = 20000;
// ****************************************************************
for (int i = 0; i <= 100; ++i)
{
// -------------- 打印进度条 --------------
printf("[");
int currentindex = i / Step;
for (int j = 0; j < iconMaxNum; ++j)
{
if (j < currentindex)
{
printf("%c", Progressicon); // 打印进度条标志
}
else
{
printf(" "); // 未达进度则打印空格
}
}
printf("] ");
// ----------------------------------------
// -------- 打印数字进度 ----------
printf("%3d%%", i);
fflush(stdout);
// -------------------------------
usleep(Printinterval);
for (int j = 0; j < strlen(LastStr); ++j)
{
printf("\b"); // 回删字符,让数字和进度条原地变化 "\b"控制光标前移一个字符
}
fflush(stdout);
}
printf("\n");
}
void tt_input(int c) //把数据输入到文件 ,删除文件的时候用
{
int i,k;
FILE* fp=fopen("fwq.txt","a+");
if(fp==NULL)
{
perror("fwq error ");
}
fprintf(fp,"%d\t%s\n",PP[c].num,PP[c].infor);
fclose(fp);
}
void tt_output()//信息的提取
{
int i=0;
FILE*fp=fopen("fwq.txt","r+");
information_num=0;
while(fscanf(fp,"%d %s\n",&PP[i].num,PP[i].infor)!=EOF)
{
i++;
}
information_num=i;
}
void send_out_quit()//把退出信息的所有的信息发送给用户
{
char buff[1024]="";
int i,j,k;
for(i=0;i<cid_number;i++)
{
memset(buff,0,sizeof(buff));//退出的信息
strcat(buff,"quit");
send(cid_arry[i].cid,buff,strlen(buff),0);//发送信息
usleep(10000);
}
}
void send_out()//把文本的所有的信息发送给用户
{
char buff[1024]="";
int i,j,k;
for(i=0;i<cid_number;i++)
{
memset(buff,0,sizeof(buff));
send(cid_arry[i].cid,qingchu,strlen(qingchu),0);//发送清除客户端的命令
usleep(10000);
for(k=0;k<information_num;k++)
{
memset(buff,0,sizeof(buff));
strcat(buff,PP[k].infor);
send(cid_arry[i].cid,buff,strlen(buff),0);//发送信息
usleep(10000);
}
send(cid_arry[i].cid,jieshu,strlen(jieshu),0);//发送结束客户端的命令
usleep(10000);
}
}
void information_cunchu(char* a,char *b)//发送的信息存入到文件
{
char buff[1024]="";
PP[information_num].num=information_num;
strcat(buff,a);
strcat(buff,":");
strcat(buff,b);
strcpy(PP[information_num].infor,buff);
information_num++;
int c= information_num-1;
tt_input(c);
}
char *return_name(int cid)//返回 cid 对应人的name
{
for(int i=0;i<cid_number;i++)
{
if(cid==cid_arry[i].cid)
{
return cid_arry[i].c_name;
}
}
return NULL;
}
char *return_ip(int cid)//返回 cid 对应人的ip
{
for(int i=0;i<cid_number;i++)
{
if(cid==cid_arry[i].cid)
{
return cid_arry[i].c_ip;
}
}
return NULL;
}
int return_port(int cid)//返回 cid 对应的port
{
for(int i=0;i<cid_number;i++)
{
if(cid==cid_arry[i].cid)
{
return cid_arry[i].c_port;
}
}
}
void *pthread_fun(void* arg)
{
int cid =*((int *)arg);
char buff[128]="";
int len =0;
char sendbuff[128]="";
while(strncmp(buff,"quit",4))
{
bzero(buff,sizeof(buff));
bzero(sendbuff,sizeof(sendbuff));
//printf("正在等待!\n");
int len = recv(cid,buff,sizeof(buff),0);//接受信息
//information(return_name(cid),buff);//把接送的信息发送到文件
/
while(pthread_mutex_trylock(&mutex));//上锁
//
///
if(strncmp(buff,"quit",4)==0||len<=0)//删除已经关闭的终端
{
sqlite3_input_xiaxian(return_name(cid),return_ip(cid));
int a=return_port(cid);
char sop[100]="";
sprintf(sop,"%d",a);
strcat(sendbuff,return_name(cid));
strcat(sendbuff," ");
strcat(sendbuff,return_ip(cid));
strcat(sendbuff," ");
strcat(sendbuff,sop);
strcat(sendbuff," : ");
strcat(sendbuff,"退出聊天室!\n");
printf("%s\n",sendbuff);
information_cunchu(kong,sendbuff);
for(int kk=0;kk<cid_number;kk++)
{
if(cid_arry[kk].cid==cid)
{
for(int ll=kk;ll<cid_number;ll++)
{
cid_arry[ll]=cid_arry[ll+1];
}
break;//关闭无限循环 防止报错
}
}
cid_number--;
send_out();//发送信息
}
else
{
information_cunchu(return_name(cid),buff);//存放信息
send_out();//发送信息
}
///
//
printf("cid =%d buff=%s\n ",cid,buff);//打印信息
pthread_mutex_unlock(&mutex); //解锁
//
}
shutdown(cid,SHUT_RDWR);//退出循环之后,关闭文件描述符号
return NULL;
}
int main(int argc,char *argv[])
{
//参数判断
if(argc <3)
{
perror("agc error\n");
printf("argc :%d\n",argc);
printf("参数错误!\n");
getchar();
return -1;
}
//1.创建套接字
int sid =socket(AF_INET,SOCK_STREAM,0);//服务端的sid
if(sid<0)
{
perror("socket error\n");
printf("套接字申请失败!\n");
getchar();
return -2;
}
printf("socket ok\n");
//printf("sid=%d\n",sid);
//2.绑定 bind 函数经常失败
struct sockaddr_in server_addr={0};
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(atoi(argv[2])); //端口号的转换 字符串-主机整数--网络整数
server_addr.sin_addr.s_addr=inet_addr(argv[1]);//主机字符串 --网络字节序
int reslg=bind(sid,(struct sockaddr*)&server_addr,sizeof(server_addr));
if(reslg==-1)
{
perror("bind error\n");
printf("绑定失败!\n");
getchar();
return -2;
}
printf("bind success ok\n");
//3.监听 listen
if(listen(sid,10)<0)
{
perror("listen error\n");
printf("监听失败!\n");
getchar();
return -3;
}
printf("listen ok\n");
//4.accept()
//建立连接
struct sockaddr_in client_addr ={0};//accept 的准备工作
int size =sizeof(client_addr); //accept 的第三个参数
/初始化锁
//2.初始化锁
if(pthread_mutex_init(&mutex,NULL)<0)
{
perror("pthrrad_mutex_init error\n");
return -1;
}
else
{
printf("pthread_mutex_init ok !\n");
}
/
signal(SIGTSTP,sigfun);//信号捕捉
sqlite3_create_table();
/
progress_bar();
printf("欢迎来到QQ 聊天室的服务器 !\n");
/
//5.循环登陆功能
char buff[1024];
int len=0;
char sendbuff[1024]="";
int cid;//客户端套接字
pthread_t tid=0;
char kkk[1000]="";
char t1[1000]="";
char ntop[1024]="";
int ttt;
while(1)
{
bzero(buff,sizeof(buff));
cid=accept(sid,(struct sockaddr*)&client_addr,&size);
recv(cid,buff,sizeof(buff),0);
if(strncmp(buff,"quit",4)==0)
{
continue;
}
printf("user is cid =%d \n",cid);
if(cid!=-1)
{
const char* ipstr = inet_ntop(AF_INET,&client_addr.sin_addr.s_addr,ntop,sizeof(ntop));
strcpy(kkk,ntop); //网络字节序,转化为主机字节序的ip
ttt=ntohl(client_addr.sin_port);//网络字节序的port 转化为主机字节序的port
strcpy(cid_arry[cid_number].c_ip,kkk);
cid_arry[cid_number].c_port=ttt;
cid_arry[cid_number].cid=cid;
strcpy(cid_arry[cid_number].c_name,buff);
cid_number++;
}
sqlite3_input_shangxian(buff ,kkk);
printf("cid = %d 连接成功!\n",cid);
//pid_t pid = fork();只能用线程做
if(cid!=-1)
{
//客户连接成功!
char jj[1000]="";
strcat(jj,buff);
strcat(jj," ");
strcat(jj,kkk);
sprintf(t1,"%d",ttt);
strcat(jj," ");
strcat(jj,t1);
strcat(jj,"欢迎用户进入聊天室!\n");
printf("%s\n",jj);
//登陆信息存入文件
information_cunchu(kong,jj);
send_out();//发送信息
pthread_create(&tid,NULL,pthread_fun,&cid);//建立线程
}
}
return 0;
}
3.khd.c (TCP 群聊客户端)
代码:
/************************************************************************************************************************************************************************************************************************
*文件名:
*作 者:She001
*时 间:
*版 本:
*作 用:客户端
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include"cursor_color.h"
int color =31;
void printf_mig()
{
printf("============================================================\n");
printf("= 聊天室 =\n");
printf("============================================================\n");
}
void printf_end()
{
char w[100];
printf("============================================================\n");
printf("============================================================\n");
printf("请输入内容:");
fflush(stdout);
}
void printf_out(char *s)
{
color++;
if(color>36)
{
color=31;
}
//printf("============================================================\n");
printf("\033[%d;40m%s \033[0m",color,s);
}
void sigfun(int signo)
{
//子进程在退出的时候,会给父进程发送 SIGCHLD 忽略信号
if(signo == SIGCHLD)
{
exit(0);
}
}
int main(int argc,char *argv[])
{
int sockfd;
struct sockaddr_in servaddr;
if(argc<4)
{
printf("argc error!\n");
printf("参数传输错误!\n");
return -1;
}
else
{
printf("参数正确,传输成功!\n");
}
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)//创建套接字 socket
{
perror("socket error\n");
printf("创建套接字失败!\n");
return -2;
}
else
{
printf("套接字创建成功\n");
}
//设置 sockaddr_in 结构体的参数
bzero(&servaddr,sizeof(servaddr)); //结构体初始化
servaddr.sin_family=AF_INET; //数据类型设置 ip 通信
servaddr.sin_port=htons(atoi(argv[2]));//端口号的赋值 字符串 - -- 主机字节序数值 --网络字节序数值
servaddr.sin_addr.s_addr=inet_addr(argv[1]);// ip 地址 的转换 十进制点分形式 到 网络字节序的模式
/// 设置描述符号的捕捉
fd_set rset = {0} ; //这个是描述符集合,把所有描述符放在这里面。
struct timeval tm = {0} ; //设定超时时间
///
//连接服务器
if((connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr)))==-1) //调用connect 函数向服务器 建立TCP 连接
{
perror("connect error\n");
printf("客户端连接错误\n");
return -3;
}
else
{
printf("客户端与服务器连接成功!\n");
char yy[1000];
strcpy(yy,argv[3]);
send(sockfd,yy,strlen(yy),0);
printf("名字传送成功!\n");
}
/
//数据的接收 与发送
//创建两个进程 一个发送信息(父进程) 一个接受信息(子进程)
//
char buff[1024]="";
char buff1[1024]="";
int len=0;//接受父进程发送消息的长度
int len1=0;//接收子进程收到消息的长度
int color=31;
pid_t pid =fork();
if(pid<0)
{
perror("fork error\n");
printf("进程创建失败!\n");
}
else if(pid>0)//父进程 发送消息
{
signal(SIGCHLD,sigfun);
while(1)
{
//把键盘文件添加到描述符号集合中
FD_SET(STDIN_FILENO,&rset);
tm.tv_sec =10; //设定超时时间,如果3s内没有动静,就立刻返回
int count =select(STDIN_FILENO + 1,&rset,NULL,NULL,&tm);//看描述符号里面信号有没有动静
//printf("count =%d\n",count);
if(FD_ISSET(STDIN_FILENO,&rset))
{
fgets(buff,sizeof(buff),stdin);
if(strlen(buff)==0)
{
strcat(buff,"空");
}
len = send(sockfd,buff,strlen(buff)+1,0);//发送信息!
}
if(!strncmp(buff,"quit",4))
{
kill(pid,SIGKILL);
printf("退出!\n");
exit(0);
}
//printf("send : %s \n",buff);
if(len<0)
{
perror(" send error\n");
}
memset(buff,0,sizeof(buff));
}
}
else if(pid ==0)
{
while(1)
{
memset(buff1,0,sizeof(buff1));
len1 = recv(sockfd,buff1,sizeof(buff1),0);
if(len1<0)
{
perror("recv error\n");
}
else
{
//printf("len =%d\n",len1);
//printf("接受成功!\n");
}
printf("recv : %s\n",buff1);
if(strncmp(buff1,"quit",4)==0)
{
printf("quit 已经接受");
sleep(2);
kill(getppid(),SIGKILL);
//kill(getppid(),SIGCHLD);
printf("pid =%d ppid=%d\n",getpid(),getppid());
kill(getpid(),SIGKILL);
exit(0);
}
if(strncmp("clear-input",buff1,11)==0)
{
system("clear");
//printf("进入成功!\n");
printf_mig();
while(1)
{
memset(buff1,0,sizeof(buff1));
len1 = recv(sockfd,buff1,sizeof(buff1),0);
if(strncmp("exit-out",buff1,8)==0)
{
printf_end();
break;
}
else
{
printf_out(buff1);
}
}
}
}
}
close(sockfd);
return 0;
}
4.main.c (主函数,程序接口)
代码:
/************************************************************************************************************************************************************************************************************************
*文件名:
*作 者:She001
*时 间:
*版 本:
*作 用:
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include"user.h"
int main(int argc,char *argv[])
{
user_information_initialize();
sign_in_surface();
return 0;
}
5.makefile (程序编译文件 生成可执行的文件)
代码:
all: qq fuq khd UTP UDP_file
qq : user.o main.o
gcc -g -o qq user.o main.o
user.o :user.c
gcc -g -c user.c -o user.o
main.o: main.c
gcc -g -c main.c -o main.o
fuq:fuq.o
gcc -g -pthread -o fuq fuq.o -l sqlite3
fuq.o:fuq.c
gcc -g -c fuq.c -pthread -o fuq.o -l sqlite5
khd:khd.o
gcc -g -pthread -o khd khd.o -l sqlite3
khd.o:khd.c
gcc -g -c khd.c -pthread -o khd.o -l sqlite3
UTP:UTP.o
gcc -g -pthread -o UTP UTP.o -l sqlite3
UTP.o:UTP.c
gcc -g -c UTP.c -pthread -o UTP.o -l sqlite3
UDP_file:UDP_file.o
gcc -g -pthread -o UDP_file UDP_file.o -l sqlite3
UDP_file.o:UDP_file.c
gcc -g -c UDP_file.c -pthread -o UDP_file.o -l sqlite3
6.UDP_file.c (私聊发送文件)
代码:
/************************************************************************************************************************************************************************************************************************
*文件名:
*作 者:She001
*时 间:
*版 本:
*作 用:UDP 服务端 发送文件
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<sqlite3.h>
//1.UDP 协议 接受端的编程
//1.socket 数据报套接字
//2.bind : 把自己的ip port 绑定好
//3.recvfrom 读写操作 while(1) printf()
//4.close
//
int cid;
struct sockaddr_in caddr={0};
struct sockaddr_in saddr={0};
int panduan=0;
//采用C模式读二进制文件//并且发送
void DataRead_CMode(char * a)//a :文件名字
{
printf("正在发送文件!\n");
FILE *fid;
int len;
char buff[10240]="";
fid = fopen(a,"rb+");
if(fid == NULL)
{
printf("读取文件出错");
return;
}
while(fscanf(fid,"%s\n",buff)!=EOF)//读一行
{
strcat(buff,"\n");
len= sendto(cid,buff,strlen(buff),0,(struct sockaddr*)&saddr,sizeof(struct sockaddr));
usleep(10000);
memset(buff,0,sizeof(buff));
if(len>0)
{
printf("buff=%s\n",buff);
printf("发送成功!\n");
}
else
{
perror("发送失败 send error\n");
}
memset(buff,0,sizeof(buff));
}
strcpy(buff,"fa-song-wang-bi");
sendto(cid,buff,strlen(buff),0,(struct sockaddr*)&saddr,sizeof(struct sockaddr));
printf("发送完毕!\n");
fclose(fid);
}
//采用C模式写二进制文件
void DataWrite_CMode()
{
//写出数据
int len;
int len1;
char buff[1024]="";
FILE *fid;
int size=sizeof(caddr);
fid = fopen("1.txt","wb+");
if(fid == NULL)
{
printf("写出文件出错");
return;
}
while(1)
{
memset(buff,0,sizeof(buff));
len=recvfrom(cid,buff,sizeof(buff),0,(struct sockaddr*)&caddr,&size);
if(len>0)
{
printf("接受成功!\n");
printf("buff=%s\n",buff);
}
else
{
printf("接受失败\n");
}
if(strncmp(buff,"fa-song-wang-bi",15)==0)
{
break;
}
len1 =fwrite(buff,strlen(buff),1,fid);
if(len1>0)
{
printf("写入成功!\n");
}
else
{
printf("写入error\n");
}
}
fclose(fid);
}
void song_file()
{
char name[1000];
char buff[1000];
printf("请输入要传送文件的名字:");
scanf("%s",name);
DataRead_CMode(name);
}
void sigfun(int signo)//信号捕捉函数
{
if(signo==SIGCHLD)
{
panduan=1;
}
}
int main(int argc,char *argv[])//1 自己的 ip 2 自己的port 3 别人的ip 4 别人的port
{
if(argc <5)
{
perror("argc error\n");
return -1;
}
cid = socket(AF_INET,SOCK_DGRAM,0);
if(cid ==-1)
{
perror("cid error\n");
return -2;
}
printf("socket ok\n");
caddr.sin_family =AF_INET;
caddr.sin_port =htons(atoi(argv[2]));
caddr.sin_addr.s_addr =inet_addr(argv[1]);
if(bind(cid,(struct sockaddr*)&caddr,sizeof(caddr))<0)
{
perror("bind error\n");
return -2;
}
printf("bind success\n");
//
fd_set rset = {0} ; //这个是描述符集合,把所有描述符放在这里面。
struct timeval tm = {0} ; //设定超时时间
///
char buff[1280]="";
saddr.sin_family =AF_INET;
saddr.sin_port =htons(atoi(argv[4]));
saddr.sin_addr.s_addr =inet_addr(argv[3]);
int size =sizeof(saddr);
char ip[128]="";
int hh=1;
int len;
if(hh==1)
{
hh=0;
pid_t pid=fork();
if(pid==0)
{
while(1)
{
bzero(buff,sizeof(buff));
recvfrom(cid,buff,sizeof(buff)-1,0,(struct sockaddr*)&caddr,&size);
if(strncmp(buff,"shoudao-song-wen-file",21)==0)
{
printf("对方已经准备接受,我方准备发送数据\n");
kill(getppid(),SIGCHLD);//收到信号结束,结束父进程的死循环
//开始发送数据
song_file();
}
if(strncmp(buff,"song-wen-jian",13)==0)
{
strcpy(buff,"shoudao-song-wen-file");
sendto(cid,buff,strlen(buff),0,(struct sockaddr*)&saddr,sizeof(struct sockaddr));
printf("接受文件的信息收到!\n");
///接受文件的函数
DataWrite_CMode();
}
printf("%s\n",buff);
}
}
if(pid>0)
{
signal(SIGCHLD,sigfun);//闹钟信号的捕捉
while(1)
{
//把键盘文件添加到描述符号集合中
FD_SET(STDIN_FILENO,&rset);
tm.tv_sec =20; //设定超时时间,如果3s内没有动静,就立刻返回
int count =select(STDIN_FILENO + 1,&rset,NULL,NULL,&tm);//看描述符号里面信号有没有动静
//printf("count =%d\n",count);
if(FD_ISSET(STDIN_FILENO,&rset))
{
printf("===================================\n");
printf("= 1.传送文件 =\n");
printf("= 2.退出 =\n");
printf("====================================\n");
printf("请输入选择:");
scanf("%s",buff);
int a=atoi(buff);
printf("a=%d\n",a);
getchar();
if(a==1)
{
panduan=0;
while(panduan!=1)
{
strcpy(buff,"song-wen-jian");
sendto(cid,buff,strlen(buff),0,(struct sockaddr*)&saddr,sizeof(struct sockaddr));
printf("正在发送 :buff=%s\n",buff);
sleep(1);
memset(buff,0,sizeof(buff));
}
}
else
{
kill(pid,SIGKILL);//杀死子进程
exit(0);//自己退出
}
}
/*
if(!strncmp(buff,"quit",4))
{
kill(pid,SIGKILL);
printf("退出!\n");
exit(0);
}*/
//printf("send : %s \n",buff);
memset(buff,0,sizeof(buff));
}
}
}
close(cid);
return 0;
}
7.user.h (用户登录界面的头文件)
代码:
//用户信息 的存储
#ifndef __USER_H__
#define __USER_H__
#include<stdio.h>
#include<string.h>
#include<stdbool.h>
#include<stdlib.h>
#include<time.h>
#include<termio.h>
typedef struct user
{
char U_name[100]; //用户的姓名
char U_account_number[100]; //用户的账户信息
char U_password[100]; //用户的密码
int U_id; //用户的身份
}user;
int getch(void); //不显示函数
void error1(); //提示函数(提醒自己 这个地方没写)
void sign_in_surface(); //开始界面的选择方式
void staff_password(); //管理员登陆界面
void passenger_password(); //乘客的登陆界面
void staff_register(); //管理员的注册界面
void passenger_register(); //乘客的注册界面
void staff_sign_in(); //管理员登陆界面
void passenger_sign_in(); //管理员登陆界面
void user_information_initialize(); //乘用户信息初始化
void user_input_txt(); //账户密码信息输入到文件中
void qq_select(); //选择群聊还是单独聊天 用户功能
void staff_open_server(); //管理员打开群聊的服务端
int check_ip_exit(char *a,char *b) ; //测试ip是否存在
#endif
8.user.c
代码:
/************************************************************************************************************************************************************************************************************************
*文件名:user.c
*作 者:She001
*时 间:
*版 本:
*作 用:用户信息的存储
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include"user.h"
int pp[100]; //密码的传递
int user_number; //用户的数量
char user_zhanghu[100]; //使用用户的帐号
char user_name[100]; //使用者用户的名字
user user_num[1000]; //开辟数组储存数据
int check_ip_exit(char *a,char *b)//测试ip是否存在
{
int sockfd;
struct sockaddr_in servaddr;
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)//创建套接字 socket
{
perror("socket error\n");
printf("创建套接字失败!\n");
return -2;
}
else
{
//printf("套接字创建成功\n");
}
//设置 sockaddr_in 结构体的参数
bzero(&servaddr,sizeof(servaddr)); //结构体初始化
servaddr.sin_family=AF_INET; //数据类型设置 ip 通信
servaddr.sin_port=htons(atoi(b));//端口号的赋值 字符串 - -- 主机字节序数值 --网络字节序数值
servaddr.sin_addr.s_addr=inet_addr(a);// ip 地址 的转换 十进制点分形式 到 网络字节序的模式
///
//连接服务器
if((connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr)))==-1) //调用connect 函数向服务器 建立TCP 连接
{
perror("connect error\n");
printf("客户端连接错误\n");
return -3;
}
else
{
//printf("客户端与服务器连接成功!\n");
//printf("服务器存在! 可以连接\n");
char pp[10]="quit";
send(sockfd,pp,strlen(pp),0);
return 1;
}
}
void staff_open_server() //管理员打开群聊界面
{
char zong[100]="";
char ip[1000];//ip
char port[1000];//port
system("clear");
printf("===================================\n");
printf("= 管理员打开服务端界面 =\n");
printf("===================================\n");
printf("请输入服务器的ip:");
scanf("%s",ip);
printf("请输入服务器的端口号:");
scanf("%s",port);
pid_t pid=fork();
if(pid<0)
{
perror("fuq fork error\n");
}
else if(pid >0)
{
wait(NULL);
}
else if(pid ==0)
{
printf("任意键回车创建服务端\n");
getchar();
strcat(zong,"gnome-terminal -x ");
strcat(zong,"bash -c ");
strcat(zong,"\"");
strcat(zong,"./fuq ");
strcat(zong,ip);
strcat(zong," ");
strcat(zong,port);
strcat(zong,"\"");
printf("zong :%s",zong);
getchar();
system(zong);//打开服务器
printf("打开成功!\n");
getchar();
}
}
void error1()
{
printf("这里有没有填函数!\n");
}
void qq_select() //选择群聊还是单独聊天
{
system("clear");
printf("============================================\n");
printf("= 聊天室功能选择 =\n");
printf("============================================\n");
printf("= 1.群聊 =\n");
printf("============================================\n");
printf("= 2.单独找别人聊天 =\n");
printf("============================================\n");
printf("= 3.传送文件给别人 =\n");
printf("============================================\n");
printf("= 4.退出 =\n");
printf("============================================\n");
printf("请输入数字选择:");
char kk[1000];
scanf("%s",kk);
int a=strlen(kk);
if(a==1)
{
int b=atoi(kk);
if(b<0||b>4)
{
printf(" 输入错误!\n");
printf("任意键加回车,重新进入当前界面\n");
getchar();
getchar();
qq_select(); //重新输入
return; //退出程序,防止有bug
}
else
{
if(b==1)
{
char zong[100];
char ip[1000]; //ip
char port[1000];//port
printf("请输入服务器的ip ");
scanf("%s",ip);
printf("请输入服务器的端口号:");
scanf("%s",port);
int ttt=check_ip_exit(ip,port);
if(ttt<0)
{
printf("服务器不存在!\n");
printf("回车返回!\n");
getchar();
getchar();
}
else
{
pid_t pid=fork();
if(pid <0)
{
perror("khd fork error\n");
return ;
}
if(pid==0)
{
printf("服务器存在,正在进入!\n");
printf("随意按键进入!\n");
getchar();
getchar();
strcat(zong,"gnome-terminal -x ");
strcat(zong,"bash -c ");
strcat(zong,"\"");
strcat(zong,"./khd ");
strcat(zong,ip);
strcat(zong," ");
strcat(zong,port);
strcat(zong," ");
strcat(zong,user_name);
strcat(zong,"\"");
//system("gnome-terminal -x "./khd ip port user_name" ");
printf("zong :%s",zong);
system(zong);//进入客户端
getchar();
}
}
wait(NULL);
qq_select();//再次选择
}
else if(b==2)
{
char zong[100];
char ip[1000]; //ip
char port[1000];//port
char name[1000];//name
char ip1[1000]; //ip
char port1[1000];//port
char name1[1000];//name
printf("为了确保网络信息的安全,私聊信息要输入的详细一点!,请您见谅!\n");
printf("请输入自己的ip ");
scanf("%s",ip);
printf("请输入自己的端口号:");
scanf("%s",port);
printf("请输入自己的姓名:");
scanf("%s",name);
printf("请输入对方的ip ");
scanf("%s",ip1);
printf("请输入对方的端口号:");
scanf("%s",port1);
printf("请输入对方的姓名:");
scanf("%s",name1);
printf("正在建立自己的客户端,正在进入!\n");
printf("随意按键进入!\n");
getchar();
getchar();
strcat(zong,"gnome-terminal -x ");
strcat(zong,"bash -c ");
strcat(zong,"\"");
strcat(zong,"./UTP ");
strcat(zong,ip);
strcat(zong," ");
strcat(zong,port);
strcat(zong," ");
strcat(zong,name);
strcat(zong," ");
strcat(zong,ip1);
strcat(zong," ");
strcat(zong,port1);
strcat(zong," ");
strcat(zong,name1);
strcat(zong,"\"");
//system("gnome-terminal -x "./khd ip port user_name" ");
printf("zong :%s\n",zong);
getchar();
system(zong);
qq_select(); //选择群聊还是单独聊天
}
else if(b==3)
{
char zong[100];
char ip[1000]; //ip
char port[1000];//port
char ip1[1000]; //ip
char port1[1000];//port
printf("为了确保网络信息的安全,私聊信息要输入的详细一点!,请您见谅!\n");
printf("请输入自己的ip ");
scanf("%s",ip);
printf("请输入自己的端口号:");
scanf("%s",port);
printf("请输入对方的ip ");
scanf("%s",ip1);
printf("请输入对方的端口号:");
scanf("%s",port1);
printf("正在建立自己的客户端,正在进入!\n");
printf("随意按键进入!\n");
getchar();
getchar();
strcat(zong,"gnome-terminal -x ");
strcat(zong,"bash -c ");
strcat(zong,"\"");
strcat(zong,"./UDP_file ");
strcat(zong,ip);
strcat(zong," ");
strcat(zong,port);
strcat(zong," ");
strcat(zong,ip1);
strcat(zong," ");
strcat(zong,port1);
strcat(zong,"\"");
//system("gnome-terminal -x "./khd ip port user_name" ");
printf("zong :%s\n",zong);
getchar();
system(zong);
qq_select(); //选择群聊还是单独聊天
}
else if(b==4)
{
exit(-1);
return;
}
else
{
qq_select();
}
}
}
else
{
printf(" 输入错误!\n");
printf("任意键加回车,重新进入当前界面\n");
getchar();
getchar();
qq_select(); //重新输入
return; //退出程序,防止有bug
}
}
void sign_in_surface() //开始界面的选择方式
{
system("clear");
printf("=================================================\n");
printf("* 登陆方式选择界面 *\n");
printf("=================================================\n");
printf("* 1.用户登陆 *\n");
printf("=================================================\n");
printf("* 2.管理员登陆 *\n");
printf("=================================================\n");
printf("请输入数字选择:");
char kk[1000];
scanf("%s",kk);
int a=strlen(kk);
if(a==1)
{
int b=atoi(kk);
if(b<0||b>2)
{
printf(" 输入错误!\n");
printf("任意键加回车,重新进入当前界面\n");
getchar();
getchar();
sign_in_surface(); //重新输入
return; //退出程序,防止有bug
}
else
{
if(b==1)
{
passenger_sign_in();
}
else if(b==2)
{
staff_sign_in();
}
else
{
sign_in_surface();
}
}
}
else
{
printf(" 输入错误!\n");
printf("任意键加回车,重新进入当前界面\n");
getchar();
getchar();
sign_in_surface(); //重新输入
return; //退出程序,防止有bug
}
}
void staff_password() //管理员登陆界面
{
system("clear");
char mm[100]; //帐号
char nn[100]; //密码
int pppp=0; //标记
int i,j;
printf("=============================================\n");
printf("= 管理员的登陆界面 =\n");
printf("=============================================\n");
printf("请输入帐号(手机号):");
scanf("%s",mm);
printf("请输入密码:");
getchar();
i=0;
j=0;
while(i<100)
{
nn[i]=getch();//getch()从控制台输入一各字符但是不显示
if(nn[i]=='\b' && i>0) //遇到回车不管
{
continue;
}
if(nn[i]=='\b' && i==0) //如果在最开始就按退格键,就让i=-1
{
i=0;
continue;
}
if(nn[i]=='\r') //如果输入的是回车,就退出输入循环
{
break;
}
i++;
putchar('*');
}
nn[i]='\0';
printf("\n");
//
error1();
//这个上面需要 密码遮掩
for(i=0;i<user_number;i++)
{
if(strcmp(user_num[i].U_account_number,mm)==0&&user_num[i].U_id==1)
{
if(strcmp(user_num[i].U_password,nn)==0)
{
pppp=1;
printf("用户姓名:%s\n",user_num[i].U_name);
printf("乘客信息确认无误 登陆成功!\n");
printf("任意键加回车,进入系统!\n");
strcpy(user_name,user_num[i].U_name);
strcpy(user_zhanghu,user_num[i].U_account_number);
getchar();
getchar();
staff_open_server();//打开服务器
这里没写()进入界面的函数
return;
}
}
}
if(pppp==0)
{
printf("没有此人信息!\n");
printf("任意键加回车,返回上一个界面!\n");
getchar();
getchar();
staff_sign_in();
}
}
void passenger_password() //乘客的登陆界面
{
system("clear");
char mm[100]; //帐号
char nn[100]; //密码
int pppp=0;
int i,j;
printf("=============================================\n");
printf("= 用户的登陆界面 =\n");
printf("=============================================\n");
printf("请输入帐号(手机号):");
scanf("%s",mm);
printf("请输入密码:");
getchar();
i=0;
j=0;
while(i<100)
{
nn[i]=getch();//getch()从控制台输入一各字符但是不显示
if(nn[i]=='\b' && i>0) //遇到回车不管
{
continue;
}
if(nn[i]=='\b' && i==0) //如果在最开始就按退格键,就让i=-1
{
i=0;
continue;
}
if(nn[i]=='\r') //如果输入的是回车,就退出输入循环
{
break;
}
i++;
putchar('*');
}
nn[i]='\0';
printf("\n");
//
//这个上面需要 密码遮掩
for(i=0;i<user_number;i++)
{
if(strcmp(user_num[i].U_account_number,mm)==0&&user_num[i].U_id==0)
{
if(strcmp(user_num[i].U_password,nn)==0)
{
pppp=1;
printf("用户姓名:%s\n",user_num[i].U_name);
printf("乘客信息确认无误 登陆成功!\n");
printf("任意键加回车,进入系统!\n");
strcpy(user_name,user_num[i].U_name);
strcpy(user_zhanghu,user_num[i].U_account_number);
getchar();
getchar();
qq_select();
///
//
//
//
//
//
//没有填写函数
return;
}
}
}
if(pppp==0)
{
printf("没有此人信息!\n");
printf("任意键加回车,返回上一个界面!\n");
getchar();
getchar();
passenger_sign_in();
}
}
void staff_register() //管理员的注册界面
{
system("clear");
char k1[100]; //姓名
char kk[100]; //权限的密码
char mm[100]; //帐号
char nn[100]; //密码
char sex[100]; //性别
int i,j;
printf("=============================================\n");
printf("= 管理员的注册界面 =\n");
printf("=============================================\n");
printf("请输入你的名字:");
scanf("%s",k1);
printf("请输入帐号(手机号):");
scanf("%s",mm);
printf("请输入密码:");
getchar();
i=0;
j=0;
while(i<100)
{
nn[i]=getch();//getch()从控制台输入一各字符但是不显示
if(nn[i]=='\b' && i>0) //遇到回车不管
{
continue;
}
if(nn[i]=='\b' && i==0) //如果在最开始就按退格键,就让i=-1
{
i=0;
continue;
}
if(nn[i]=='\r') //如果输入的是回车,就退出输入循环
{
break;
}
i++;
putchar('*');
}
nn[i]='\0';
printf("\n");
//
for(i=0;i<user_number;i++)
{
if(strcmp(user_num[i].U_name,mm)==0)
{
printf("账户用户已经存在!\n");
printf("任意按键加回车,重新输入信息!\n");
getchar();
//getchar();
staff_register();
perror("xi tong bao cuo\n");
return;
}
}
printf("请输入gw的权限密码:");
scanf("%s",kk);
if(strcmp(kk,"666666")==0)
{
printf("权限密码正确,确认成功!\n");
}
else
{
printf("权限密码错误!\n");
printf("注册失败!\n");
printf("按下任意键加回车返回上一个界面!\n");
getchar();
getchar();
sign_in_surface();
return;
}
strcpy(user_num[i].U_account_number,mm); //帐号
strcpy(user_num[i].U_password,nn); //密码
strcpy(user_num[i].U_name,k1); //姓名
user_num[i].U_id=1;
printf("注册的帐号:%s\n",user_num[i].U_account_number);
printf("注册的密码:%s\n",user_num[i].U_password);
user_number++;
printf("注册成功!\n");
/用户写入文本
user_input_txt();
printf("按下任意键加回车返回上一个界面!\n");
getchar();
getchar();
sign_in_surface();
}
void passenger_register() //乘客的注册界面
{
system("clear");
char k1[100]; //姓名
char kk[100]; //权限的密码
char mm[100]; //帐号
char nn[100]; //密码
char sex[100]; //性别
int i,j;
printf("=============================================\n");
printf("= 用户的注册界面 =\n");
printf("=============================================\n");
printf("请输入你的名字:");
scanf("%s",k1);
printf("请输入帐号(手机号):");
scanf("%s",mm);
printf("请输入密码:");
getchar();
i=0;
j=0;
while(i<100)
{
nn[i]=getch();//getch()从控制台输入一各字符但是不显示
if(nn[i]=='\b' && i>0) //遇到回车不管
{
continue;
}
if(nn[i]=='\b' && i==0) //如果在最开始就按退格键,就让i=-1
{
i=0;
continue;
}
if(nn[i]=='\r') //如果输入的是回车,就退出输入循环
{
break;
}
i++;
putchar('*');
}
nn[i]='\0';
printf("\n");
//
for(i=0;i<user_number;i++)
{
if(strcmp(user_num[i].U_name,mm)==0)
{
printf("账户用户已经存在!\n");
printf("任意按键加回车,重新输入信息!\n");
getchar();
//getchar();
passenger_register();
return;
}
}
strcpy(user_num[i].U_account_number,mm); //帐号
strcpy(user_num[i].U_password,nn); //密码
strcpy(user_num[i].U_name,k1); //姓名
user_num[i].U_id=0;
printf("注册的帐号:%s\n",user_num[i].U_account_number);
printf("注册的密码:%s\n",user_num[i].U_password);
user_number++;
printf("注册成功!\n");
/用户写入文本
user_input_txt();
printf("按下任意键加回车返回上一个界面!\n");
getchar();
getchar();
sign_in_surface();
}
void staff_sign_in() //管理员登陆界面
{
system("clear");
printf("==================================================\n");
printf("* 管理员登陆界面 *\n");
printf("==================================================\n");
printf("* 1.注册新的账户 *\n");
printf("==================================================\n");
printf("* 2.进入登陆模式 *\n");
printf("==================================================\n");
printf("* 3.返回上个界面 *\n");
printf("==================================================\n");
printf("请输入数字选择:");
char kk[1000];
scanf("%s",kk);
int a=strlen(kk);
if(a==1)
{
int b=atoi(kk);
if(b<0||b>3)
{
printf(" 输入错误!\n");
printf("任意键加回车,重新进入当前界面\n");
getchar();
getchar();
staff_sign_in(); //重新输入
return; //退出程序,防止有bug
}
else
{
if(b==1)
{
staff_register();
}
else if(b==2)
{
staff_password();
}
else if(b==3)
{
sign_in_surface();
}
else
{
staff_sign_in();
}
}
}
else
{
printf(" 输入错误!\n");
printf("任意键加回车,重新进入当前界面\n");
getchar();
getchar();
staff_password(); //重新输入
return; //退出程序,防止有bug
}
}
void passenger_sign_in() //乘客登陆界面
{
system("clear");
printf("==================================================\n");
printf("* 乘客登陆界面 *\n");
printf("==================================================\n");
printf("* 1.注册新的账户 *\n");
printf("==================================================\n");
printf("* 2.进入登陆模式 *\n");
printf("==================================================\n");
printf("* 3.返回上个界面 *\n");
printf("==================================================\n");
printf("请输入数字选择:");
char kk[1000];
scanf("%s",kk);
int a=strlen(kk);
if(a==1)
{
int b=atoi(kk);
if(b<0||b>3)
{
printf(" 输入错误!\n");
printf("任意键加回车,重新进入当前界面\n");
getchar();
getchar();
passenger_sign_in(); //重新输入
return; //退出程序,防止有bug
}
else
{
if(b==1)
{
passenger_register();
}
else if(b==2)
{
passenger_password();
}
else if(b==3)
{
sign_in_surface();
}
else
{
passenger_sign_in();
}
}
}
else
{
printf(" 输入错误!\n");
printf("任意键加回车,重新进入当前界面\n");
getchar();
getchar();
passenger_sign_in(); //重新输入
return; //退出程序,防止有bug
}
}
void user_information_initialize() //用户信息初始化
{
int i=0;
FILE* fp=fopen("user_information.txt","r+");
if(fp==NULL)
{
perror("user_information_file error ");
}
while(fscanf(fp,"%s %s %s %d",user_num[i].U_name,user_num[i].U_account_number,user_num[i].U_password,&user_num[i].U_id)!=EOF)
{
i++;
}
user_number=i;
fclose(fp);
}
void user_input_txt() //账户密码信息输入到文件中
{
int i,k;
FILE* fp=fopen("user_information.txt","w+");
if(fp==NULL)
{
perror("user_information_file error ");
}
for(i=0;i<user_number;i++)
{
fprintf(fp,"%15s%30s%30s%10d\n",user_num[i].U_name,user_num[i].U_account_number,user_num[i].U_password,user_num[i].U_id);
}
fclose(fp);
}
int getch(void)
{
struct termios tm, tm_old;
int fd = 0, ch;
if (tcgetattr(fd, &tm) < 0) {//保存现在的终端设置
return -1;
}
tm_old = tm;
cfmakeraw(&tm);//更改终端设置为原始模式,该模式下所有的输入数据以字节为单位被处理
if (tcsetattr(fd, TCSANOW, &tm) < 0) {//设置上更改之后的设置
return -1;
}
ch = getchar();
if (tcsetattr(fd, TCSANOW, &tm_old) < 0) {//更改设置为最初的样子
return -1;
}
return ch;
}
/*
int main()
{
user_information_initialize(); //用户信息初始化
sign_in_surface();
return 0;
}
*/
9.UTP (用户私聊功能的文件)
代码:
/************************************************************************************************************************************************************************************************************************
*文件名:
*作 者:She001
*时 间:
*版 本:
*作 用:UDP 服务端 接受端一体
****************************************************************************************************************************************************************************************************************************/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<stdbool.h>
#include<time.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/wait.h>
#include<a.out.h>
#include<signal.h>
#include<stdarg.h>
#include<sys/socket.h>
#include<utime.h>
#include<sys/utsname.h>
#include<sys/times.h>
#include<sys/un.h>
#include<ctype.h>
#include<dirent.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<syslog.h>
#include<pthread.h>
#include<semaphore.h>
#include<sys/time.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/msg.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<sqlite3.h>
//1.UDP 协议 接受端的编程
//1.socket 数据报套接字
//2.bind : 把自己的ip port 绑定好
//3.recvfrom 读写操作 while(1) printf()
//4.close
//
int color=31;
void printf_mig()
{
printf("============================================================\n");
printf("= 聊天室 =\n");
printf("============================================================\n");
}
void printf_end()
{
char w[100];
printf("============================================================\n");
printf("============================================================\n");
printf("请输入内容:");
fflush(stdout);
}
void printf_out(char *s)
{
color++;
if(color>36)
{
color=31;
}
//printf("============================================================\n");
printf("\033[%d;40m%s \033[0m",color,s);
}
int sqlite3_input(char *a,char *b,char *c,char *d,char *e )//把用户接受的 写入数据库 a ip b port c : name d : 信息 e: 别人的port
{
sqlite3 *studb =NULL;
//下面这个函数 返回0 是执行成功
int res =sqlite3_open("stu1.db",&studb);// 打开数据库的函数 sqlite3 里面的 agrv[1] (参数传入)
if(!res)
{
//printf("sqlite3_Open ok\n");//打开成功
}
else
{
//printf("sqlite_open error\n");//打开失败
//printf("errmsg:%s \n",sqlite3_errmsg(studb));//错误信息的返回 函数errmsg
return -1;
}
char * errstr =NULL;
//先写好操作sqlite3的库的命令
//const char * stup ="insert into qq_ip_port_port(q_name, q_information )values(\'帅哥\',\'下线\');";
char stup[1024]="";
strcat(stup,"insert into qq_");
strcat(stup,"stu1");
strcat(stup,"_");
strcat(stup,b);
strcat(stup,"_");
strcat(stup,e);
strcat(stup,"(q_name,q_information)values(\'");
strcat(stup,c);
strcat(stup," :");
strcat(stup,"\',\'");
strcat(stup,d);
strcat(stup,"\');");
//printf("%s\n",stup);
//下面这个函数返回0 是执行成功
if(!sqlite3_exec(studb,stup,NULL,NULL,&errstr)) //执行命令stup errstr 是出现错误的时候返回的错误信息
{
//printf("opeation is suceessfuly \n");
}
else
{
//printf("opeation is failed \n");
//printf("error: %s\n",errstr);
return -2;
}
sqlite3_close(studb);
return 1;
}
void create_table_stu1(char* a,char *b,char *c)//a: ip b:port c: 别人的port //创造一个表
{
sqlite3 *studb =NULL;
//下面这个函数 返回0 是执行成功
int res =sqlite3_open("stu1.db",&studb);// 打开数据库的函数 sqlite3 里面的 agrv[1] (参数传入)
if(!res)
{
// printf("sqlite3_Open ok\n");//打开成功
}
else
{
//printf("sqlite_open error\n");//打开失败
// printf("errmsg:%s \n",sqlite3_errmsg(studb));//错误信息的返回 函数errmsg
return ;
}
char * errstr =NULL;
//char * create_table ="create table qq_ip_port_port(q_name text , q_information text);";
char create_table[1024]="";
char ip1[1024]="";
char port1[1024]="";
strcat(ip1,a);//ip
strcat(port1,b);//port
strcat(create_table,"create table qq_");
strcat(create_table,"stu1");
strcat(create_table,"_");
strcat(create_table,port1);
strcat(create_table,"_");
strcat(create_table,c);
strcat(create_table,"(q_name text,q_information text);");
//printf("%s\n",create_table);
if(!sqlite3_exec(studb,create_table,NULL,NULL,&errstr))//创建一个表来存储信息
{
//printf("create ta ble is suceessfuly \n");
}
else
{
//printf("create_table is failed \n");
/// printf("error: %s\n",errstr);
}
sqlite3_close(studb);
}
void read_table_stu1(char *a,char* b,char *c )//a :ip b: port c :别人的port //从表里面读取数据
{
sqlite3 *studb =NULL;
//下面这个函数 返回0 是执行成功
int res =sqlite3_open("stu1.db",&studb);// 打开数据库的函数 sqlite3 里面的 agrv[1] (参数传入)
if(!res)
{
//printf("sqlite3_Open ok\n");//打开成功
}
else
{
printf("sqlite_open error\n");//打开失败
printf("errmsg:%s \n",sqlite3_errmsg(studb));//错误信息的返回 函数errmsg
return ;
}
char * errstr =NULL;
//char *look = "select * from qq_ip_port_port";//查看所有的列
char look[1024]="";
char ** paz_result;
int hang;//用于存放获取到的总个数
int lie;//用于存放一列表的个数
strcat(look,"select * from qq_");
strcat(look,"stu1");
strcat(look,"_");
strcat(look,b);
strcat(look,"_");
strcat(look,c);
//printf("%s\n",look);
//将数据库内容传到C变量里
if(SQLITE_OK != sqlite3_get_table(studb,look,&paz_result,&hang,&lie,&errstr))
{
//打印错误信息
fprintf(stderr,"数据库操作错误\n%s\n",errstr); //输入到标准报错里面
//释放掉错误区域内存,防止内存溢出
sqlite3_free(errstr);
return;
}
int i,j,index = 0;
//system("clear");
//printf_mig();
for ( i = 0; i <= hang; i++)//默认会少打印一行,所以 i <= hang
{
color++;
if(color>36)
{
color=31;
}
for ( j = 0; j < lie; j++)
{
printf("\033[%d;40m %s \033[0m",color,paz_result[index]);
index++;
}
fflush(stdout);
if(i==0)
{
system("clear");
printf_mig();
system("clear");
printf_mig();
}
}
printf_end();
sqlite3_close(studb);
}
int main(int argc,char *argv[])//1 自己的 ip 2 自己的port 3 自己的name 4 别人的ip 5 别人的port 6 别人的name
{
if(argc <7)
{
perror("argc error\n");
return -1;
}
int cid = socket(AF_INET,SOCK_DGRAM,0);
if(cid ==-1)
{
perror("cid error\n");
return -2;
}
printf("socket ok\n");
struct sockaddr_in caddr={0};
caddr.sin_family =AF_INET;
caddr.sin_port =htons(atoi(argv[2]));
caddr.sin_addr.s_addr =inet_addr(argv[1]);
if(bind(cid,(struct sockaddr*)&caddr,sizeof(caddr))<0)
{
perror("bind error\n");
return -2;
}
printf("bind success\n");
//
create_table_stu1(argv[1],argv[2],argv[5]);//建立一个表 ,也可以是查看这个表存在不
fd_set rset = {0} ; //这个是描述符集合,把所有描述符放在这里面。
struct timeval tm = {0} ; //设定超时时间
///
char buff[1280]="";
struct sockaddr_in saddr={0};
saddr.sin_family =AF_INET;
saddr.sin_port =htons(atoi(argv[5]));
saddr.sin_addr.s_addr =inet_addr(argv[4]);
int size =sizeof(saddr);
char ip[128]="";
int hh=1;
int len;
if(hh==1)
{
hh=0;
pid_t pid=fork();
if(pid==0)
{
while(1)
{
int fanhui=0;
bzero(buff,sizeof(buff));
recvfrom(cid,buff,sizeof(buff)-1,0,(struct sockaddr*)&caddr,&size);
printf("%s\n",buff);
while(1)
{
fanhui=sqlite3_input(argv[1],argv[2],argv[6],buff,argv[5]);//向数据库写入数据
if(fanhui==1)
{
break;
}
}
read_table_stu1(argv[1],argv[2],argv[5]);
//printf("%d %s\n",ntohs(saddr.sin_port),inet_ntop(AF_INET,&saddr.sin_addr.s_addr,ip,20));
}
}
if(pid>0)
{
while(1)
{
int fanhui=0;
//把键盘文件添加到描述符号集合中
FD_SET(STDIN_FILENO,&rset);
tm.tv_sec =10; //设定超时时间,如果3s内没有动静,就立刻返回
int count =select(STDIN_FILENO + 1,&rset,NULL,NULL,&tm);//看描述符号里面信号有没有动静
//printf("count =%d\n",count);
if(FD_ISSET(STDIN_FILENO,&rset))
{
fgets(buff,sizeof(buff),stdin);
sendto(cid,buff,strlen(buff),0,(struct sockaddr*)&saddr,sizeof(struct sockaddr));
// sqlite3_input(argv[1],argv[2],argv[3],buff);//向数据库写入数据
while(1)
{
fanhui=sqlite3_input(argv[1],argv[2],argv[3],buff,argv[5]);//向数据库写入数据
if(fanhui==1)
{
break;
}
}
read_table_stu1(argv[1],argv[2],argv[5]);
}
if(!strncmp(buff,"quit",4))
{
kill(pid,SIGKILL);
printf("退出!\n");
exit(0);
}
//printf("send : %s \n",buff);
memset(buff,0,sizeof(buff));
}
}
}
close(cid);
return 0;
}
6.注意事项 。
1.自己的IP 请输入正确!
2.注意,客户端不要异常退出!,请输入quit 退出!
3.服务器。请输入ctrl + z 信号捕捉之后退出!