C语言实现简易网络聊天室

本文实例为大家分享了C语言实现网络聊天室的具体代码,供大家参考,具体内容如下

业务逻辑:

1、客户端注册名字2、告诉所有在线的客户端,XXX进入聊天室3、新建一个线程为该客户端服务,随时接收客户端发送来的消息4、当接收到一个客户端的消息时,向每一个客户端转发一份(群聊)5、同时在线人数最多50人

任何客户端可以随意随时进入或退出客户端

服务端代码server.c

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <signal.h>#include <pthread.h>#include <semaphore.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#ifndef DEBUG #define debug(format,...) {}#else #define debug(format,...) \ {\  fprintf(stdout,"%s:%d:%s ",__func__,__LINE__,__TIME__);\  fprintf(stdout,format,##__VA_ARGS__);\  fprintf(stdout,"\n");\ }#endif//DEBUG#define error(format,...)\{\ fprintf(stdout,"%s:%d:%s ",__func__,__LINE__,__TIME__);\ fprintf(stdout,format,##__VA_ARGS__);\ fprintf(stdout,":%m\n");\ exit(EXIT_FAILURE);\}// 客户端最大连接数#define CLIENT_MAX 50// 服务器端口号#define PORT 5566// 缓冲区大小#define BUF_SIZE 4096// 重定义socket地址类型typedef struct sockaddr* SP;// 客户端结构体typedef struct Client{ int sock;//socket 标识符 pthread_t tid; //线程ID char name[20]; struct sockaddr_in addr;}Client;// 定义50个存储客户端的结构变量Client clients[50];// 定义信号量用于限制客户端的数量sem_t sem;// 信号处理函数void sigint(int num){ for(int i=0; i<10; i++) {  if(clients[i].sock)  {   pthread_cancel(clients[i].tid);//销毁线程  } } debug("服务器退出!"); exit(EXIT_SUCCESS);}void client_eixt(Client* client){ sem_post(&sem); close(client->sock); client->sock = 0;}void client_send(Client* client,char* buf){ size_t len = strlen(buf)+1; for(int i=0; i<CLIENT_MAX; i++) {  if(clients[i].sock && clients[i].sock != client->sock)  {    send(clients[i].sock,buf,len,0);  } }}void* run(void* arg){ Client* client = arg; char buf[BUF_SIZE] = {}; // 接收昵称 int ret_size = recv(client->sock,client->name,20,0); if(0 >= ret_size) {  client_eixt(client);  return NULL; } // 通知其它客户端新人上线 sprintf(buf,"!!!欢迎%s进入聊天室!!!",client->name); client_send(client,buf); for(;;) {   // 接收消息  ret_size = recv(client->sock,buf,BUF_SIZE,0);  if(0 >= ret_size || 0 == strcmp("quit",buf))  {   // 通知其它客户端退出   sprintf(buf,"!!!%s退出聊天室!!!",client->name);   client_send(client,buf);   client_eixt(client);   return NULL;  }  strcat(buf,":");  strcat(buf,client->name);  client_send(client,buf);  debug(buf); }}int main(int argc,const char* argv[]){ signal(SIGINT,sigint); debug("注册信号处理函数成功!"); sem_init(&sem,0,CLIENT_MAX); debug("初始化信号量成功!"); int svr_sock = socket(AF_INET,SOCK_STREAM,0); if(0 > svr_sock) {  error("socket"); } debug("创建socket对象成功!"); struct sockaddr_in svr_addr = {}; svr_addr.sin_family = AF_INET; svr_addr.sin_port = htons(PORT); svr_addr.sin_addr.s_addr = INADDR_ANY; socklen_t addrlen = sizeof(svr_addr); debug("准备通信地址成功!"); if(bind(svr_sock,(SP)&svr_addr,addrlen)) {  error("bind"); } debug("绑定socket对象和通信地址成功!"); if(listen(svr_sock,10)) {  error("listen"); } debug("设置监听socket监听成功!"); for(;;) {  debug("等待客户端连接...");  sem_wait(&sem);  int index = 0;  while(clients[index].sock)  {   index++;  }  clients[index].sock = accept(svr_sock,(SP)&clients[index].addr,&addrlen);  if(0 > clients[index].sock)  {   kill(getpid(),SIGINT);  }  debug("有新的客户端连接,from ip:%s",inet_ntoa(clients[index].addr.sin_addr));  pthread_create(&clients[index].tid,NULL,run,&clients[index]); }}

客户端代码client.c

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <signal.h>#include <pthread.h>#include <semaphore.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#ifndef DEBUG #define debug(format,...) {}#else #define debug(format,...) \ {\  fprintf(stdout,"%s:%d:%s ",__func__,__LINE__,__TIME__);\  fprintf(stdout,format,##__VA_ARGS__);\  fprintf(stdout,"\n");\ }#endif//DEBUG#define error(format,...)\{\ fprintf(stdout,"%s:%d:%s ",__func__,__LINE__,__TIME__);\ fprintf(stdout,format,##__VA_ARGS__);\ fprintf(stdout,":%m\n");\ exit(EXIT_FAILURE);\}#define BUF_SIZE  4096#define SERVER_PORT 5566#define SERVER_IP  "192.168.0.125"typedef struct sockaddr* SP;void* run(void* arg){ int cli_sock = *(int*)arg; char buf[BUF_SIZE] = {}; for(;;) {  int ret_size = recv(cli_sock,buf,BUF_SIZE,0);  if(0 >= ret_size)  {   printf("服务器正在升级,请稍候登录!\n");   exit(EXIT_SUCCESS);  }  printf("\r%30s\n>>>",buf);  fflush(stdout); }}int main(int argc,const char* argv[]){ int cli_sock = socket(AF_INET,SOCK_STREAM,0); if(0 > cli_sock) {  error("socket"); } struct sockaddr_in cli_addr = {}; cli_addr.sin_family = AF_INET; cli_addr.sin_port = htons(SERVER_PORT); cli_addr.sin_addr.s_addr = inet_addr(SERVER_IP); socklen_t addrlen = sizeof(cli_addr); if(connect(cli_sock,(SP)&cli_addr,addrlen)) {  printf("服务器正在升级,请稍候登录!\n");  return EXIT_SUCCESS; } char buf[BUF_SIZE] = {}; printf("请输入你的眤称:"); gets(buf); send(cli_sock,buf,strlen(buf)+1,0); pthread_t tid; pthread_create(&tid,NULL,run,&cli_sock); for(;;) {  printf(">>>");  gets(buf);  send(cli_sock,buf,strlen(buf)+1,0);  if(0 == strcmp("quit",buf))  {   printf("退出聊天室!\n");   return EXIT_SUCCESS;  } }}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

人总是珍惜未得到的,而遗忘了所拥有的

C语言实现简易网络聊天室

相关文章:

你感兴趣的文章:

标签云: