首页 > 学院 > 开发设计 > 正文

即时通讯软件

2019-11-06 07:57:28
字体:
来源:转载
供稿:网友

客户端:

#include <stdio.h>

#include <errno.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <netdb.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <ctype.h>#include <sqlite3.h>#include <signal.h>#define PORT 9999//判断在线情况标识符,1表示在线正常,2表示被踢下线,3表示被禁言int *adress_online;int *adress_socketfd;struct client_msg{int cmd_c; //0表示注册成功 1表示登录成功 2表示登录失败 3表示私聊信息发送成功 4表示私聊信息发送失败int id_c;int cmd2_c;char name_c[20];char psw[10];char tak_c[100];};struct server_msg{int cmd_s;int id_s;char fname[20];char tak_s[100];};static void * handle_client(void *arg);void signal_handler(struct sigaction *act);  //看看就好,不要尝试,会出bug;int main(int argc, char *argv[]){if(2 != argc){PRintf("Usage : %s ip/n", argv[0]);exit(EXIT_FAILURE);}//建立socket***********************************int socket_fd;socket_fd = socket(AF_INET, SOCK_STREAM, 0);if(-1 == socket_fd){perror("socket");exit(EXIT_FAILURE);}adress_socketfd = &socket_fd;//请求连接***************************************struct hostent *host;host = gethostbyname(argv[1]);struct sockaddr_in clientaddr;if(NULL == host){perror("gethostbyname");exit(EXIT_FAILURE);}memset(&clientaddr, 0, sizeof(struct sockaddr));clientaddr.sin_family = AF_INET;clientaddr.sin_port = htons(PORT);clientaddr.sin_addr = *((struct in_addr *)host->h_addr);int ret;ret = connect(socket_fd, (struct sockaddr*)(&clientaddr), sizeof(struct sockaddr));if(-1 == ret){perror("connect");   exit(EXIT_FAILURE);}printf("******************连接成功************************/n");    struct client_msg client1;char snd_buf[1024];char buffer[1024];pthread_t cli_thread;while(1){printf("*****请输入指令*****/n");printf("*****************************/n");printf("**      1:注册           ****/n");printf("**      2:登录           ****/n");printf("**      3:退出程序       ****/n");printf("*****************************/n");scanf("%d", &client1.cmd_c);switch(client1.cmd_c){case 1://************注册*******************************{char psw_2[10];printf("  *****************************/n");printf("     *****      注册      *****/n");   printf("     *****  请输入用户名  *****/n");                scanf("%s", client1.name_c);    printf("     *****  请输入密码    *****/n");scanf("%s", client1.psw);//*********确认密码***********printf("     *****  请再次输入密码*****/n");scanf("%s", psw_2);int same = 1;same = strcmp(psw_2, client1.psw);if(0 != same){printf("      <<<<两次密码输入不同,注册失败>>>>/n");break;}printf("      正在向服务器发送请求....../n");//**************发送信息************************                memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &client1, sizeof(client1)); //结构体转换成字符串ret = write(socket_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("      发送成功,等待服务器处理....../n");ret = read(socket_fd, buffer, 1024);if(-1 == ret){printf("read fail/n");perror("read");exit(EXIT_FAILURE);}//printf("read success/n");struct server_msg fserver; //定义结构体变量memset(&fserver, 0, sizeof(fserver));//清空结构体memcpy(&fserver, buffer, sizeof(fserver));//把接收到的信息转换成结构体if(0 != fserver.cmd_s){printf("      <<<<注册失败>>>>/n");break;}printf("/n");printf("      注册成功,您的ID是:%d/t!/n", fserver.id_s);printf("/n");break;}case 2://************登录*******************************{printf("   **********登录**************/n");printf("      ***      请输入ID    ****/n");scanf("%d", &client1.id_c);printf("      ***     请输入密码   ****/n");scanf("%s", client1.psw);printf("      登录中.../n");printf("/n");memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &client1, sizeof(client1)); //结构体转换成字符串ret = write(socket_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}//printf("发送成功,等待服务器处理....../n");ret = read(socket_fd, buffer, 1024);if(-1 == ret){printf("read fail/n");perror("read");exit(EXIT_FAILURE);}struct server_msg fserver; //定义结构体变量memset(&fserver, 0, sizeof(fserver));//清空结构体memcpy(&fserver, buffer, sizeof(fserver));//把接收到的信息转换成结构体if(1 == fserver.cmd_s)//普通用户登录{int online = 1;adress_online = &online;ret = pthread_create(&cli_thread, NULL, handle_client, (void *)socket_fd);if(-1 == ret){perror("pthread_create");exit(EXIT_FAILURE);}printf("      用户登录成功/n");//登录成功,*******************************************************************while(1){printf("/n");printf("***********************************************************/n");printf("   *************请输入指令***********/n");printf("   ******    1:在线人数查询    ******/n");printf("   ******    2:私聊            *****/n");printf("   ******    3:群聊            ******/n");printf("   ******    4:注销            ******/n");printf("   ******    8:文件传输        ******/n");printf("***********************************************************/n");printf("/n");scanf("%d", &client1.cmd2_c);if(1 == online){printf("online is %d/n", online);}else{if(2 == online){ printf("online is %d/n", online);goto label1;} }switch(client1.cmd2_c)//判断命令{case 1:{printf("/n");printf("********************在线人数查询***********************/n");//给服务器发消息//printf("发送信息ing/n");memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &client1, sizeof(client1)); //结构体转换成字符串ret = write(socket_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("    发送请求成功,等待服务器处理....../n");break;}case 2:{printf("/n");if(3 != online){printf("*********************私聊********************/n");printf("    请输入对方ID:/n");scanf("%d", &client1.id_c);printf("    请输入聊天内容:/n");scanf("%s", client1.tak_c);//发送信息printf("     ....../n");//printf("1客户机命令:%d/n", client1.cmd2_c);//memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &client1, sizeof(client1)); //结构体转换成字符串//printf("2客户机命令:%d/n", client1.cmd2_c);ret = write(socket_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("    <私聊>请求发送成功,等待服务器处理....../n");break;}else{printf("    您被管理员禁言,不能发起私聊/n");break;} }case 3:{printf("/n");if(3 != online){printf("*********************群聊模式开启************************/n");printf("    请输入群聊内容:/n");scanf("%s", client1.tak_c);//printf("群聊内容是 :%s/n", client1.tak_c);printf("     ....../n");memcpy(snd_buf, &client1, sizeof(client1)); //结构体转换成字符串ret = write(socket_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("    <群聊>信息发送成功,等待服务器处理....../n");break;}else{printf("    您被管理员禁言,不能发起群聊/n");break;}}case 4:{printf("/n");printf("*********************注销***************/n");printf("    发送注销请求...../n");memcpy(snd_buf, &client1, sizeof(client1)); //结构体转换成字符串ret = write(socket_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("    <注销>信息发送成功,等待服务器处理....../n");goto label1;}case 8:{printf("/n");printf("******************文件传输********************/n");printf("    请输入文件名:/n");scanf("%s", client1.name_c);printf("    请输入发送方Id:/n");scanf("%d", &client1.id_c);memcpy(snd_buf, &client1, sizeof(client1)); //结构体转换成字符串ret = write(socket_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("<文件传输>信息发送成功/n");FILE * fp = fopen(client1.name_c, "r");if(NULL == fp ){printf("    File:/t%s Not Found/n", client1.name_c);}else{char buffer_file[1024];memset(buffer_file, 0, 1024); //用0清空int file_block_length = 0;while( (file_block_length = fread(buffer_file, sizeof(char), 1024, fp)) > 0) //把fp读到buffer_file中返回值为实际长度{printf("    file_block_length = %d/n",file_block_length);if(write(socket_fd, buffer_file, 1024) != -1) //send发送,失败返回值为-1{printf("    Send File:/t%s Failed/n", client1.name_c);break;}bzero(buffer_file, 1024);  //必须清空}        fclose(fp);printf("    文件主体发送完成/n");strcpy( buffer_file , "END");printf("    client (发送) buffer is %s/n", buffer_file);if(write(socket_fd, buffer_file, 1024) < 0){printf("    Send File:  Failed/n");break;}printf("    文件传输完成/n");}break;}}}}else //超级用户登录{if(10 == fserver.cmd_s){printf("      恭喜成为管理员/n");ret = pthread_create(&cli_thread, NULL, handle_client, (void *)socket_fd);if(-1 == ret){perror("pthread_create");exit(EXIT_FAILURE);}printf("      登录成功/n");//登录成功,*******************************************************************while(1){printf("/n");   printf("***********************************************************/n");   printf("   *************请输入指令***********/n");   printf("   ******    1:在线人数查询    ******/n");   printf("   ******    2:私聊            *****/n");   printf("   ******    3:群聊            ******/n");   printf("   ******    4:注销            ******/n");printf("   ******    5:踢人            ******/n");printf("   ******    6:禁言            ******/n");printf("   ******    7:解禁            ******/n");   printf("   ******    8:文件传输        ******/n");   printf("***********************************************************/n");   printf("/n");scanf("%d", &client1.cmd2_c);switch(client1.cmd2_c)//判断命令{case 1:{printf("/n");printf("********************在线人数查询***********************/n");//给服务器发消息//printf("发送信息ing/n");memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &client1, sizeof(client1)); //结构体转换成字符串ret = write(socket_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("    发送请求成功,等待服务器处理....../n");break;}case 2:{printf("/n");printf("*********************私聊********************/n");printf("    请输入对方ID:/n");scanf("%d", &client1.id_c);printf("    请输入聊天内容:/n");scanf("%s", client1.tak_c);//发送信息printf("     ....../n");//printf("1客户机命令:%d/n", client1.cmd2_c);//memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &client1, sizeof(client1)); //结构体转换成字符串//printf("2客户机命令:%d/n", client1.cmd2_c);ret = write(socket_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("    <私聊>请求发送成功,等待服务器处理....../n");break;}case 3:{printf("/n");printf("*********************群聊模式开启************************/n");printf("    请输入群聊内容:/n");scanf("%s", client1.tak_c);//printf("群聊内容是 :%s/n", client1.tak_c);printf("     ....../n");memcpy(snd_buf, &client1, sizeof(client1)); //结构体转换成字符串ret = write(socket_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("    <群聊>信息发送成功,等待服务器处理....../n");break;}case 4:{printf("/n");printf("*********************注销***************/n");printf("    发送注销请求...../n");memcpy(snd_buf, &client1, sizeof(client1)); //结构体转换成字符串ret = write(socket_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("    <注销>信息发送成功,等待服务器处理....../n");goto label1;}case 5:{printf("*********************踢人****************/n");printf("    请输入被踢者的ID/n");scanf("%d", &client1.id_c);printf("    ....../n");//printf("1客户机命令:%d/n", client1.cmd2_c);//memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &client1, sizeof(client1)); //结构体转换成字符串//printf("2客户机命令:%d/n", client1.cmd2_c);ret = write(socket_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("    <踢人>请求发送成功,等待服务器处理....../n");break;}case 6:{printf("*********************禁言****************/n");printf("    请输入被禁言者ID/n");scanf("%d", &client1.id_c);printf("    ....../n");memcpy(snd_buf, &client1, sizeof(client1)); //结构体转换成字符串//printf("2客户机命令:%d/n", client1.cmd2_c);ret = write(socket_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("    <禁言>请求发送成功,等待服务器处理....../n");break;}case 7:{printf("*********************解禁***************/n");printf("    请输入要解禁的人的ID/n");scanf("%d", &client1.id_c);printf("    ....../n");memcpy(snd_buf, &client1, sizeof(client1)); //结构体转换成字符串//printf("2客户机命令:%d/n", client1.cmd2_c);ret = write(socket_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("    <解禁>请求发送成功,等待服务器处理....../n");break;}case 8:{printf("/n");printf("******************文件传输********************/n");printf("    请输入要发送的文件名:/n");scanf("%s", client1.name_c);// printf("    请输入接收的文件名:/n");// scanf("%s", client1.name_r);printf("    请输入发送方Id:/n");scanf("%d", &client1.id_c);memcpy(snd_buf, &client1, sizeof(client1)); //结构体转换成字符串ret = write(socket_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("<文件传输>信息发送成功/n");FILE * fp = fopen(client1.name_c, "r");if(NULL == fp ){printf("    File:/t%s Not Found/n", client1.name_c);}else{char buffer_file[1024];memset(buffer_file, 0, 1024); //用0清空int file_block_length = 0;while( (file_block_length = fread(buffer_file, sizeof(char), 1024, fp)) > 0) //把fp读到buffer_file中返回值为实际长度{printf("    file_block_length = %d/n",file_block_length);if(write(socket_fd, buffer_file, 1024) != -1) //send发送,失败返回值为-1{printf("    Send File:/t%s Failed/n", client1.name_c);break;}memset(buffer_file, 0,1024);  //必须清空}        fclose(fp);printf("    文件主体发送完成/n");memset(buffer_file, 0,1024);strcpy( buffer_file , "END");printf("    client (发送) buffer is %s/n", buffer_file);if(write(socket_fd, buffer_file, 1024) == -1){printf("    Send File:  Failed/n");break;}printf("    文件传输完成/n");}break;}}}}}printf("登录失败/n");break;}case 3://************退出程序*******************************{memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &client1, sizeof(client1)); //结构体转换成字符串ret = write(socket_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("用户退出/n");goto outprogram;}}label1:printf("waiting*******************************************/n");}outprogram:close(socket_fd);return 0;}static void * handle_client(void *arg){int ret;int socket_fd = (int)arg;char buffer[1024];while(1){ ret = read(socket_fd, buffer, 1024);if(-1 == ret){perror("read");exit(EXIT_FAILURE);}struct server_msg fserver; //定义结构体变量memset(&fserver, 0, sizeof(fserver));//清空结构体memcpy(&fserver, buffer, sizeof(fserver));//把接收到的信息转换成结构体//printf("fserver.cmd_s is %d/n", fserver.cmd_s);switch(fserver.cmd_s){case 9:{printf("在线人数为 %d/n", fserver.id_s);break;}case 3:{printf("私聊信息发送成功/n");break;}case 4:{printf("私聊信息发送失败/n");break;}case 5:{printf("%d发来私聊信息%s/n", fserver.id_s, fserver.tak_s);break;}case 6:{printf("%d/t发来群发消息%s/n",  fserver.id_s, fserver.tak_s);break;}case 7:{printf("群聊发送成功/n");break;}case 8:{printf("注销成功/n");goto label2;}case 10:{printf("管理员登录成功/n");break;}case 11:{printf("您被管理员踢出本聊天室/n");struct client_msg client1;char snd_buf[1024];client1.cmd2_c = 4;memcpy(snd_buf, &client1, sizeof(client1)); //结构体转换成字符串ret = write(socket_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("(被踢)信息发送成功,等待服务器处理....../n");printf("输入任意数字退出界面/n");*adress_online = 2;break;}case 12:{printf("踢人操作完成/n");break;}case 13:{printf("您被管理员禁言/n");*adress_online = 3;break; }case 14:{printf("禁言成功/n");break;}case 15:{printf("您被管理员解除禁言/n");*adress_online = 1;break;}case 16:{printf("解除禁言成功/n");break;}case 17:{char buffer_file[1024];printf("%d/t发来文件%s, 请注意查收/n", fserver.id_s, fserver.fname);FILE * fp = fopen("222.txt","w+");   if(NULL == fp ){printf("File:/t%s Can Not Open To Write/n", fserver.fname);exit(1);}//从服务器接收数据到buffer中memset(buffer_file, 0, 1024);int length = 0;while(1){length = read(socket_fd, buffer_file, 1024);  //收到的字符串长度printf("length = %d/n",length);if(length < 0){printf("Recieve Data From Server %s Failed!/n", fserver.fname);break;}printf("client(接收) : buffer_file is %s/n", buffer_file);if(0 == strcmp(buffer_file, "END")){printf("文件接收完成/n");break;}int write_length = fwrite(buffer_file, sizeof(char), length, fp);printf("write_length = %d/n", write_length);if (write_length < length){printf("File:/t%s Write Failed/n", fserver.fname);break;}memset(buffer_file, 0, 1024);  }fclose(fp);break;}case 18:{printf("文件传输完成/n");break;}}}label2:printf("waiting********************************/n");return;}void signal_handler(struct sigaction *act){int socket_fd = *adress_socketfd;struct client_msg client1;client1.cmd_c = 99;client1.cmd2_c = 99;char snd_buf[1024];memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &client1, sizeof(client1)); //结构体转换成字符串int ret;ret = write(socket_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}exit(0);}

服务端:

#include <stdio.h>#include <errno.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <netdb.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <ctype.h>#include <pthread.h>#include <sqlite3.h>//定义端口#define PORT 9999//登录成功标志变量地址int *adress;//客户机结构体                            struct client_msg{int cmd_c; //功能选项 1.注册 2.登录。3.退出int id_c;int cmd2_c; //功能选项 1.客户机查看在线人数。2.私聊。3.群聊。4.注销。5.超级用户踢人。6.禁言。7.解禁。8.文件传输。99.客户机强退。char name_c[20];char psw[10];char tak_c[100];};//服务器结构体                            struct server_msg{int cmd_s;  //0表示注册成功 1表示登录成功 2表示登录失败 3表示私聊信息发送成功 4表示私聊信息发送失败int id_s;                  char fname[20];char tak_s[100];};//链表结构体typedef struct Node{int id_l;int fd_l; struct Node *next;}linkedlist;linkedlist *list;//链表函数linkedlist *createlinkedlist();int getcount(linkedlist *list);//void insert1(linkedlist *list, int id, int fd);linkedlist *insert2(linkedlist *list, int id, int fd);int queryfd(linkedlist *list, int id);int queryid(linkedlist *list, int fd);void print(linkedlist *list);linkedlist *dellinkedlist(linkedlist *list, int fd);//线程处理函数static void * handle_client(void * arg);//回调函数int select_callback(void *date, int column_count,char* columnValue[],char* columnName[]);int main(){//用来创建socketint socket_fd;socket_fd = socket(AF_INET, SOCK_STREAM, 0);if(-1 == socket_fd){perror("socket");exit(EXIT_FAILURE);}printf("socket success/n");//用来绑定struct sockaddr_in myaddr;memset(&myaddr, 0, sizeof(struct sockaddr));myaddr.sin_family = AF_INET;//设置协议myaddr.sin_port = htons(PORT);//端口号myaddr.sin_addr.s_addr = INADDR_ANY;//任意ip都可以通信int ret;ret = bind(socket_fd, (struct sockaddr*)&myaddr, sizeof(struct sockaddr));if(-1 == ret){perror("bind");exit(EXIT_FAILURE);}printf("bind success/n");//监听ret = listen(socket_fd, 6);if(-1 == ret){perror("listen");exit(EXIT_FAILURE);}printf("listen success/n");struct sockaddr_in clientaddr;pthread_t cli_thread;//建立数据库int sqlret;sqlite3 *db;char *ErrMsg;sqlret = sqlite3_open("./chatroom.db", &db);//打开数据库if(sqlret != SQLITE_OK){printf("error : open sqlite/n");}printf("建立数据库成功/n");char *create_str = "create table people (id INTEGER primary key, name TEXT, psw TEXT);";sqlret = sqlite3_exec(db, create_str, 0, 0, &ErrMsg);if(sqlret != SQLITE_OK){   printf("error : create   %s/n", sqlite3_errmsg(db));}printf("建立表成功/n");//关闭数据库ret = sqlite3_close(db);if(ret != SQLITE_OK){   printf("error : close/n");}    char snd_buf[1024];//创建链表list = createlinkedlist();while(1){int size = sizeof(struct sockaddr_in);//此处发生第一次阻塞,满足条件:有新的客户端接入   int new_fd;   new_fd = accept(socket_fd, (struct sockaddr*)&clientaddr, &size);   if(-1 == new_fd)   {    perror("accept");   }   printf("accept success/n");//线程处理新接入的客户机ret = pthread_create(&cli_thread, NULL, handle_client, (void *)new_fd);if(-1 == ret){perror("pthread_create");   exit(EXIT_FAILURE);}}return 0;}static void * handle_client(void *arg){int new_fd = (int)arg;char buffer[1024];char snd_buf[1024];int ret;static int num = 520;//用作idwhile(1){//接收信息printf("reading.../n");ret = read(new_fd, buffer, 1024);if(-1 == ret){printf("read fail/n");perror("read");exit(EXIT_FAILURE);}printf("read success/n");//解析信息   struct client_msg fclient; //定义结构体变量memset(&fclient, 0, sizeof(fclient));//清空结构体memcpy(&fclient, buffer, sizeof(fclient));//把接收到的信息转换成结构体//printf("%d/t%s/t%s/t%s/n", fclient.cmd_c,  fclient.name_c, fclient.psw, fclient.tak_c);struct server_msg server1;server1.cmd_s = -1;switch(fclient.cmd_c){case 1:{printf("有新的客户请求注册/n");//*********插入注册信息****************int sqlret;sqlite3 *db;sqlret = sqlite3_open("./chatroom.db", &db);if(sqlret != SQLITE_OK){printf("error : open sqlite/n");}char *insert_str = "insert into people (id, name, psw) values (%d, '%s', '%s');";char *ErrMsg;char str[1024];//插入注册信息到people表sprintf(str, insert_str, num, fclient.name_c, fclient.psw);ret = sqlite3_exec(db, str, 0, 0, &ErrMsg);if(ret != SQLITE_OK){printf("error : insert   %s/n", sqlite3_errmsg(db));exit(EXIT_FAILURE);}ret = sqlite3_close(db);if(ret != SQLITE_OK){printf("error : close/n");}server1.cmd_s = 0;server1.id_s = num;num++;//***********发送服务器结构体*********memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &server1, sizeof(server1)); //结构体转换成字符串ret = write(new_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("发送成功,等待下一指令....../n");break;}case 2:{printf("有新的客户端请求登录/n");//printf("%d/t%s/t%s/t%d/n", fclient.cmd_c,  fclient.name_c, fclient.psw, fclient.id_c);//回调函数查找int ret;sqlite3 *db;char *ErrMsg;char str[1024];//打开数据库ret = sqlite3_open("./chatroom.db", &db);if(ret != SQLITE_OK){printf("error : open/n");}//查找表内数据int check = -1;adress = &check;//登录成功标志变量printf("*********查询信息********/n");char *select_str = "select * from people where id = %d and psw = '%s';";sprintf(str, select_str, fclient.id_c, fclient.psw);printf("开始查找/n");ret = sqlite3_exec(db, str, select_callback, 0, &ErrMsg);if(ret != SQLITE_OK)           {               printf("error : select  %s/n", sqlite3_errmsg(db));break;           }printf("check = %d/n", check);//关闭数据库ret = sqlite3_close(db);if(ret != SQLITE_OK){printf("error : close/n");}if(check == 1)//登录成功{//server1.cmd_s = 1;if(520 == fclient.id_c){server1.cmd_s = 10;}else{server1.cmd_s = 1;}memset(snd_buf, 0, 1024);//清空发送缓存   memcpy(snd_buf, &server1, sizeof(server1)); //结构体转换成字符串ret = write(new_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("登录成功,发送反馈成功,等待下一指令....../n");//插入信息到链表list = insert2(list, fclient.id_c, new_fd);printf("现在打印链表/n");print(list);printf("在线人数为:%d/n", getcount(list));//reading...while(1){printf("现在等待客户端命令/n");//**************读取信息*******************************************memset(buffer, 0, 1024);ret = read(new_fd, buffer, 1024);if(-1 == ret){printf("read fail/n");perror("read");exit(EXIT_FAILURE);}printf("read success/n");//解析信息struct client_msg fclient; //定义结构体变量memset(&fclient, 0, sizeof(fclient));//清空结构体memcpy(&fclient, buffer, sizeof(fclient));//把接收到的信息转换成结构体//******************读取完成****************************************printf("客户端命令为 :%d/n", fclient.cmd2_c);switch(fclient.cmd2_c){case 1://客户机请求查看在线人数{printf("客户机请求查看在线人数/n");server1.cmd_s = 9;print(list);server1.id_s = getcount(list);memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &server1, sizeof(server1)); //结构体转换成字符串ret = write(new_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("发送反馈成功,等待下一指令....../n");break;}case 2://私聊{printf("私聊ID:%d/t私聊内容:%s/n", fclient.id_c, fclient.tak_c);int send_fd = queryfd(list, fclient.id_c);printf("1send_fd is %d/n", send_fd);if(0 != send_fd){printf("2send_fd is %d/n", send_fd);strcpy(server1.tak_s, fclient.tak_c);//私聊信息存到服务器结构体printf("本身id :%d/n", queryid(list, new_fd));server1.id_s = queryid(list, new_fd);server1.cmd_s = 5;memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &server1, sizeof(server1)); //结构体转换成字符串ret = write(send_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("(私聊信息)发送成功/n");server1.cmd_s = 3;memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &server1, sizeof(server1)); //结构体转换成字符串ret = write(new_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("(私聊反馈)发送成功/n");}else{printf("(私聊信息)发送失败/n");server1.cmd_s = 4;memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &server1, sizeof(server1)); //结构体转换成字符串ret = write(new_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("(私聊反馈)发送成功/n");}break;}case 3://群聊{printf("客户机请求群聊/n");server1.id_s = queryid(list, new_fd);printf("发起人%d/t群聊内容:%s/n", server1.id_s, fclient.tak_c);int i;linkedlist *h = list;for(i = 0; i<getcount(list); i++){if(h -> fd_l != new_fd){strcpy(server1.tak_s, fclient.tak_c);//私聊信息存到服务器结构体//printf("本身id :%d/n", queryid(list, new_fd));server1.cmd_s = 6;memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &server1, sizeof(server1)); //结构体转换成字符串ret = write(h -> fd_l, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf(" (私聊信息)发送成功/n");}h = h -> next;}server1.cmd_s = 7;memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &server1, sizeof(server1)); //结构体转换成字符串ret = write(new_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("(私聊反馈)发送成功/n");break;}case 4://注销{printf("用户请求注销下线/n");list = dellinkedlist(list, new_fd);print(list);server1.cmd_s = 8;memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &server1, sizeof(server1)); //结构体转换成字符串ret = write(new_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("(注销反馈)发送成功/n");goto label1;}case 5://踢人{printf("超级用户请求踢人,被踢者ID为%d/n", fclient.id_c);int ti_fd = queryfd(list, fclient.id_c);//list = dellinkedlist(list, ti_fd);//print(list);server1.cmd_s = 11;memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &server1, sizeof(server1)); //结构体转换成字符串ret = write(ti_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("(踢人指令)发送成功/n");server1.cmd_s = 12;memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &server1, sizeof(server1)); //结构体转换成字符串ret = write(new_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("(踢人反馈)发送成功/n");break;}case 6://禁言{printf("超级用户请求禁言,被禁言者ID为%d/n");int jin_fd = queryfd(list, fclient.id_c);server1.cmd_s = 13;memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &server1, sizeof(server1)); //结构体转换成字符串ret = write(jin_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("(禁言指令)发送成功/n");server1.cmd_s = 14;memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &server1, sizeof(server1)); //结构体转换成字符串ret = write(new_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("(禁言反馈)发送成功/n");break;}case 7://解禁{printf("超级用户请求解除禁言,被解除者ID为%d/n");int jiejin_fd = queryfd(list, fclient.id_c);server1.cmd_s = 15;memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &server1, sizeof(server1)); //结构体转换成字符串ret = write(jiejin_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("(解禁指令)发送成功/n");server1.cmd_s = 16;memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &server1, sizeof(server1)); //结构体转换成字符串ret = write(new_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("(解禁反馈)发送成功/n");break;}case 8://文件传输{printf("客户机请求发送文件******************/n");printf("发送给%d/t文件名:%s/n", fclient.id_c, fclient.name_c);int id_sdf = queryid(list, new_fd);int fd_rsvf = queryfd(list, fclient.id_c);server1.cmd_s = 17;server1.id_s = id_sdf;strcpy(server1.fname, fclient.name_c);memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &server1, sizeof(server1)); //结构体转换成字符串ret = write(fd_rsvf, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("(文件传输指令)发送成功/n");////转发//while(1)printf("文件发送ing/n");char buffer_file[1024] = {0};while(read(new_fd, buffer_file, 1024) != -1)  //失败返回-1{printf("server : buffer_file is %s/n", buffer_file);if(write(fd_rsvf, buffer_file, 1024) == -1)  //失败返回-1{perror("send");exit(-1);}if(0 == strcmp(buffer_file, "END")){printf("文件主体传输完成/n");break;}memset(buffer_file, 0, 1024);//清空缓存}perror("recv");//exit(-1);server1.cmd_s = 18;memset(snd_buf, 0, 1024);//清空发送缓存memcpy(snd_buf, &server1, sizeof(server1)); //结构体转换成字符串ret = write(new_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("(文件传输反馈)发送成功/n");break;}case 99://客户机强行退出{printf("客户机强行退出/n");list = dellinkedlist(list, new_fd);print(list);goto label1;}}}}else//登录失败{server1.cmd_s = 2;memset(snd_buf, 0, 1024);//清空发送缓存   memcpy(snd_buf, &server1, sizeof(server1)); //结构体转换成字符串ret = write(new_fd, snd_buf, 1024);//发送信息if(-1 == ret){perror("write");exit(EXIT_FAILURE);}printf("登录失败,发送反馈成功,等待下一指令....../n");break;}break;}case 3:{printf("客户机退出程序/n");goto clientout;}case 99:{printf("客户机强行退出/n");goto clientout;}}label1:printf("**************/n");}clientout:close(new_fd);}linkedlist *createlinkedlist(){linkedlist *h;h = NULL;return h;}linkedlist *dellinkedlist(linkedlist *list, int fd){linkedlist *p = list -> next;linkedlist *h = list;if(list -> fd_l == fd){free(h);return list -> next;}else{while(p -> fd_l != fd){p = p -> next;h = h -> next;}h -> next = p -> next;free(p);return list;}}linkedlist *insert2(linkedlist *list, int id, int fd){linkedlist *head, *p;head = list;p = (linkedlist *)malloc(sizeof(linkedlist));if(head == NULL){head = p;p -> next = NULL;}else{p -> next = head;head = p;}p -> id_l = id;p -> fd_l = fd;return head;}int getcount(linkedlist *list){linkedlist *h = list;int count = 0;while(h != NULL){count++;h = h -> next;}return count;}int queryid(linkedlist *list, int fd){linkedlist *p, *h;h = list;while(h != NULL){if(fd == h -> fd_l){return h -> id_l;}h = h -> next;}}int queryfd(linkedlist *list, int id){linkedlist *h = list;while(h != NULL){if(id == h -> id_l){return h -> fd_l;}h = h -> next;}return 0;}void print(linkedlist *list){linkedlist *h = list;while(h != NULL){printf("list id is %d/tfd is %d/n",h ->id_l, h -> fd_l);        h = h -> next;}printf("/n");}int select_callback(void *date, int column_count,char* columnValue[],char* columnName[])//回调函数查找{if(column_count != 0){*adress = 1;}else{*adress = 2;}    return 0; }//回调函数查找


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表