服务器端:

ChatRoom.h

#ifndef  _CHATROOM_H_H
#define  _CHATROOM_H_H#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sqlite3.h>
#include <pthread.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>#define  TRUE     1
#define  FALSE    2
#define  SUCCESS  3
#define  FAILURE  4
#define  PORT     8888#define  REGISTER               100
#define  REG_SUCCESS            101
#define  LOGIN                  102
#define  LOG_SUCCESS            103
#define  LOG_FAILURE            104
#define  OnLine                 105
#define  NoOnLine               106
#define  Online                 107
#define  PrivateChat            108
#define  OFFLINE                109
#define  GroupChat              110
#define  ChatVip                111
#define  ShutUp                 112
#define  NoShutup               113
#define  SHUTUP                 114
#define  IsChatVip              115
#define  NoChatVip              116
#define  IsGroupShutup          117
#define  NoGroupShutup          118
#define  Kick                   119
#define  KickSuccess            120
#define  KickFailure            121
#define  KickOk                 122
#define  KickNoOk               123
#define  Expression             124struct user
{char id[20];char password[20];char username[20];char toname[20];int Tofd;                             //文件描述符int cmd;char online[20][20]   ;int n;                               //记录在线人数char buf[100];                        //聊天内容 int vip ;int speak;int find;char ep;                             };struct linknode
{struct user User;struct linknode *next;
};void Register(struct user *U);
void Login(struct user *U);
int isOnLine(struct linknode *List, struct user *User);
void ListInsert(struct linknode *list, struct user *User);
void TraverList(struct linknode*list, struct user *User);
void ChatRoom(int chatfd, struct user recvbuf, struct user USER);
void DeleteList(struct linknode *list, struct user *User);
void TraverId(struct linknode *list, struct user User, sqlite3 *db);
void TraverFriend(struct linknode *list, struct user User, sqlite3 *db);
void gettime();
void DealVip(struct user User, sqlite3 *db);
void Shut_up(struct user User, sqlite3 *db);
void DealKick(struct linknode *list, struct user User, sqlite3 *db);
char *nowtime();
void ExpressionShow();
void des_ep(struct user User);#endif

Server.c

#include <stdio.h>
#include "ChatRoom.h"struct linknode *UserList;struct user RecvBuf = {0};int isOnLine(struct linknode *list, struct user *User)
{struct linknode *p =list->next;while (p != NULL && strcmp(p->User.id, User->id) != 0 ){p = p->next;}if (p == NULL){return NoOnLine;}return OnLine;}void ListInsert(struct linknode *list, struct user *User)
{struct linknode *p = list;struct linknode*node = (struct linknode*)malloc(sizeof(struct linknode));strcpy(node->User.id, User->id); strcpy(node->User.username, User->username);node->User.Tofd = User->Tofd;node->next = p->next;p->next = node;}/*void copyUser(struct user *User1, struct user *User2)
{strcpy((*User1).username, (*User2).username);
}*/void TraverList(struct linknode *list, struct user *User)
{int j = 0;if (list == NULL){return ;}struct linknode *p  = list->next;while (p){strcpy(RecvBuf.online[j], p->User.username);j++;p = p->next;}RecvBuf.n = j; send(User->Tofd, &RecvBuf, sizeof(RecvBuf), 0);memset(&RecvBuf, 0 , sizeof(RecvBuf));}void TraverId(struct linknode *list, struct user User, sqlite3 *db)
{int ret;char sql[300] = {0};char *errmsg = NULL;char **dbResult = NULL;int nRow, nCol;if (list == NULL){return ;}struct linknode *p = list->next;while(p){if (User.Tofd == p->User.Tofd){strcpy(User.username, p->User.username);             //拷贝自己的名字break;}p = p->next;}sprintf(sql, "select speak from message where username = '%s';", User.username);ret  = sqlite3_get_table(db, sql, &dbResult, &nRow, &nCol, &errmsg);if (ret != SQLITE_OK){perror("sqlite3_get_table");exit(1);}if (*dbResult[1]-48 == 1){   User.find = SHUTUP;ret = send(User.Tofd, &User, sizeof(User), 0);if (ret < 0){perror("send");exit(1);}}else{p = list->next;while(p){ if (!strcmp(p->User.username, User.toname )){    User.find = NoShutup;ret = send(p->User.Tofd, &User, sizeof(User), 0);     //从链表中找出你想发送人的文件描述符if (ret < 0){perror("send");exit(1);}break;     }p = p->next;}}
}void DeleteList(struct linknode*list, struct user *User)
{struct linknode *p = list;struct linknode *tmp  ;if (p == NULL){return;}while(p->next != NULL){if (strcmp(p->next->User.id, User->id) == 0)       //根据帐号判断是否下线{tmp = p->next;p->next = tmp->next;free(tmp);break;}p = p->next;}}int main()
{struct user User;int sockfd,ret,fd[100] = {0};int length,j,i = 0;struct sockaddr_in server_addr;struct sockaddr_in client_addr;fd_set ReadFd, TmpFd;int MaxFd;int Tem;sqlite3 *ppdb;char sql[300] = {0};char **dbResult = NULL;int nRow, nCol;char *errmsg = NULL;UserList = (struct linknode*)malloc(sizeof(struct linknode));UserList->next = NULL;ret = sqlite3_open("message.db", &ppdb);                //打开或创建数据库if (ret != SQLITE_OK){perror("sqlite3_open");exit(1);}sprintf(sql,"create table if not exists message (id text, password text, username text, vip integer, speak integer);");ret = sqlite3_exec(ppdb, sql, NULL, NULL, NULL);if (ret != SQLITE_OK){perror("sqlite3_execl");exit(1);}sockfd = socket(PF_INET, SOCK_STREAM, 0);              // socket 建立连接,不用于发送消息if (sockfd < 0){perror("sockfd");exit(1);}int opt = 1;setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));    //允许重复使用地址bzero(&server_addr, sizeof(server_addr));server_addr.sin_family = PF_INET;server_addr.sin_port = htons(PORT);server_addr.sin_addr.s_addr = inet_addr("192.168.0.128");ret = bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));    //绑定信息if (ret < 0){perror("bind");exit(1);}ret = listen(sockfd, 20);                  //监听if (ret < 0){perror("listen");exit(1);}FD_ZERO(&ReadFd);                          //初始化FD_ZERO(&TmpFd);FD_SET(sockfd, &ReadFd);                   //添加MaxFd = sockfd;while(1){TmpFd = ReadFd;ret = select(MaxFd + 1, &TmpFd, NULL, NULL, NULL);if (-1 == ret){perror("select");exit(1);}if(FD_ISSET(sockfd, &TmpFd))                            //检测{length = sizeof(client_addr);fd[i] = accept(sockfd, (struct sockaddr *)&client_addr, &length);if (fd[i] < 0){perror("accept");exit(1);}printf("Accept  %d  Port  %d\n",fd[i], client_addr.sin_port);          //打印客户端端口号FD_SET(fd[i], &ReadFd);j = 0;Tem = fd[0];while(fd[j]){if (Tem < fd[j]){Tem = fd[j];}j++;}MaxFd = Tem;i++;}else{for(j = 0; j < i; j++){if (FD_ISSET(fd[j], &TmpFd)){ret = recv(fd[j], &RecvBuf, sizeof(RecvBuf), 0);            //接收客户端的请求if (ret < 0){perror("recv");exit(1);}switch(RecvBuf.cmd){case REGISTER:                        //注册用户信息{RecvBuf.Tofd = fd[j];memset(sql, 0, sizeof(sql));sprintf(sql, "insert into message (id, password, username, vip, speak) values ('%s', '%s', '%s', %d, %d);", RecvBuf.id, RecvBuf.password, RecvBuf.username, RecvBuf.vip,RecvBuf.speak);ret = sqlite3_exec(ppdb, sql, NULL, NULL, NULL);if (ret != SQLITE_OK){           perror("sqlite3_exec2");exit(1);}RecvBuf.cmd = REG_SUCCESS;send(RecvBuf.Tofd, &RecvBuf, sizeof(RecvBuf), 0);memset(&RecvBuf, 0 , sizeof(RecvBuf));break;}case LOGIN:                                                //登录信息{RecvBuf.Tofd = fd[j];memset(sql, 0, sizeof(sql));    sprintf(sql, "select * from message where id = '%s' and password = '%s';", RecvBuf.id, RecvBuf.password);ret = sqlite3_get_table(ppdb, sql,&dbResult, &nRow, &nCol, &errmsg);if (ret != SQLITE_OK){perror("sqlite3_get_table");exit(1);} int i;for (i = 0; i < (nRow + 1) * nCol; i++){if (strcmp(dbResult[i],RecvBuf.id) == 0 && strcmp(dbResult[i+1], RecvBuf.password) == 0){   ret = isOnLine(UserList, &RecvBuf);if (ret == OnLine){RecvBuf.cmd = OnLine;break;}strcpy(RecvBuf.username,dbResult[i+2]);                        ListInsert(UserList, &RecvBuf);RecvBuf.cmd = LOG_SUCCESS;break;}}send(RecvBuf.Tofd, &RecvBuf, sizeof(RecvBuf), 0);memset(&RecvBuf, 0, sizeof(RecvBuf));break;}case Online:{RecvBuf.Tofd = fd[j];TraverList(UserList, &RecvBuf);memset(&RecvBuf, 0, sizeof(RecvBuf));break;}case PrivateChat:{RecvBuf.Tofd = fd[j];TraverId(UserList, RecvBuf, ppdb);memset(&RecvBuf, 0, sizeof(RecvBuf));break;}case GroupChat:{RecvBuf.Tofd = fd[j];TraverFriend(UserList, RecvBuf, ppdb);memset(&RecvBuf, 0, sizeof(RecvBuf));break;}case ChatVip:{RecvBuf.Tofd = fd[j];DealVip(RecvBuf, ppdb);memset(&RecvBuf, 0, sizeof(RecvBuf));break;}case Kick:{RecvBuf.Tofd = fd[j];DealKick(UserList, RecvBuf, ppdb);memset(&RecvBuf, 0, sizeof(RecvBuf));break;}case ShutUp:{RecvBuf.Tofd = fd[j];Shut_up(RecvBuf, ppdb);memset(&RecvBuf, 0, sizeof(RecvBuf));break;}case Expression:{RecvBuf.Tofd = fd[j];Send_expression(UserList, RecvBuf, ppdb);memset(&RecvBuf, 0, sizeof(RecvBuf));break;}case OFFLINE:{RecvBuf.Tofd = fd[j];DeleteList(UserList, &RecvBuf);memset(&RecvBuf, 0, sizeof(RecvBuf));FD_CLR(fd[j], &ReadFd);close(fd[j]);break;}}    }}}}return 0;
}

TestServer.c

#include <stdio.h>
#include "ChatRoom.h"void TraverFriend(struct linknode *list, struct user User, sqlite3 *db)
{int ret;char sql[300] = {0};char *errmsg = NULL;char **dbResult = NULL;int nRow, nCol;if (NULL == list){return;}struct linknode *p = list->next;while(p){if (p->User.Tofd == User.Tofd){strcpy(User.username, p->User.username);break;}p = p->next;}sprintf(sql, "select speak from message where username = '%s';", User.username);ret = sqlite3_get_table(db, sql, &dbResult, &nRow, &nCol, &errmsg);if (ret != SQLITE_OK){perror("sqlite3_get_table");exit(1);}if (*dbResult[1] - 48 == 1){   User.find = IsGroupShutup;ret = send(User.Tofd, &User, sizeof(User), 0);if (ret < 0){perror("send");exit(1);}}else{p = list->next;while(p){if (strcmp(p->User.username, User.username) != 0){  User.find = NoGroupShutup;ret = send(p->User.Tofd, &User, sizeof(User), 0);if (ret < 0){perror("send");exit(1);}}p = p->next;}}}void DealVip(struct user User, sqlite3 *db)
{int ret;char sql[300] = {0};char *errmsg = NULL;char **dbResult = NULL;int nRow, nCol;sprintf(sql, "select vip from message where username = '%s';",User.username);ret = sqlite3_get_table(db, sql, &dbResult, &nRow, &nCol, &errmsg);if (ret != SQLITE_OK){perror("sqlite3_get_table");exit(1);}if (*dbResult[1]-48 == 0){User.vip = 1;memset(sql, 0, sizeof(sql));sprintf(sql, "update message set vip = %d where username = '%s';", User.vip, User.username);ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);if (ret != SQLITE_OK){perror("sqlite3_exec");exit(1);}ret = send(User.Tofd, &User, sizeof(User), 0);if (ret < 0){perror("send");exit(1);}}else{ret = send(User.Tofd, &User, sizeof(User), 0);if (ret < 0){perror("send");exit(1);}}}void Shut_up(struct user User, sqlite3 *db)
{int ret;char sql[300] = {0};char *errmsg = NULL;char **dbResult = NULL;int nRow, nCol;sprintf(sql, "select vip from message where username = '%s';", User.username);ret = sqlite3_get_table(db, sql, &dbResult, &nRow, &nCol, &errmsg);if (ret != SQLITE_OK){perror("sqlite3_get_table");exit(1);}if (*dbResult[1] -  48 == 0){User.find = NoChatVip;ret = send(User.Tofd, &User, sizeof(User), 0);if (ret < 0){perror("send");exit(1);}}else{User.speak = 1;User.find = IsChatVip;memset(sql, 0, sizeof(sql));sprintf(sql, "update message set speak = %d where username = '%s';", User.speak, User.toname);ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg);if (ret != SQLITE_OK){perror("sqlite3_exec");exit(1);}ret = send(User.Tofd, &User, sizeof(User), 0);if (ret < 0){perror("send");exit(1);}}    }void DealKick(struct linknode *list, struct user User, sqlite3 *db)
{int ret;struct linknode *p = list;struct linknode *tmp;char sql[200] = {0};char *errmsg = NULL;char **dbResult = NULL;int nRow, nCol;if (p == NULL){return ;}sprintf(sql, "select vip from message where username = '%s';", User.username);ret = sqlite3_get_table(db, sql, &dbResult, &nRow, &nCol, &errmsg);if (ret != SQLITE_OK){perror("sqlite3_get_table");exit(1);}if (*dbResult[1] - 48 == 0){User.find = KickFailure;ret = send(User.Tofd, &User, sizeof(User), 0);if (ret < 0){perror("send");exit(1);}}else{while(p->next){if (!strcmp(p->next->User.username, User.toname))    //要特别注意条件里的p->next是否成立{User.find = KickSuccess;ret = send(User.Tofd, &User, sizeof(User), 0);if (ret < 0){perror("send");exit(1);}User.find = KickOk;User.Tofd = p->next->User.Tofd;ret = send(User.Tofd, &User, sizeof(User), 0);if (ret < 0){perror("send");exit(1);}tmp = p->next;p->next = tmp->next;free(tmp);break;}p = p->next;}if (p->next == NULL){User.find = KickNoOk;ret = send(User.Tofd, &User, sizeof(User), 0);if (ret < 0){perror("send");exit(1);}}}}void Send_expression(struct linknode *list, struct user User, sqlite3 *db)
{int ret;char sql[200] = {0};char *errmsg = NULL;char **dbResult = NULL;int nRow, nCol;if (list == NULL){return ;}struct linknode *p = list->next;sprintf(sql, "select speak from message where username = '%s';", User.username);ret = sqlite3_get_table(db, sql, &dbResult, &nRow, &nCol, &errmsg);if (ret != SQLITE_OK){perror("sqlite3_get_table");exit(1);}if(*dbResult[1] - 48 == 1){User.find = SHUTUP;ret = send(User.Tofd, &User, sizeof(User), 0);if (ret < 0){perror("send");exit(1);}}else{p = list->next;while(p){if (!strcmp(p->User.username, User.toname)){User.find = NoShutup;ret = send(p->User.Tofd, &User, sizeof(User), 0);if (ret < 0){perror("send");exit(1);}break;}p = p->next;}}}

Select 实现网络聊天室功能 (服务器端)相关推荐

  1. [NUAA]Python用UDP协议建立带有私聊功能的网络聊天室-建立聊天工具

    文章目录 前言 1.网络聊天室的基本架构是什么? 1.1 客户端和服务器的架构 1.2 通信协议的选择以及多线程通信 1.2.1 多线程通信 1.2.2 通信协议选择 1.3 前后端功能设计思路 1. ...

  2. python基于udp的网络聊天室再用tkinter显示_Python实现网络聊天室的示例代码(支持多人聊天与私聊)...

    实验名称: 网络聊天室 功能: i. 掌握利用Socket进行编程的技术 ii. 掌握多线程技术,保证双方可以同时发送 iii. 建立聊天工具 iv. 可以和单人聊天 v. 可以和多个人同时进行聊天 ...

  3. Python实现网络聊天室(支持多人聊天与私聊)

    实验名称: 网络聊天室 功能: i. 掌握利用Socket进行编程的技术 ii. 掌握多线程技术,保证双方可以同时发送 iii. 建立聊天工具 iv. 可以和单人聊天 v. 可以和多个人同时进行聊天 ...

  4. linux点对点聊天室的实现与设计心得,基于Socket接口的Linux与Windows网络聊天室设计与实现...

    陈洁 孟晓景 摘要:为了实现Linux与Windows跨平台通信,及时共享信息,构建了一个适用于跨平台的网络聊天室通信程序.先搭建跨平台通信环境,然后使用Socket套接字网络编程接口实现通信.整个系 ...

  5. 基于UDP的网络聊天室网络编程0811作业-洪庆乐

    项目:基于UDP的网络聊天室 功能:1.服务器日志系统,且可以查看(实现) 2.有用户,其他用户收到这个人登入信息(实现) 3.群发消息(实现) 4.如果有用户下线,其他用户收到下线消息(实现) 5. ...

  6. 使用socket实现基于select模型的网络聊天室

    假期闲来无事,便写了个小小的网络聊天室程序.以前一直都是写MFC的有界面的程序,时间长了,便失去了兴趣,感觉有些东西经过MFC的封装,反而失去了意义,让人学不到东西,所以,丢开MFC那层的东西,直接使 ...

  7. Java NIO示例:多人网络聊天室完整代码

    服务端:  package cn.zhangxueliang.herostory.chatroom;import java.io.IOException; import java.net.InetSo ...

  8. Java NIO示例:多人网络聊天室

    一个多客户端聊天室,支持多客户端聊天,有如下功能: 功能1: 客户端通过Java NIO连接到服务端,支持多客户端的连接 功能2:客户端初次连接时,服务端提示输入昵称,如果昵称已经有人使用,提示重新输 ...

  9. 【网络聊天室】——基于socket编程的TCP/UDP网络聊天服务器

    早期网络刚刚普及的时候,给人们印象最深的就是上网聊天,虽然作为一名上世纪的尾巴刚刚出生的我没有经历过,但仍从有所耳闻,那个时期是网络聊天室风靡的年代,全国知名聊天室大家都争破头的想要进去,基于如上和一 ...

最新文章

  1. python之33个关键字详解_Python 中的关键字 with 详解
  2. javascript创建类_如何使用JavaScript创建吹气效果
  3. consulAPI服务的注册源码
  4. 数字化转型 数字分析_数字化转型背后的公司领先于开放的领导者
  5. 122345 java_【每天算法2】:用java语言实现,一个组数:122345这6个数,打印出它所有可能的组合;要求4不能在第3位,3和5不能相连。 | 学步园...
  6. 基于Docker布署伪分布式hadoop环境(一)
  7. 剑指 offer set 5 二进制中 1 的个数
  8. 小程序接入h5页面_小程序和H5页面的相互跳转
  9. 用火箭送快递?淘宝宣布联合蓝箭航天起启动“宝箭”计划
  10. 基于vue利用openlayers加载天地图,高德地图
  11. 已有一个排好序的数组,由键盘输入一个数,要求按原来的排序规律将其插入到数组中.
  12. 国内可用的时间服务器
  13. 中学计算机社团活动计划,社团活动方案
  14. win7设置定时锁定计算机,Win7系统怎么设置锁屏?Win7系统设置电脑锁屏的方法
  15. 令人惊艳的80个免费学习网站,每一个都备受好评!
  16. Anaconda 安装及使用
  17. VUE plugin 插件
  18. 1.1 硅、玻璃和石英微流控芯片的制作
  19. 工具 | Windows 功能猎手 (WFH)
  20. c语言蓝桥杯b组试题及答案,2014第五届蓝桥杯C-C++本科B组试题及答案要点-20210413045934.docx-原创力文档...

热门文章

  1. 人只剩一个心脏还能活吗
  2. python+vue+elementui校园二手书交易信息网站django
  3. EgretH5游戏开发笔记(一)
  4. 关于爱情和婚姻的一点看法
  5. Windows Server 2008 R2文件系统管理(NTFS)视频课程-深博-专题视频课程
  6. FlyMcu下载时的问题
  7. qtCreator 请不要使用高性能显卡设置
  8. 天拓分享|西门子plc常见接口及通讯协议有哪些?
  9. 02-文档扫描OCR识别
  10. 通过扩展 Rational Functional Tester 对 Adobe Flex 或 Flash 应用程序进行测试